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", INSTALL_DATA);
68 debug_fp = fopen(filename, "a");
71 if (options.deb & DEBUG_STACK)
73 SPRINT(filename, "%s/debug_mISDN.log", INSTALL_DATA);
74 mISDN_debug_init(0xffffffff, filename, filename, filename);
76 mISDN_debug_init(0, NULL, NULL, NULL);
81 void mISDN_deinitialize(void)
98 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings)
100 p_m_mISDNport = mISDNport;
101 p_m_portnum = mISDNport->portnum;
109 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
110 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
118 p_m_dtmf = !mISDNport->ifport->nodtmf;
121 p_m_remote_ref = 0; /* channel shall be exported to given remote */
122 p_m_remote_id = 0; /* remote admin socket */
123 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
131 p_m_crypt_listen = 0;
132 p_m_crypt_msg_loops = 0;
133 p_m_crypt_msg_loops = 0;
134 p_m_crypt_msg_len = 0;
135 p_m_crypt_msg[0] = '\0';
136 p_m_crypt_msg_current = 0;
137 p_m_crypt_key_len = 0;
138 p_m_crypt_listen = 0;
139 p_m_crypt_listen_state = 0;
140 p_m_crypt_listen_len = 0;
141 p_m_crypt_listen_msg[0] = '\0';
142 p_m_crypt_listen_crc = 0;
143 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56)
145 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
146 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
150 /* if any channel requested by constructor */
151 if (channel == CHANNEL_ANY)
153 /* reserve channel */
155 mISDNport->b_reserved++;
158 /* reserve channel */
159 if (channel > 0) // only if constructor was called with a channel resevation
160 seize_bchannel(channel, exclusive);
162 /* we increase the number of objects: */
164 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
173 struct lcr_msg *message;
175 /* remove bchannel relation */
181 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
182 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
183 message->param.disconnectinfo.cause = 16;
184 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
185 message_put(message);
186 /* remove from list */
187 free_epointlist(p_epointlist);
190 /* we decrease the number of objects: */
191 p_m_mISDNport->use--;
192 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
199 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
201 /* init trace with given values */
202 start_trace(mISDNport?mISDNport->portnum:0,
203 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
204 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
205 port?port->p_dialinginfo.id:NULL,
208 port?port->p_serial:0,
216 static struct isdn_message {
220 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
221 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
222 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
223 {"DL_RELEASE", L2_RELEASE_REQ},
224 {"UNKNOWN", L3_UNKNOWN},
225 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
226 {"MT_SETUP", L3_SETUP_REQ},
227 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
228 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
229 {"MT_ALERTING", L3_ALERTING_REQ},
230 {"MT_CONNECT", L3_CONNECT_REQ},
231 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
232 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
233 {"MT_RELEASE", L3_RELEASE_REQ},
234 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
235 {"MT_INFORMATION", L3_INFORMATION_REQ},
236 {"MT_PROGRESS", L3_PROGRESS_REQ},
237 {"MT_NOTIFY", L3_NOTIFY_REQ},
238 {"MT_SUSPEND", L3_SUSPEND_REQ},
239 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
240 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
241 {"MT_RESUME", L3_RESUME_REQ},
242 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
243 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
244 {"MT_HOLD", L3_HOLD_REQ},
245 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
246 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
247 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
248 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
249 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
250 {"MT_FACILITY", L3_FACILITY_REQ},
251 {"MT_STATUS", L3_STATUS_REQ},
252 {"MT_RESTART", L3_RESTART_REQ},
253 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
254 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
257 static char *isdn_prim[4] = {
263 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
266 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
268 /* select message and primitive text */
270 while(isdn_message[i].name)
272 if (isdn_message[i].value == (msg&0xffffff00))
274 SCPY(msgtext, isdn_message[i].name);
279 SCAT(msgtext, isdn_prim[msg&0x00000003]);
282 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ)
286 if (mISDNport->ntmode)
288 if (direction == DIRECTION_OUT)
289 SCAT(msgtext, " N->U");
291 SCAT(msgtext, " N<-U");
294 if (direction == DIRECTION_OUT)
295 SCAT(msgtext, " U->N");
297 SCAT(msgtext, " U<-N");
302 /* init trace with given values */
303 start_trace(mISDNport?mISDNport->portnum:0,
304 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
305 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
306 port?port->p_dialinginfo.id:NULL,
309 port?port->p_serial:0,
315 * send control information to the channel (dsp-module)
317 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, char *trace_name, int trace_value)
319 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
320 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
321 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
327 ctrl->prim = PH_CONTROL_REQ;
331 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
333 PERROR("Failed to send to socket %d\n", sock);
334 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
335 if (c1 == DSP_CONF_JOIN)
336 add_trace(trace_name, NULL, "0x%08x", trace_value);
338 add_trace(trace_name, NULL, "%d", trace_value);
342 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, void *c2, int c2_len, char *trace_name, int trace_value)
344 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
345 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
346 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
352 ctrl->prim = PH_CONTROL_REQ;
355 memcpy(d, c2, c2_len);
356 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
358 PERROR("Failed to send to socket %d\n", sock);
359 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
360 add_trace(trace_name, NULL, "%d", trace_value);
366 * subfunction for bchannel_event
369 static int _bchannel_create(struct mISDNport *mISDNport, int i)
373 struct sockaddr_mISDN addr;
375 if (mISDNport->b_socket[i] > -1)
377 PERROR("Error: Socket already created for index %d\n", i);
382 //#warning testing without DSP
383 // mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_HDLC:ISDN_P_B_RAW);
384 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_L2DSPHDLC:ISDN_P_B_L2DSP);
385 if (mISDNport->b_socket[i] < 0)
387 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
391 /* set nonblocking io */
392 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
395 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
396 close(mISDNport->b_socket[i]);
397 mISDNport->b_socket[i] = -1;
401 /* bind socket to bchannel */
402 addr.family = AF_ISDN;
403 addr.dev = mISDNport->portnum-1;
404 addr.channel = i+1+(i>=15);
405 ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr));
408 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
409 close(mISDNport->b_socket[i]);
410 mISDNport->b_socket[i] = -1;
414 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
415 add_trace("channel", NULL, "%d", i+1+(i>=15));
416 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
424 * subfunction for bchannel_event
425 * activate / deactivate request
427 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
429 struct mISDNhead act;
432 if (mISDNport->b_socket[i] < 0)
434 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
436 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
438 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
441 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
442 add_trace("channel", NULL, "%d", i+1+(i>=15));
443 if (mISDNport->b_timer[i])
444 add_trace("event", NULL, "timeout recovery");
450 * subfunction for bchannel_event
453 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
458 if (mISDNport->b_socket[i] < 0)
460 handle = mISDNport->b_socket[i];
461 port = mISDNport->b_port[i];
462 mode = mISDNport->b_mode[i];
465 PERROR("bchannel index i=%d not associated with a port object\n", i);
469 /* set dsp features */
470 if (port->p_m_txdata)
471 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
472 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
473 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
474 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
475 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
476 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
477 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
478 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
479 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
481 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
483 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
484 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
485 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
487 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
488 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
489 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
490 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
491 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
492 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
493 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);
497 * subfunction for bchannel_event
500 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
502 if (mISDNport->b_socket[i] < 0)
504 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
505 add_trace("channel", NULL, "%d", i+1+(i>=15));
506 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
508 close(mISDNport->b_socket[i]);
509 mISDNport->b_socket[i] = -1;
517 A bchannel goes through the following states in this order:
520 No one is using the bchannel.
521 It is available and not linked to Port class, nor reserved.
524 The bchannel stack is created and an activation request is sent.
525 It MAY be linked to Port class, but already unlinked due to Port class removal.
528 The bchannel is active and cofigured to the Port class needs.
529 Also it is linked to a Port class, otherwhise it would be deactivated.
531 - B_STATE_DEACTIVATING
532 The bchannel is in deactivating state, due to deactivation request.
533 It may be linked to a Port class, that likes to reactivate it.
537 After deactivating bchannel, and if not used, the bchannel becomes idle again.
539 Also the bchannel may be exported, but only if the state is or becomes idle:
542 The bchannel assignment has been sent to the remove application.
545 The bchannel assignment is acknowledged by the remote application.
548 The bchannel is re-imported by mISDN port object.
552 After re-importing bchannel, and if not used, the bchannel becomes idle again.
555 A bchannel can have the following events:
558 A bchannel is required by a Port class.
561 The bchannel beomes active.
564 The bchannel is not required by Port class anymore
566 - B_EVENT_DEACTIVATED
567 The bchannel becomes inactive.
570 The bchannel is now used by remote application.
573 The bchannel is not used by remote application.
575 - B_EVENT_EXPORTREQUEST
576 The bchannel shall be exported to the remote application.
578 - B_EVENT_IMPORTREQUEST
579 The bchannel is released from the remote application.
581 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
583 if an export request is receive by remote application, p_m_remote_* is set.
584 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.)
585 - set on export request from remote application (if port is assigned)
586 - set on channel use, if requested by remote application (p_m_remote_*)
587 - cleared on drop request
589 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
590 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
591 the bchannel import/export is acknowledged with stack given.
593 if exporting, b_remote_*[index] is set to the remote socket id.
594 if importing has been acknowledged. b_remote_*[index] is cleared.
599 * process bchannel events
600 * - mISDNport is a pointer to the port's structure
601 * - i is the index of the bchannel
602 * - event is the B_EVENT_* value
603 * - port is the PmISDN class pointer
605 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
607 class PmISDN *b_port = mISDNport->b_port[i];
608 int state = mISDNport->b_state[i];
609 double timer = mISDNport->b_timer[i];
610 unsigned int p_m_remote_ref = 0;
611 unsigned int p_m_remote_id = 0;
614 char *p_m_pipeline = NULL;
615 unsigned char *p_m_crypt_key = NULL;
616 int p_m_crypt_key_len = 0;
617 int p_m_crypt_key_type = 0;
618 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
622 p_m_remote_id = b_port->p_m_remote_id;
623 p_m_remote_ref = b_port->p_m_remote_ref;
624 p_m_tx_gain = b_port->p_m_tx_gain;
625 p_m_rx_gain = b_port->p_m_rx_gain;
626 p_m_pipeline = b_port->p_m_pipeline;
627 p_m_crypt_key = b_port->p_m_crypt_key;
628 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
629 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
635 /* port must be linked in order to allow activation */
637 FATAL("bchannel must be linked to a Port class\n");
643 /* export bchannel */
644 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);
645 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
646 add_trace("type", NULL, "assign");
647 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
649 state = B_STATE_EXPORTING;
650 mISDNport->b_remote_id[i] = p_m_remote_id;
651 mISDNport->b_remote_ref[i] = p_m_remote_ref;
654 /* create stack and send activation request */
655 if (_bchannel_create(mISDNport, i))
657 _bchannel_activate(mISDNport, i, 1);
658 state = B_STATE_ACTIVATING;
659 timer = now_d + B_TIMER_ACTIVATING;
664 case B_STATE_ACTIVATING:
665 case B_STATE_EXPORTING:
666 /* do nothing, because it is already activating */
669 case B_STATE_DEACTIVATING:
670 case B_STATE_IMPORTING:
671 /* do nothing, because we must wait until we can reactivate */
675 /* problems that might ocurr:
676 * B_EVENT_USE is received when channel already in use.
677 * bchannel exported, but not freed by other port
679 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
683 case B_EVENT_EXPORTREQUEST:
684 /* special case where the bchannel is requested by remote */
687 PERROR("export request without remote channel set, please correct.\n");
693 /* in case, the bchannel is exported right after seize_bchannel */
694 /* export bchannel */
695 /* p_m_remote_id is set, when this event happens. */
696 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);
697 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
698 add_trace("type", NULL, "assign");
699 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
701 state = B_STATE_EXPORTING;
702 mISDNport->b_remote_id[i] = p_m_remote_id;
703 mISDNport->b_remote_ref[i] = p_m_remote_ref;
706 case B_STATE_ACTIVATING:
707 case B_STATE_EXPORTING:
708 /* do nothing, because it is already activating */
711 case B_STATE_DEACTIVATING:
712 case B_STATE_IMPORTING:
713 /* do nothing, because we must wait until we can reactivate */
717 /* bchannel is active, so we deactivate */
718 _bchannel_activate(mISDNport, i, 0);
719 state = B_STATE_DEACTIVATING;
720 timer = now_d + B_TIMER_DEACTIVATING;
724 /* problems that might ocurr:
725 * ... when channel already in use.
726 * bchannel exported, but not freed by other port
728 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
732 case B_EVENT_IMPORTREQUEST:
733 /* special case where the bchannel is released by remote */
736 PERROR("import request with remote channel set, please correct.\n");
743 /* bchannel is not exported */
746 case B_STATE_ACTIVATING:
747 case B_STATE_EXPORTING:
748 /* do nothing because we must wait until bchanenl is active before deactivating */
752 /* bchannel is exported, so we re-import */
753 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
754 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
755 add_trace("type", NULL, "remove");
756 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
758 state = B_STATE_IMPORTING;
761 case B_STATE_DEACTIVATING:
762 case B_STATE_IMPORTING:
763 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
767 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
771 case B_EVENT_ACTIVATED:
775 case B_STATE_ACTIVATING:
776 if (b_port && !p_m_remote_id)
778 /* bchannel is active and used by Port class, so we configure bchannel */
779 _bchannel_configure(mISDNport, i);
780 state = B_STATE_ACTIVE;
781 b_port->p_m_load = 0;
784 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
785 _bchannel_activate(mISDNport, i, 0);
786 state = B_STATE_DEACTIVATING;
787 timer = now_d + B_TIMER_DEACTIVATING;
792 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
796 case B_EVENT_EXPORTED:
799 case B_STATE_EXPORTING:
800 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
802 /* remote export done */
803 state = B_STATE_REMOTE;
806 /* bchannel is now exported, but we need bchannel back
807 * OR bchannel is not used anymore
808 * OR bchannel has been exported to an obsolete ref,
809 * so reimport, to later export to new remote */
810 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
811 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
812 add_trace("type", NULL, "remove");
813 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
815 state = B_STATE_IMPORTING;
820 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
826 FATAL("bchannel must be linked to a Port class\n");
830 /* bchannel is idle due to an error, so we do nothing */
833 case B_STATE_ACTIVATING:
834 case B_STATE_EXPORTING:
835 /* do nothing because we must wait until bchanenl is active before deactivating */
839 /* bchannel is active, so we deactivate */
840 _bchannel_activate(mISDNport, i, 0);
841 state = B_STATE_DEACTIVATING;
842 timer = now_d + B_TIMER_DEACTIVATING;
846 /* bchannel is exported, so we re-import */
847 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
848 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
849 add_trace("type", NULL, "remove");
850 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
852 state = B_STATE_IMPORTING;
855 case B_STATE_DEACTIVATING:
856 case B_STATE_IMPORTING:
857 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
861 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
865 case B_EVENT_DEACTIVATED:
870 /* ignore due to deactivation confirm after unloading */
873 case B_STATE_DEACTIVATING:
874 _bchannel_destroy(mISDNport, i);
875 state = B_STATE_IDLE;
878 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
881 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);
882 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
883 add_trace("type", NULL, "assign");
884 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
886 state = B_STATE_EXPORTING;
887 mISDNport->b_remote_id[i] = p_m_remote_id;
888 mISDNport->b_remote_ref[i] = p_m_remote_ref;
891 if (_bchannel_create(mISDNport, i))
893 _bchannel_activate(mISDNport, i, 1);
894 state = B_STATE_ACTIVATING;
895 timer = now_d + B_TIMER_ACTIVATING;
902 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
906 case B_EVENT_IMPORTED:
909 case B_STATE_IMPORTING:
910 state = B_STATE_IDLE;
911 mISDNport->b_remote_id[i] = 0;
912 mISDNport->b_remote_ref[i] = 0;
915 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
918 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);
919 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
920 add_trace("type", NULL, "assign");
921 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
923 state = B_STATE_EXPORTING;
924 mISDNport->b_remote_id[i] = p_m_remote_id;
925 mISDNport->b_remote_ref[i] = p_m_remote_ref;
928 if (_bchannel_create(mISDNport, i))
930 _bchannel_activate(mISDNport, i, 1);
931 state = B_STATE_ACTIVATING;
932 timer = now_d + B_TIMER_ACTIVATING;
939 /* ignore, because not assigned */
944 case B_EVENT_TIMEOUT:
949 /* ignore due to deactivation confirm after unloading */
952 case B_STATE_ACTIVATING:
953 _bchannel_activate(mISDNport, i, 1);
954 timer = now_d + B_TIMER_ACTIVATING;
957 case B_STATE_DEACTIVATING:
958 _bchannel_activate(mISDNport, i, 0);
959 timer = now_d + B_TIMER_DEACTIVATING;
963 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
968 PERROR("Illegal event %d, please correct.\n", event);
971 mISDNport->b_state[i] = state;
972 mISDNport->b_timer[i] = timer;
979 * check for available channel and reserve+set it.
980 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
982 * returns -(cause value) or x = channel x or 0 = no channel
983 * NOTE: no activation is done here
985 int PmISDN::seize_bchannel(int channel, int exclusive)
989 /* the channel is what we have */
990 if (p_m_b_channel == channel)
993 /* if channel already in use, release it */
998 if (channel==CHANNEL_NO || channel==0)
1001 /* is channel in range ? */
1003 || (channel>p_m_mISDNport->b_num && channel<16)
1004 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1005 return(-6); /* channel unacceptable */
1007 /* request exclusive channel */
1008 if (exclusive && channel>0)
1010 i = channel-1-(channel>16);
1011 if (p_m_mISDNport->b_port[i])
1012 return(-44); /* requested channel not available */
1016 /* ask for channel */
1019 i = channel-1-(channel>16);
1020 if (p_m_mISDNport->b_port[i] == NULL)
1024 /* search for channel */
1026 while(i < p_m_mISDNport->b_num)
1028 if (!p_m_mISDNport->b_port[i])
1030 channel = i+1+(i>=15);
1035 return(-34); /* no free channel */
1038 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1040 /* link Port, set parameters */
1041 p_m_mISDNport->b_port[i] = this;
1043 p_m_b_channel = channel;
1044 p_m_b_exclusive = exclusive;
1045 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1047 /* reserve channel */
1051 p_m_mISDNport->b_reserved++;
1058 * drop reserved channel and unset it.
1059 * deactivation is also done
1061 void PmISDN::drop_bchannel(void)
1063 /* unreserve channel */
1065 p_m_mISDNport->b_reserved--;
1069 if (p_m_b_index < 0)
1074 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1076 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1077 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1078 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1079 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1082 p_m_b_exclusive = 0;
1085 /* process bchannel export/import message from join */
1086 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1088 class Endpoint *epoint;
1090 class PmISDN *isdnport;
1091 struct mISDNport *mISDNport;
1096 case BCHANNEL_REQUEST:
1097 /* find the port object for the join object ref */
1098 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1100 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1103 if (!epoint->ep_portlist)
1105 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1108 if (epoint->ep_portlist->next)
1110 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);
1112 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1114 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1117 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN)
1119 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1121 isdnport = (class PmISDN *)port;
1124 if (isdnport->p_m_remote_id)
1126 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1129 mISDNport = isdnport->p_m_mISDNport;
1130 i = isdnport->p_m_b_index;
1131 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1132 add_trace("type", NULL, "export request");
1134 isdnport->p_m_remote_ref = joinremote->j_serial;
1135 isdnport->p_m_remote_id = joinremote->j_remote_id;
1136 if (mISDNport && i>=0)
1138 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1142 case BCHANNEL_RELEASE:
1143 case BCHANNEL_ASSIGN_ACK:
1144 case BCHANNEL_REMOVE_ACK:
1145 /* find mISDNport for stack ID */
1146 mISDNport = mISDNport_first;
1150 ii = mISDNport->b_num;
1153 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1159 mISDNport = mISDNport->next;
1163 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1167 if (type!=BCHANNEL_RELEASE)
1170 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1171 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1173 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1177 isdnport = mISDNport->b_port[i];
1178 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1179 add_trace("type", NULL, "import request");
1183 isdnport->p_m_remote_ref = 0;
1184 isdnport->p_m_remote_id = 0;
1186 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1190 PERROR("received wrong bchannel message type %d from remote\n", type);
1198 audio transmission procedure:
1199 -----------------------------
1202 three sources of audio transmission:
1203 - crypto-data high priority
1204 - tones high priority (also high)
1205 - remote-data low priority
1208 a variable that temporarily shows the number of samples elapsed since last transmission process.
1209 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1212 a variable that is increased whenever data is transmitted.
1213 it is decreased while time elapses. it stores the number of samples that
1214 are currently loaded to dsp module.
1215 since clock in dsp module is the same clock for user space process, these
1219 there are two levels:
1220 ISDN_LOAD will give the load that have to be kept in dsp.
1221 ISDN_MAXLOAD will give the maximum load before dropping.
1223 * procedure for low priority data
1224 see txfromup() for procedure
1225 in short: remote data is ignored during high priority tones
1227 * procedure for high priority data
1228 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1229 if no more data is available, load becomes empty again.
1232 0 ISDN_LOAD ISDN_MAXLOAD
1233 +--------------------+----------------------+
1235 +--------------------+----------------------+
1237 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1238 0 ISDN_LOAD ISDN_MAXLOAD
1239 +--------------------+----------------------+
1240 |TTTTTTTTTTTTTTTTTTTT| |
1241 +--------------------+----------------------+
1243 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1244 0 ISDN_LOAD ISDN_MAXLOAD
1245 +--------------------+----------------------+
1246 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1247 +--------------------+----------------------+
1250 int PmISDN::handler(void)
1252 struct lcr_msg *message;
1256 if ((ret = Port::handler()))
1260 if (p_m_last_tv_sec)
1262 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1263 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1266 /* set clock of first process ever in this instance */
1267 p_m_last_tv_sec = now_tv.tv_sec;
1268 p_m_last_tv_msec = now_tv.tv_usec/1000;
1270 /* process only if we have a minimum of samples, to make packets not too small */
1271 if (elapsed >= ISDN_TRANSMIT
1272 && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1274 /* set clock of last process! */
1275 p_m_last_tv_sec = now_tv.tv_sec;
1276 p_m_last_tv_msec = now_tv.tv_usec/1000;
1279 if (elapsed < p_m_load)
1280 p_m_load -= elapsed;
1284 /* to send data, tone must be active OR crypt messages must be on */
1285 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1286 && (p_m_load < ISDN_LOAD)
1287 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1289 int tosend = ISDN_LOAD - p_m_load, length;
1290 unsigned char buf[MISDN_HEADER_LEN+tosend];
1291 struct mISDNhead *frm = (struct mISDNhead *)buf;
1292 unsigned char *p = buf+MISDN_HEADER_LEN;
1294 /* copy crypto loops */
1295 while (p_m_crypt_msg_loops && tosend)
1297 /* how much do we have to send */
1298 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1301 if (length > tosend)
1304 /* copy message (part) to buffer */
1305 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1308 p_m_crypt_msg_current += length;
1309 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1312 p_m_crypt_msg_current = 0;
1313 p_m_crypt_msg_loops--;
1314 // puts("eine loop weniger");
1322 if (p_tone_name[0] && tosend)
1324 tosend -= read_audio(p, tosend);
1328 if (ISDN_LOAD - p_m_load - tosend > 0)
1330 frm->prim = PH_DATA_REQ;
1332 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1334 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);
1335 p_m_load += ISDN_LOAD - p_m_load - tosend;
1340 // NOTE: deletion is done by the child class
1342 /* handle timeouts */
1345 if (p_m_timer+p_m_timeout < now_d)
1347 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1349 /* send timeout to endpoint */
1350 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1351 message->param.state = p_state;
1352 message_put(message);
1357 return(0); /* nothing done */
1362 * whenever we get audio data from bchannel, we process it here
1364 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1366 unsigned int cont = *((unsigned int *)data);
1367 unsigned char *data_temp;
1368 unsigned int length_temp;
1369 struct lcr_msg *message;
1373 if (hh->prim == PH_CONTROL_IND)
1377 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1380 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1382 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1383 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1385 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1386 message->param.dtmf = cont & DTMF_TONE_MASK;
1387 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1388 message_put(message);
1394 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1395 add_trace("DSP-CRYPT", NULL, "error");
1397 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1398 message->param.crypt.type = CC_ERROR_IND;
1399 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1400 message_put(message);
1404 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1405 add_trace("DSP-CRYPT", NULL, "ok");
1407 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1408 message->param.crypt.type = CC_ACTBF_CONF;
1409 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1410 message_put(message);
1414 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1415 add_trace("unknown", NULL, "0x%x", cont);
1420 if (hh->prim == PH_CONTROL_IND)
1425 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1426 add_trace("unknown", NULL, "0x%x", hh->id);
1431 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ)
1435 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1436 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1439 /* see below (same condition) */
1440 if (p_state!=PORT_STATE_CONNECT
1441 && !p_m_mISDNport->tones)
1443 // printf(".");fflush(stdout);return;
1445 record(data, len, 1); // from up
1448 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1450 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1454 /* calls will not process any audio data unless
1455 * the call is connected OR tones feature is enabled.
1457 #ifndef DEBUG_COREBRIDGE
1458 if (p_state!=PORT_STATE_CONNECT
1459 && !p_m_mISDNport->tones)
1464 /* the bearer capability must be audio in order to send and receive
1465 * audio prior or after connect.
1467 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1471 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1474 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1480 record(data, len, 0); // from down
1482 /* randomize and listen to crypt message if enabled */
1483 if (p_m_crypt_listen)
1485 /* the noisy randomizer */
1489 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1491 cryptman_listen_bch(data, len);
1496 /* send data to epoint */
1497 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1503 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1504 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1505 memcpy(message->param.data.data, data_temp, message->param.data.len);
1506 message_put(message);
1507 if (length_temp <= sizeof(message->param.data.data))
1509 data_temp += sizeof(message->param.data.data);
1510 length_temp -= sizeof(message->param.data.data);
1519 void PmISDN::set_echotest(int echo)
1521 if (p_m_echo != echo)
1524 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1526 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1527 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);
1534 void PmISDN::set_tone(char *dir, char *tone)
1540 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1547 /* check if we NOT really have to use a dsp-tone */
1548 if (!options.dsptones)
1552 if (p_m_b_index > -1)
1553 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)
1555 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1556 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1559 Port::set_tone(dir, tone);
1565 /* now we USE dsp-tone, convert name */
1566 else if (!strcmp(tone, "dialtone"))
1568 switch(options.dsptones) {
1569 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1570 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1571 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1573 } else if (!strcmp(tone, "dialpbx"))
1575 switch(options.dsptones) {
1576 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1577 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1578 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1580 } else if (!strcmp(tone, "ringing"))
1582 switch(options.dsptones) {
1583 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1584 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1585 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1587 } else if (!strcmp(tone, "ringpbx"))
1589 switch(options.dsptones) {
1590 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1591 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1592 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1594 } else if (!strcmp(tone, "busy"))
1597 switch(options.dsptones) {
1598 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1599 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1600 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1602 } else if (!strcmp(tone, "release"))
1605 switch(options.dsptones) {
1606 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1607 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1608 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1610 } else if (!strcmp(tone, "cause_10"))
1612 else if (!strcmp(tone, "cause_11"))
1614 else if (!strcmp(tone, "cause_22"))
1616 switch(options.dsptones) {
1617 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1618 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1619 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1621 } else if (!strncmp(tone, "cause_", 6))
1622 id = TONE_SPECIAL_INFO;
1626 /* if we have a tone that is not supported by dsp */
1627 if (id==TONE_OFF && tone[0])
1635 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1636 if (p_m_b_index > -1)
1637 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1638 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_tone?DSP_TONE_PATT_ON:DSP_TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1640 /* turn user-space tones off in cases of no tone OR dsp tone */
1641 Port::set_tone("",NULL);
1645 /* MESSAGE_mISDNSIGNAL */
1646 //extern struct lcr_msg *dddebug;
1647 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1649 switch(param->mISDNsignal.message)
1651 case mISDNSIGNAL_VOLUME:
1652 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1654 p_m_tx_gain = param->mISDNsignal.tx_gain;
1655 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1656 if (p_m_b_index > -1)
1657 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1658 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1660 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1661 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1663 p_m_rx_gain = param->mISDNsignal.rx_gain;
1664 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1665 if (p_m_b_index > -1)
1666 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1667 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1669 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1672 case mISDNSIGNAL_CONF:
1673 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1674 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1675 if (p_m_conf != param->mISDNsignal.conf)
1677 p_m_conf = param->mISDNsignal.conf;
1678 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1679 if (p_m_b_index > -1)
1680 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1681 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], (p_m_conf)?DSP_CONF_JOIN:DSP_CONF_SPLIT, p_m_conf, "DSP-CONF", p_m_conf);
1683 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1684 /* we must set, even if currently tone forbids conf */
1685 p_m_conf = param->mISDNsignal.conf;
1686 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1689 case mISDNSIGNAL_JOINDATA:
1690 if (p_m_joindata != param->mISDNsignal.joindata)
1692 p_m_joindata = param->mISDNsignal.joindata;
1693 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1695 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1698 case mISDNSIGNAL_DELAY:
1699 if (p_m_delay != param->mISDNsignal.delay)
1701 p_m_delay = param->mISDNsignal.delay;
1702 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1703 if (p_m_b_index > -1)
1704 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1705 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_delay?DSP_DELAY:DSP_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
1707 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1711 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1716 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1718 struct lcr_msg *message;
1720 switch(param->crypt.type)
1722 case CC_ACTBF_REQ: /* activate blowfish */
1724 p_m_crypt_key_len = param->crypt.len;
1725 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1727 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1728 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1729 message->param.crypt.type = CC_ERROR_IND;
1730 message_put(message);
1733 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1735 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1736 if (p_m_b_index > -1)
1737 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1738 ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_crypt?DSP_BF_ENABLE_KEY:DSP_BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len);
1741 case CC_DACT_REQ: /* deactivate session encryption */
1746 case CR_LISTEN_REQ: /* start listening to messages */
1747 p_m_crypt_listen = 1;
1748 p_m_crypt_listen_state = 0;
1751 case CR_UNLISTEN_REQ: /* stop listening to messages */
1752 p_m_crypt_listen = 0;
1755 case CR_MESSAGE_REQ: /* send message */
1756 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1757 if (!p_m_crypt_msg_len)
1759 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1762 p_m_crypt_msg_current = 0; /* reset */
1763 p_m_crypt_msg_loops = 6; /* enable */
1765 /* disable txmix, or we get corrupt data due to audio process */
1766 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1768 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1769 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1775 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1781 * endpoint sends messages to the port
1783 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1785 if (Port::message_epoint(epoint_id, message_id, param))
1790 case MESSAGE_DATA: /* tx-data from upper layer */
1791 txfromup(param->data.data, param->data.len);
1794 case MESSAGE_mISDNSIGNAL: /* user command */
1795 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1796 message_mISDNsignal(epoint_id, message_id, param);
1799 case MESSAGE_CRYPT: /* crypt control command */
1800 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1801 message_crypt(epoint_id, message_id, param);
1810 * main loop for processing messages from mISDN
1812 int mISDN_handler(void)
1815 struct mISDNport *mISDNport;
1816 class PmISDN *isdnport;
1818 unsigned char buffer[2048+MISDN_HEADER_LEN];
1819 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1823 /* process all ports */
1824 mISDNport = mISDNport_first;
1827 /* process all bchannels */
1829 while(i < mISDNport->b_num)
1831 /* process timer events for bchannel handling */
1832 if (mISDNport->b_timer[i])
1834 if (mISDNport->b_timer[i] <= now_d)
1835 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
1837 /* handle port of bchannel */
1838 isdnport=mISDNport->b_port[i];
1841 /* call bridges in user space OR crypto OR recording */
1842 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1844 /* rx IS required */
1845 if (isdnport->p_m_rxoff)
1848 isdnport->p_m_rxoff = 0;
1849 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1850 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1851 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1856 /* rx NOT required */
1857 if (!isdnport->p_m_rxoff)
1860 isdnport->p_m_rxoff = 1;
1861 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1862 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1863 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1868 if (isdnport->p_record)
1870 /* txdata IS required */
1871 if (!isdnport->p_m_txdata)
1874 isdnport->p_m_txdata = 1;
1875 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1876 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1877 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1882 /* txdata NOT required */
1883 if (isdnport->p_m_txdata)
1886 isdnport->p_m_txdata = 0;
1887 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1888 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1889 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1895 /* handle message from bchannel */
1896 if (mISDNport->b_socket[i] > -1)
1898 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
1899 if (ret >= (int)MISDN_HEADER_LEN)
1904 /* we don't care about confirms, we use rx data to sync tx */
1908 /* we receive audio data, we respond to it AND we send tones */
1913 case PH_CONTROL_IND:
1914 if (mISDNport->b_port[i])
1915 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1917 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
1920 case PH_ACTIVATE_IND:
1921 case DL_ESTABLISH_IND:
1922 case PH_ACTIVATE_CNF:
1923 case DL_ESTABLISH_CNF:
1924 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
1925 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1928 case PH_DEACTIVATE_IND:
1929 case DL_RELEASE_IND:
1930 case PH_DEACTIVATE_CNF:
1931 case DL_RELEASE_CNF:
1932 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
1933 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1937 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
1941 if (ret < 0 && errno != EWOULDBLOCK)
1942 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
1949 /* handle queued up-messages (d-channel) */
1950 while ((mb = mdequeue(&mISDNport->upqueue)))
1955 case MPH_ACTIVATE_IND:
1956 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1958 mISDNport->l1link = 1;
1961 case MPH_DEACTIVATE_IND:
1962 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1964 mISDNport->l1link = 0;
1967 case MPH_INFORMATION_IND:
1968 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1971 case L1_SIGNAL_LOS_ON:
1974 case L1_SIGNAL_LOS_OFF:
1977 case L1_SIGNAL_AIS_ON:
1980 case L1_SIGNAL_AIS_OFF:
1983 case L1_SIGNAL_RDI_ON:
1986 case L1_SIGNAL_RDI_OFF:
1989 case L1_SIGNAL_SLIP_TX:
1990 mISDNport->slip_tx++;
1992 case L1_SIGNAL_SLIP_RX:
1993 mISDNport->slip_rx++;
1998 case MT_L2ESTABLISH:
1999 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
2000 add_trace("tei", NULL, "%d", l3m->pid);
2002 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2004 if (mISDNport->l2establish)
2006 mISDNport->l2establish = 0;
2007 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2009 mISDNport->l2link = 1;
2014 if (!mISDNport->l2establish)
2016 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2017 add_trace("tei", NULL, "%d", l3m->pid);
2020 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2022 mISDNport->l2link = 0;
2023 if (!mISDNport->l2establish && mISDNport->l2hold)
2025 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
2026 time(&mISDNport->l2establish);
2027 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2033 /* l3-data is sent to LCR */
2034 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
2041 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2043 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2044 mISDNport->l1timeout = 0;
2047 /* layer 2 establish timer */
2048 if (mISDNport->l2establish)
2050 if (now-mISDNport->l2establish > 5)
2052 mISDNport->l2establish = 0;
2053 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2056 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2057 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2058 time(&mISDNport->l2establish);
2065 mISDNport = mISDNport->next;
2068 /* if we received at least one b-frame, we will return 1 */
2072 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2076 * l3m must be queued, except for MT_ASSIGN
2079 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2082 /* special MT_ASSIGN handling:
2084 * if we request a PID from mlayer, we always do it while lcr is locked.
2085 * therefore we must check the MT_ASSIGN reply first before we lock.
2086 * this is because the MT_ASSIGN reply is received with the requesting
2087 * process, not by the mlayer thread!
2088 * this means, that the reply is sent during call of the request.
2089 * we must check if we get a reply and we know that we lcr is currently
2092 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER)
2094 /* let's do some checking if someone changes stack behaviour */
2095 if (mt_assign_pid != 0)
2096 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2097 mt_assign_pid = pid;
2101 /* queue message, create, if required */
2104 l3m = alloc_l3_msg();
2106 FATAL("No memory for layer 3 message\n");
2108 mb = container_of(l3m, struct mbuffer, l3);
2111 mqueue_tail(&mISDNport->upqueue, mb);
2117 * global function to add a new card (port)
2119 struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, struct interface *interface)
2122 struct mISDNport *mISDNport, **mISDNportp;
2126 // struct mlayer3 *ml3;
2127 struct mISDN_devinfo devinfo;
2128 unsigned int protocol, prop;
2130 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2133 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2139 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2142 if (port>cnt || port<1)
2144 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2148 pri = bri = pots = nt = te = 0;
2149 devinfo.id = port - 1;
2150 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2153 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2156 /* output the port info */
2157 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2162 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2167 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2172 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2178 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2185 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2191 if (force_nt && !nt)
2193 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2198 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2201 if (pots && !bri && !pri)
2203 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2208 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2213 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2216 /* set NT by turning off TE */
2219 /* if TE an NT is supported (and not forced to NT), turn off NT */
2223 /* add mISDNport structure */
2224 mISDNportp = &mISDNport_first;
2226 mISDNportp = &((*mISDNportp)->next);
2227 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2228 mISDNport->l1link = -1;
2230 *mISDNportp = mISDNport;
2232 /* if pri, must set PTP */
2253 /* allocate ressources of port */
2254 /* open layer 3 and init upqueue */
2255 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2256 prop = (1 << MISDN_FLG_L2_CLEAN);
2257 if (ptp) // ptp forced
2258 prop |= (1 << MISDN_FLG_PTP);
2259 if (nt) // supports hold/retrieve on nt-mode
2260 prop |= (1 << MISDN_FLG_NET_HOLD);
2261 if (l2hold) // supports layer 2 hold
2262 prop |= (1 << MISDN_FLG_L2_HOLD);
2263 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2264 mqueue_init(&mISDNport->upqueue);
2265 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_layer3, mISDNport);
2266 if (!mISDNport->ml3)
2268 mqueue_purge(&mISDNport->upqueue);
2269 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2277 "PORT (open failed)");
2279 mISDNport_close(mISDNport);
2284 /* if ntmode, establish L1 to send the tei removal during start */
2285 if (mISDNport->ntmode)
2289 act.prim = PH_ACTIVATE | REQUEST;
2290 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2291 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2294 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2295 usleep(10000); /* to be sure, that l1 is up */
2299 SCPY(mISDNport->name, devinfo.name);
2300 mISDNport->b_num = devinfo.nrbchan;
2301 mISDNport->portnum = port;
2302 mISDNport->ntmode = nt;
2303 mISDNport->pri = pri;
2304 mISDNport->ptp = ptp;
2305 mISDNport->l2hold = l2hold;
2306 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2308 while(i < mISDNport->b_num)
2310 mISDNport->b_state[i] = B_STATE_IDLE;
2311 mISDNport->b_socket[i] = -1;
2315 /* if ptp, pull up the link */
2316 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2318 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2319 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2320 add_trace("tei", NULL, "%d", 0);
2322 time(&mISDNport->l2establish);
2325 /* initially, we assume that the link is down, exept for nt-ptmp */
2326 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2328 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2330 start_trace(mISDNport->portnum,
2338 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2339 add_trace("channels", NULL, "%d", mISDNport->b_num);
2346 * function to free ALL cards (ports)
2348 void mISDNport_close_all(void)
2350 /* free all ports */
2351 while(mISDNport_first)
2352 mISDNport_close(mISDNport_first);
2356 * free only one port
2358 void mISDNport_close(struct mISDNport *mISDNport)
2360 struct mISDNport **mISDNportp;
2362 class PmISDN *isdnport;
2365 /* remove all port instance that are linked to this mISDNport */
2369 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2371 isdnport = (class PmISDN *)port;
2372 if (isdnport->p_m_mISDNport)
2374 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2381 /* only if we are already part of interface */
2382 if (mISDNport->ifport)
2384 start_trace(mISDNport->portnum,
2385 mISDNport->ifport->interface,
2395 /* free bchannels */
2397 while(i < mISDNport->b_num)
2399 if (mISDNport->b_socket[i] > -1)
2401 _bchannel_destroy(mISDNport, i);
2402 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2407 /* close layer 3, if open and purge upqueue */
2410 close_layer3(mISDNport->ml3);
2411 mqueue_purge(&mISDNport->upqueue);
2414 /* remove from list */
2415 mISDNportp = &mISDNport_first;
2418 if (*mISDNportp == mISDNport)
2420 *mISDNportp = (*mISDNportp)->next;
2424 mISDNportp = &((*mISDNportp)->next);
2428 FATAL("mISDNport not in list\n");
2430 FREE(mISDNport, sizeof(struct mISDNport));
2437 * enque data from upper buffer
2439 void PmISDN::txfromup(unsigned char *data, int length)
2441 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2442 struct mISDNhead *hh = (struct mISDNhead *)buf;
2445 if (p_m_b_index < 0)
2447 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2450 /* check if high priority tones exist
2451 * ignore data in this case
2453 if (p_tone_name[0] || p_m_crypt_msg_loops)
2456 /* preload procedure
2457 * if transmit buffer in DSP module is empty,
2458 * preload it to DSP_LOAD to prevent jitter gaps.
2460 if (p_m_load==0 && ISDN_LOAD>0)
2462 hh->prim = PH_DATA_REQ;
2464 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2465 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2467 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
2468 p_m_load += ISDN_LOAD;
2471 /* drop if load would exceed ISDN_MAXLOAD
2472 * this keeps the delay not too high
2474 if (p_m_load+length > ISDN_MAXLOAD)
2477 /* make and send frame */
2478 hh->prim = PH_DATA_REQ;
2480 memcpy(buf+MISDN_HEADER_LEN, data, length);
2481 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2483 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);