1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 **
10 \*****************************************************************************/
20 #ifdef __compiler_offsetof
21 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
23 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
26 #define container_of(ptr, type, member) ({ \
27 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
28 (type *)( (char *)__mptr - offsetof(type,member) );})
30 // timeouts if activating/deactivating response from mISDN got lost
31 #define B_TIMER_ACTIVATING 1 // seconds
32 #define B_TIMER_DEACTIVATING 1 // seconds
34 /* list of mISDN ports */
35 struct mISDNport *mISDNport_first;
37 /* noise randomizer */
38 unsigned char mISDN_rand[256];
39 int mISDN_rand_count = 0;
41 unsigned long mt_assign_pid = ~0;
45 int mISDN_initialize(void)
49 /* try to open raw socket to check kernel */
50 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
53 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
58 init_layer3(4); // buffer of 4
60 /* open debug, if enabled and not only stack debugging */
63 SPRINT(filename, "%s/debug.log", INSTALL_DATA);
64 debug_fp = fopen(filename, "a");
67 if (options.deb & DEBUG_STACK)
69 SPRINT(filename, "%s/debug_mISDN.log", INSTALL_DATA);
70 mISDN_debug_init(0xffffffff, filename, filename, filename);
72 mISDN_debug_init(0, NULL, NULL, NULL);
77 void mISDN_deinitialize(void)
94 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : Port(type, portname, settings)
96 p_m_mISDNport = mISDNport;
97 p_m_portnum = mISDNport->portnum;
104 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
105 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
113 p_m_dtmf = !mISDNport->ifport->nodtmf;
116 p_m_remote_ref = 0; /* channel shall be exported to given remote */
117 p_m_remote_id = 0; /* channel shall be exported to given remote */
118 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
126 p_m_crypt_listen = 0;
127 p_m_crypt_msg_loops = 0;
128 p_m_crypt_msg_loops = 0;
129 p_m_crypt_msg_len = 0;
130 p_m_crypt_msg[0] = '\0';
131 p_m_crypt_msg_current = 0;
132 p_m_crypt_key_len = 0;
133 p_m_crypt_listen = 0;
134 p_m_crypt_listen_state = 0;
135 p_m_crypt_listen_len = 0;
136 p_m_crypt_listen_msg[0] = '\0';
137 p_m_crypt_listen_crc = 0;
138 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56)
140 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
141 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
145 /* if any channel requested by constructor */
146 if (channel == CHANNEL_ANY)
148 /* reserve channel */
150 mISDNport->b_reserved++;
153 /* reserve channel */
154 if (channel > 0) // only if constructor was called with a channel resevation
155 seize_bchannel(channel, exclusive);
157 /* we increase the number of objects: */
159 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
168 struct lcr_msg *message;
170 /* remove bchannel relation */
176 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
177 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
178 message->param.disconnectinfo.cause = 16;
179 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
180 message_put(message);
181 /* remove from list */
182 free_epointlist(p_epointlist);
185 /* we decrease the number of objects: */
186 p_m_mISDNport->use--;
187 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
194 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
196 /* init trace with given values */
197 start_trace(mISDNport?mISDNport->portnum:0,
198 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
199 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
200 port?port->p_dialinginfo.id:NULL,
203 port?port->p_serial:0,
211 static struct isdn_message {
215 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
216 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
217 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
218 {"DL_RELEASE", L2_RELEASE_REQ},
219 {"UNKNOWN", L3_UNKNOWN},
220 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
221 {"MT_SETUP", L3_SETUP_REQ},
222 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
223 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
224 {"MT_ALERTING", L3_ALERTING_REQ},
225 {"MT_CONNECT", L3_CONNECT_REQ},
226 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
227 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
228 {"MT_RELEASE", L3_RELEASE_REQ},
229 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
230 {"MT_INFORMATION", L3_INFORMATION_REQ},
231 {"MT_PROGRESS", L3_PROGRESS_REQ},
232 {"MT_NOTIFY", L3_NOTIFY_REQ},
233 {"MT_SUSPEND", L3_SUSPEND_REQ},
234 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
235 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
236 {"MT_RESUME", L3_RESUME_REQ},
237 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
238 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
239 {"MT_HOLD", L3_HOLD_REQ},
240 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
241 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
242 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
243 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
244 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
245 {"MT_FACILITY", L3_FACILITY_REQ},
246 {"MT_STATUS", L3_STATUS_REQ},
247 {"MT_RESTART", L3_RESTART_REQ},
248 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
249 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
252 static char *isdn_prim[4] = {
258 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long msg, int direction)
261 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
263 /* select message and primitive text */
265 while(isdn_message[i].name)
267 if (isdn_message[i].value == (msg&0xffffff00))
269 SCPY(msgtext, isdn_message[i].name);
274 SCAT(msgtext, isdn_prim[msg&0x00000003]);
277 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ)
281 if (mISDNport->ntmode)
283 if (direction == DIRECTION_OUT)
284 SCAT(msgtext, " N->U");
286 SCAT(msgtext, " N<-U");
289 if (direction == DIRECTION_OUT)
290 SCAT(msgtext, " U->N");
292 SCAT(msgtext, " U<-N");
297 /* init trace with given values */
298 start_trace(mISDNport?mISDNport->portnum:0,
299 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
300 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
301 port?port->p_dialinginfo.id:NULL,
304 port?port->p_serial:0,
310 * send control information to the channel (dsp-module)
312 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long sock, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
314 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
315 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
316 unsigned long *d = (unsigned long *)(buffer+MISDN_HEADER_LEN);
322 ctrl->prim = PH_CONTROL_REQ;
326 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
328 PERROR("Failed to send to socket %d\n", sock);
329 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
330 if (c1 == DSP_CONF_JOIN)
331 add_trace(trace_name, NULL, "0x%08x", trace_value);
333 add_trace(trace_name, NULL, "%d", trace_value);
337 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned long c1, void *c2, int c2_len, char *trace_name, int trace_value)
339 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
340 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
341 unsigned long *d = (unsigned long *)(buffer+MISDN_HEADER_LEN);
347 ctrl->prim = PH_CONTROL_REQ;
350 memcpy(d, c2, c2_len);
351 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
353 PERROR("Failed to send to socket %d\n", sock);
354 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
355 add_trace(trace_name, NULL, "%d", trace_value);
361 * subfunction for bchannel_event
364 static int _bchannel_create(struct mISDNport *mISDNport, int i)
367 unsigned long on = 1;
368 struct sockaddr_mISDN addr;
370 if (mISDNport->b_socket[i] > -1)
372 PERROR("Error: Socket already created for index %d\n", i);
377 //#warning testing without DSP
378 // mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_RAW);
379 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
380 if (mISDNport->b_socket[i] < 0)
382 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
386 /* set nonblocking io */
387 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
390 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
391 close(mISDNport->b_socket[i]);
392 mISDNport->b_socket[i] = -1;
396 /* bind socket to bchannel */
397 addr.family = AF_ISDN;
398 addr.dev = mISDNport->portnum-1;
399 addr.channel = i+1+(i>=15);
400 ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr));
403 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
404 close(mISDNport->b_socket[i]);
405 mISDNport->b_socket[i] = -1;
409 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
410 add_trace("channel", NULL, "%d", i+1+(i>=15));
411 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
419 * subfunction for bchannel_event
420 * activate / deactivate request
422 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
424 struct mISDNhead act;
427 if (mISDNport->b_socket[i] < 0)
429 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
431 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
433 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
436 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
437 add_trace("channel", NULL, "%d", i+1+(i>=15));
438 if (mISDNport->b_timer[i])
439 add_trace("event", NULL, "timeout recovery");
445 * subfunction for bchannel_event
448 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
453 if (mISDNport->b_socket[i] < 0)
455 handle = mISDNport->b_socket[i];
456 port = mISDNport->b_port[i];
459 PERROR("bchannel index i=%d not associated with a port object\n", i);
463 /* set dsp features */
464 if (port->p_m_txdata)
465 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
467 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
468 if (port->p_m_tx_gain)
469 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
470 if (port->p_m_rx_gain)
471 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
472 if (port->p_m_pipeline[0])
473 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
475 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
477 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
479 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
481 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
482 // if (port->p_m_txmix)
483 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
485 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
487 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);
491 * subfunction for bchannel_event
494 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
496 if (mISDNport->b_socket[i] < 0)
498 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
499 add_trace("channel", NULL, "%d", i+1+(i>=15));
500 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
502 close(mISDNport->b_socket[i]);
503 mISDNport->b_socket[i] = -1;
511 A bchannel goes through the following states in this order:
514 No one is using the bchannel.
515 It is available and not linked to Port class, nor reserved.
518 The bchannel stack is created and an activation request is sent.
519 It MAY be linked to Port class, but already unlinked due to Port class removal.
522 The bchannel is active and cofigured to the Port class needs.
523 Also it is linked to a Port class, otherwhise it would be deactivated.
525 - B_STATE_DEACTIVATING
526 The bchannel is in deactivating state, due to deactivation request.
527 It may be linked to a Port class, that likes to reactivate it.
531 After deactivating bchannel, and if not used, the bchannel becomes idle again.
533 Also the bchannel may be exported, but only if the state is or becomes idle:
536 The bchannel assignment has been sent to the remove application.
539 The bchannel assignment is acknowledged by the remote application.
542 The bchannel is re-imported by mISDN port object.
546 After re-importing bchannel, and if not used, the bchannel becomes idle again.
549 A bchannel can have the following events:
552 A bchannel is required by a Port class.
555 The bchannel beomes active.
558 The bchannel is not required by Port class anymore
560 - B_EVENT_DEACTIVATED
561 The bchannel becomes inactive.
564 The bchannel is now used by remote application.
567 The bchannel is not used by remote application.
569 - B_EVENT_EXPORTREQUEST
570 The bchannel shall be exported to the remote application.
572 - B_EVENT_IMPORTREQUEST
573 The bchannel is released from the remote application.
575 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
577 if an export request is receive by remote application, p_m_remote_* is set.
578 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.)
579 - set on export request from remote application (if port is assigned)
580 - set on channel use, if requested by remote application (p_m_remote_*)
581 - cleared on drop request
583 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
584 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
585 the bchannel import/export is acknowledged with stack given.
587 if exporting, b_remote_*[index] is set to the remote socket id.
588 if importing has been acknowledged. b_remote_*[index] is cleared.
593 * process bchannel events
594 * - mISDNport is a pointer to the port's structure
595 * - i is the index of the bchannel
596 * - event is the B_EVENT_* value
597 * - port is the PmISDN class pointer
599 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
601 class PmISDN *b_port = mISDNport->b_port[i];
602 int state = mISDNport->b_state[i];
603 double timer = mISDNport->b_timer[i];
604 unsigned long p_m_remote_ref = 0;
605 unsigned long p_m_remote_id = 0;
608 char *p_m_pipeline = NULL;
609 unsigned char *p_m_crypt_key = NULL;
610 int p_m_crypt_key_len = 0;
611 int p_m_crypt_key_type = 0;
612 unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
616 p_m_remote_id = b_port->p_m_remote_id;
617 p_m_remote_ref = b_port->p_m_remote_ref;
618 p_m_tx_gain = b_port->p_m_tx_gain;
619 p_m_rx_gain = b_port->p_m_rx_gain;
620 p_m_pipeline = b_port->p_m_pipeline;
621 p_m_crypt_key = b_port->p_m_crypt_key;
622 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
623 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
629 /* port must be linked in order to allow activation */
631 FATAL("bchannel must be linked to a Port class\n");
637 /* export bchannel */
638 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);
639 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
640 add_trace("type", NULL, "assign");
641 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
643 state = B_STATE_EXPORTING;
644 mISDNport->b_remote_id[i] = p_m_remote_id;
645 mISDNport->b_remote_ref[i] = p_m_remote_ref;
648 /* create stack and send activation request */
649 if (_bchannel_create(mISDNport, i))
651 _bchannel_activate(mISDNport, i, 1);
652 state = B_STATE_ACTIVATING;
653 timer = now_d + B_TIMER_ACTIVATING;
658 case B_STATE_ACTIVATING:
659 case B_STATE_EXPORTING:
660 /* do nothing, because it is already activating */
663 case B_STATE_DEACTIVATING:
664 case B_STATE_IMPORTING:
665 /* do nothing, because we must wait until we can reactivate */
669 /* problems that might ocurr:
670 * B_EVENT_USE is received when channel already in use.
671 * bchannel exported, but not freed by other port
673 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
677 case B_EVENT_EXPORTREQUEST:
678 /* special case where the bchannel is requested by remote */
681 PERROR("export request without remote channel set, please correct.\n");
687 /* in case, the bchannel is exported right after seize_bchannel */
688 /* export bchannel */
689 /* p_m_remote_id is set, when this event happens. */
690 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);
691 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
692 add_trace("type", NULL, "assign");
693 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
695 state = B_STATE_EXPORTING;
696 mISDNport->b_remote_id[i] = p_m_remote_id;
697 mISDNport->b_remote_ref[i] = p_m_remote_ref;
700 case B_STATE_ACTIVATING:
701 case B_STATE_EXPORTING:
702 /* do nothing, because it is already activating */
705 case B_STATE_DEACTIVATING:
706 case B_STATE_IMPORTING:
707 /* do nothing, because we must wait until we can reactivate */
711 /* bchannel is active, so we deactivate */
712 _bchannel_activate(mISDNport, i, 0);
713 state = B_STATE_DEACTIVATING;
714 timer = now_d + B_TIMER_DEACTIVATING;
718 /* problems that might ocurr:
719 * ... when channel already in use.
720 * bchannel exported, but not freed by other port
722 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
726 case B_EVENT_IMPORTREQUEST:
727 /* special case where the bchannel is released by remote */
730 PERROR("import request with remote channel set, please correct.\n");
737 /* bchannel is not exported */
740 case B_STATE_ACTIVATING:
741 case B_STATE_EXPORTING:
742 /* do nothing because we must wait until bchanenl is active before deactivating */
746 /* bchannel is exported, so we re-import */
747 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
748 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
749 add_trace("type", NULL, "remove");
750 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
752 state = B_STATE_IMPORTING;
755 case B_STATE_DEACTIVATING:
756 case B_STATE_IMPORTING:
757 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
761 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
765 case B_EVENT_ACTIVATED:
769 case B_STATE_ACTIVATING:
770 if (b_port && !p_m_remote_id)
772 /* bchannel is active and used by Port class, so we configure bchannel */
773 _bchannel_configure(mISDNport, i);
774 state = B_STATE_ACTIVE;
777 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
778 _bchannel_activate(mISDNport, i, 0);
779 state = B_STATE_DEACTIVATING;
780 timer = now_d + B_TIMER_DEACTIVATING;
785 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
789 case B_EVENT_EXPORTED:
792 case B_STATE_EXPORTING:
793 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
795 /* remote export done */
796 state = B_STATE_REMOTE;
799 /* bchannel is now exported, but we need bchannel back
800 * OR bchannel is not used anymore
801 * OR bchannel has been exported to an obsolete ref,
802 * so reimport, to later export to new remote */
803 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
804 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
805 add_trace("type", NULL, "remove");
806 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
808 state = B_STATE_IMPORTING;
813 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
819 FATAL("bchannel must be linked to a Port class\n");
823 /* bchannel is idle due to an error, so we do nothing */
826 case B_STATE_ACTIVATING:
827 case B_STATE_EXPORTING:
828 /* do nothing because we must wait until bchanenl is active before deactivating */
832 /* bchannel is active, so we deactivate */
833 _bchannel_activate(mISDNport, i, 0);
834 state = B_STATE_DEACTIVATING;
835 timer = now_d + B_TIMER_DEACTIVATING;
839 /* bchannel is exported, so we re-import */
840 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
841 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
842 add_trace("type", NULL, "remove");
843 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
845 state = B_STATE_IMPORTING;
848 case B_STATE_DEACTIVATING:
849 case B_STATE_IMPORTING:
850 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
854 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
858 case B_EVENT_DEACTIVATED:
863 /* ignore due to deactivation confirm after unloading */
866 case B_STATE_DEACTIVATING:
867 _bchannel_destroy(mISDNport, i);
868 state = B_STATE_IDLE;
871 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
874 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);
875 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
876 add_trace("type", NULL, "assign");
877 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
879 state = B_STATE_EXPORTING;
880 mISDNport->b_remote_id[i] = p_m_remote_id;
881 mISDNport->b_remote_ref[i] = p_m_remote_ref;
884 if (_bchannel_create(mISDNport, i))
886 _bchannel_activate(mISDNport, i, 1);
887 state = B_STATE_ACTIVATING;
888 timer = now_d + B_TIMER_ACTIVATING;
895 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
899 case B_EVENT_IMPORTED:
902 case B_STATE_IMPORTING:
903 state = B_STATE_IDLE;
904 mISDNport->b_remote_id[i] = 0;
905 mISDNport->b_remote_ref[i] = 0;
908 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
911 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);
912 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
913 add_trace("type", NULL, "assign");
914 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
916 state = B_STATE_EXPORTING;
917 mISDNport->b_remote_id[i] = p_m_remote_id;
918 mISDNport->b_remote_ref[i] = p_m_remote_ref;
921 if (_bchannel_create(mISDNport, i))
923 _bchannel_activate(mISDNport, i, 1);
924 state = B_STATE_ACTIVATING;
925 timer = now_d + B_TIMER_ACTIVATING;
932 /* ignore, because not assigned */
937 case B_EVENT_TIMEOUT:
942 /* ignore due to deactivation confirm after unloading */
945 case B_STATE_ACTIVATING:
946 _bchannel_activate(mISDNport, i, 1);
947 timer = now_d + B_TIMER_ACTIVATING;
950 case B_STATE_DEACTIVATING:
951 _bchannel_activate(mISDNport, i, 0);
952 timer = now_d + B_TIMER_DEACTIVATING;
956 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
961 PERROR("Illegal event %d, please correct.\n", event);
964 mISDNport->b_state[i] = state;
965 mISDNport->b_timer[i] = timer;
972 * check for available channel and reserve+set it.
973 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
975 * returns -(cause value) or x = channel x or 0 = no channel
976 * NOTE: no activation is done here
978 int PmISDN::seize_bchannel(int channel, int exclusive)
982 /* the channel is what we have */
983 if (p_m_b_channel == channel)
986 /* if channel already in use, release it */
991 if (channel==CHANNEL_NO || channel==0)
994 /* is channel in range ? */
996 || (channel>p_m_mISDNport->b_num && channel<16)
997 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
998 return(-6); /* channel unacceptable */
1000 /* request exclusive channel */
1001 if (exclusive && channel>0)
1003 i = channel-1-(channel>16);
1004 if (p_m_mISDNport->b_port[i])
1005 return(-44); /* requested channel not available */
1009 /* ask for channel */
1012 i = channel-1-(channel>16);
1013 if (p_m_mISDNport->b_port[i] == NULL)
1017 /* search for channel */
1019 while(i < p_m_mISDNport->b_num)
1021 if (!p_m_mISDNport->b_port[i])
1023 channel = i+1+(i>=15);
1028 return(-34); /* no free channel */
1031 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1034 p_m_mISDNport->b_port[i] = this;
1036 p_m_b_channel = channel;
1037 p_m_b_exclusive = exclusive;
1039 /* reserve channel */
1043 p_m_mISDNport->b_reserved++;
1050 * drop reserved channel and unset it.
1051 * deactivation is also done
1053 void PmISDN::drop_bchannel(void)
1055 /* unreserve channel */
1057 p_m_mISDNport->b_reserved--;
1061 if (p_m_b_index < 0)
1066 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1068 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1069 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1070 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1073 p_m_b_exclusive = 0;
1076 /* process bchannel export/import message from join */
1077 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned long handle)
1079 class Endpoint *epoint;
1081 class PmISDN *isdnport;
1082 struct mISDNport *mISDNport;
1087 case BCHANNEL_REQUEST:
1088 /* find the port object for the join object ref */
1089 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1091 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1094 if (!epoint->ep_portlist)
1096 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1099 if (epoint->ep_portlist->next)
1101 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);
1103 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1105 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1108 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN)
1110 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1112 isdnport = (class PmISDN *)port;
1115 if (isdnport->p_m_remote_id)
1117 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1120 mISDNport = isdnport->p_m_mISDNport;
1121 i = isdnport->p_m_b_index;
1122 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1123 add_trace("type", NULL, "export request");
1125 isdnport->p_m_remote_ref = joinremote->j_serial;
1126 isdnport->p_m_remote_id = joinremote->j_remote_id;
1127 if (mISDNport && i>=0)
1129 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1133 case BCHANNEL_RELEASE:
1134 case BCHANNEL_ASSIGN_ACK:
1135 case BCHANNEL_REMOVE_ACK:
1136 /* find mISDNport for stack ID */
1137 mISDNport = mISDNport_first;
1141 ii = mISDNport->b_num;
1144 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1150 mISDNport = mISDNport->next;
1154 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1158 if (type!=BCHANNEL_RELEASE)
1161 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1162 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1164 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1168 isdnport = mISDNport->b_port[i];
1169 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1170 add_trace("type", NULL, "export request");
1174 isdnport->p_m_remote_ref = 0;
1175 isdnport->p_m_remote_id = 0;
1177 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1181 PERROR("received wrong bchannel message type %d from remote\n", type);
1189 audio transmission procedure:
1190 -----------------------------
1193 three sources of audio transmission:
1194 - crypto-data high priority
1195 - tones high priority (also high)
1196 - remote-data low priority
1199 a variable that temporarily shows the number of samples elapsed since last transmission process.
1200 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1203 a variable that is increased whenever data is transmitted.
1204 it is decreased while time elapses. it stores the number of samples that
1205 are currently loaded to dsp module.
1206 since clock in dsp module is the same clock for user space process, these
1210 there are two levels:
1211 ISDN_LOAD will give the load that have to be kept in dsp.
1212 ISDN_MAXLOAD will give the maximum load before dropping.
1214 * procedure for low priority data
1215 see txfromup() for procedure
1216 in short: remote data is ignored during high priority tones
1218 * procedure for high priority data
1219 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1220 if no more data is available, load becomes empty again.
1223 0 ISDN_LOAD ISDN_MAXLOAD
1224 +--------------------+----------------------+
1226 +--------------------+----------------------+
1228 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1229 0 ISDN_LOAD ISDN_MAXLOAD
1230 +--------------------+----------------------+
1231 |TTTTTTTTTTTTTTTTTTTT| |
1232 +--------------------+----------------------+
1234 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1235 0 ISDN_LOAD ISDN_MAXLOAD
1236 +--------------------+----------------------+
1237 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1238 +--------------------+----------------------+
1241 int PmISDN::handler(void)
1243 struct lcr_msg *message;
1247 if ((ret = Port::handler()))
1251 if (p_m_last_tv_sec)
1253 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1254 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1257 /* set clock of first process ever in this instance */
1258 p_m_last_tv_sec = now_tv.tv_sec;
1259 p_m_last_tv_msec = now_tv.tv_usec/1000;
1261 /* process only if we have a minimum of samples, to make packets not too small */
1262 if (elapsed >= ISDN_TRANSMIT)
1264 /* set clock of last process! */
1265 p_m_last_tv_sec = now_tv.tv_sec;
1266 p_m_last_tv_msec = now_tv.tv_usec/1000;
1269 if (elapsed < p_m_load)
1270 p_m_load -= elapsed;
1274 /* to send data, tone must be active OR crypt messages must be on */
1275 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1276 && (p_m_load < ISDN_LOAD)
1277 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1279 int tosend = ISDN_LOAD - p_m_load, length;
1280 unsigned char buf[MISDN_HEADER_LEN+tosend];
1281 struct mISDNhead *frm = (struct mISDNhead *)buf;
1282 unsigned char *p = buf+MISDN_HEADER_LEN;
1284 /* copy crypto loops */
1285 while (p_m_crypt_msg_loops && tosend)
1287 /* how much do we have to send */
1288 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1291 if (length > tosend)
1294 /* copy message (part) to buffer */
1295 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1298 p_m_crypt_msg_current += length;
1299 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1302 p_m_crypt_msg_current = 0;
1303 p_m_crypt_msg_loops--;
1304 // puts("eine loop weniger");
1312 if (p_tone_name[0] && tosend)
1314 tosend -= read_audio(p, tosend);
1318 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && ISDN_LOAD-p_m_load-tosend > 0)
1320 frm->prim = PH_DATA_REQ;
1322 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1324 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);
1326 p_m_load += ISDN_LOAD - p_m_load - tosend;
1330 // NOTE: deletion is done by the child class
1332 /* handle timeouts */
1335 if (p_m_timer+p_m_timeout < now_d)
1337 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1339 /* send timeout to endpoint */
1340 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1341 message->param.state = p_state;
1342 message_put(message);
1347 return(0); /* nothing done */
1352 * whenever we get audio data from bchannel, we process it here
1354 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1356 unsigned long cont = *((unsigned long *)data);
1357 unsigned char *data_temp;
1358 unsigned long length_temp;
1359 struct lcr_msg *message;
1363 if (hh->prim == PH_CONTROL_IND)
1367 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1370 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1372 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1373 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1375 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1376 message->param.dtmf = cont & DTMF_TONE_MASK;
1377 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1378 message_put(message);
1384 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1385 add_trace("DSP-CRYPT", NULL, "error");
1387 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1388 message->param.crypt.type = CC_ERROR_IND;
1389 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1390 message_put(message);
1394 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1395 add_trace("DSP-CRYPT", NULL, "ok");
1397 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1398 message->param.crypt.type = CC_ACTBF_CONF;
1399 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1400 message_put(message);
1404 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1405 add_trace("unknown", NULL, "0x%x", cont);
1410 if (hh->prim == PH_CONTROL_IND)
1415 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1416 add_trace("unknown", NULL, "0x%x", hh->id);
1421 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ)
1425 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1426 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1429 /* see below (same condition) */
1430 if (p_state!=PORT_STATE_CONNECT
1431 && !p_m_mISDNport->tones)
1433 // printf(".");fflush(stdout);return;
1435 record(data, len, 1); // from up
1438 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1440 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1444 /* calls will not process any audio data unless
1445 * the call is connected OR tones feature is enabled.
1447 #ifndef DEBUG_COREBRIDGE
1448 if (p_state!=PORT_STATE_CONNECT
1449 && !p_m_mISDNport->tones)
1454 /* the bearer capability must be audio in order to send and receive
1455 * audio prior or after connect.
1457 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1461 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1464 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1470 record(data, len, 0); // from down
1472 /* randomize and listen to crypt message if enabled */
1473 if (p_m_crypt_listen)
1475 /* the noisy randomizer */
1479 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1481 cryptman_listen_bch(data, len);
1486 /* send data to epoint */
1487 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1493 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1494 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1495 memcpy(message->param.data.data, data_temp, message->param.data.len);
1496 message_put(message);
1497 if (length_temp <= sizeof(message->param.data.data))
1499 data_temp += sizeof(message->param.data.data);
1500 length_temp -= sizeof(message->param.data.data);
1509 void PmISDN::set_echotest(int echo)
1511 if (p_m_echo != echo)
1514 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1516 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1517 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);
1524 void PmISDN::set_tone(char *dir, char *tone)
1530 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1537 /* check if we NOT really have to use a dsp-tone */
1538 if (!options.dsptones)
1542 if (p_m_b_index > -1)
1543 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1545 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1546 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1549 Port::set_tone(dir, tone);
1555 /* now we USE dsp-tone, convert name */
1556 else if (!strcmp(tone, "dialtone"))
1558 switch(options.dsptones) {
1559 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1560 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1561 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1563 } else if (!strcmp(tone, "dialpbx"))
1565 switch(options.dsptones) {
1566 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1567 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1568 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1570 } else if (!strcmp(tone, "ringing"))
1572 switch(options.dsptones) {
1573 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1574 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1575 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1577 } else if (!strcmp(tone, "ringpbx"))
1579 switch(options.dsptones) {
1580 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1581 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1582 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1584 } else if (!strcmp(tone, "busy"))
1587 switch(options.dsptones) {
1588 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1589 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1590 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1592 } else if (!strcmp(tone, "release"))
1595 switch(options.dsptones) {
1596 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1597 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1598 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1600 } else if (!strcmp(tone, "cause_10"))
1602 else if (!strcmp(tone, "cause_11"))
1604 else if (!strcmp(tone, "cause_22"))
1606 switch(options.dsptones) {
1607 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1608 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1609 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1611 } else if (!strncmp(tone, "cause_", 6))
1612 id = TONE_SPECIAL_INFO;
1616 /* if we have a tone that is not supported by dsp */
1617 if (id==TONE_OFF && tone[0])
1625 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1626 if (p_m_b_index > -1)
1627 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1628 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);
1630 /* turn user-space tones off in cases of no tone OR dsp tone */
1631 Port::set_tone("",NULL);
1635 /* MESSAGE_mISDNSIGNAL */
1636 //extern struct lcr_msg *dddebug;
1637 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1639 switch(param->mISDNsignal.message)
1641 case mISDNSIGNAL_VOLUME:
1642 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1644 p_m_tx_gain = param->mISDNsignal.tx_gain;
1645 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1646 if (p_m_b_index > -1)
1647 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1648 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);
1650 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1651 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1653 p_m_rx_gain = param->mISDNsignal.rx_gain;
1654 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1655 if (p_m_b_index > -1)
1656 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1657 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);
1659 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1662 case mISDNSIGNAL_CONF:
1663 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1664 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1665 if (p_m_conf != param->mISDNsignal.conf)
1667 p_m_conf = param->mISDNsignal.conf;
1668 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1669 if (p_m_b_index > -1)
1670 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1671 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);
1673 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1674 /* we must set, even if currently tone forbids conf */
1675 p_m_conf = param->mISDNsignal.conf;
1676 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1679 case mISDNSIGNAL_JOINDATA:
1680 if (p_m_joindata != param->mISDNsignal.joindata)
1682 p_m_joindata = param->mISDNsignal.joindata;
1683 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1685 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1688 case mISDNSIGNAL_DELAY:
1689 if (p_m_delay != param->mISDNsignal.delay)
1691 p_m_delay = param->mISDNsignal.delay;
1692 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1693 if (p_m_b_index > -1)
1694 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1695 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);
1697 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1701 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1706 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1708 struct lcr_msg *message;
1710 switch(param->crypt.type)
1712 case CC_ACTBF_REQ: /* activate blowfish */
1714 p_m_crypt_key_len = param->crypt.len;
1715 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1717 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1718 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1719 message->param.crypt.type = CC_ERROR_IND;
1720 message_put(message);
1723 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1725 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1726 if (p_m_b_index > -1)
1727 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1728 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);
1731 case CC_DACT_REQ: /* deactivate session encryption */
1736 case CR_LISTEN_REQ: /* start listening to messages */
1737 p_m_crypt_listen = 1;
1738 p_m_crypt_listen_state = 0;
1741 case CR_UNLISTEN_REQ: /* stop listening to messages */
1742 p_m_crypt_listen = 0;
1745 case CR_MESSAGE_REQ: /* send message */
1746 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1747 if (!p_m_crypt_msg_len)
1749 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1752 p_m_crypt_msg_current = 0; /* reset */
1753 p_m_crypt_msg_loops = 6; /* enable */
1755 /* disable txmix, or we get corrupt data due to audio process */
1756 if (p_m_txmix && p_m_b_index>=0)
1758 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1759 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1765 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1771 * endpoint sends messages to the port
1773 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1775 if (Port::message_epoint(epoint_id, message_id, param))
1780 case MESSAGE_DATA: /* tx-data from upper layer */
1781 txfromup(param->data.data, param->data.len);
1784 case MESSAGE_mISDNSIGNAL: /* user command */
1785 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1786 message_mISDNsignal(epoint_id, message_id, param);
1789 case MESSAGE_CRYPT: /* crypt control command */
1790 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1791 message_crypt(epoint_id, message_id, param);
1800 * main loop for processing messages from mISDN
1802 int mISDN_handler(void)
1805 struct mISDNport *mISDNport;
1806 class PmISDN *isdnport;
1808 unsigned char buffer[2048+MISDN_HEADER_LEN];
1809 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1813 /* process all ports */
1814 mISDNport = mISDNport_first;
1817 /* process all bchannels */
1819 while(i < mISDNport->b_num)
1821 /* process timer events for bchannel handling */
1822 if (mISDNport->b_timer[i])
1824 if (mISDNport->b_timer[i] <= now_d)
1825 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
1827 /* handle port of bchannel */
1828 isdnport=mISDNport->b_port[i];
1831 /* call bridges in user space OR crypto OR recording */
1832 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1834 /* rx IS required */
1835 if (isdnport->p_m_rxoff)
1838 isdnport->p_m_rxoff = 0;
1839 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1840 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1841 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1846 /* rx NOT required */
1847 if (!isdnport->p_m_rxoff)
1850 isdnport->p_m_rxoff = 1;
1851 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1852 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1853 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1858 if (isdnport->p_record)
1860 /* txdata IS required */
1861 if (!isdnport->p_m_txdata)
1864 isdnport->p_m_txdata = 1;
1865 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1866 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1867 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1872 /* txdata NOT required */
1873 if (isdnport->p_m_txdata)
1876 isdnport->p_m_txdata = 0;
1877 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1878 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1879 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1885 /* handle message from bchannel */
1886 if (mISDNport->b_socket[i] > -1)
1888 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
1889 if (ret >= (int)MISDN_HEADER_LEN)
1894 /* we don't care about confirms, we use rx data to sync tx */
1898 /* we receive audio data, we respond to it AND we send tones */
1903 case PH_CONTROL_IND:
1904 if (mISDNport->b_port[i])
1905 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1907 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
1910 case PH_ACTIVATE_IND:
1911 case DL_ESTABLISH_IND:
1912 case PH_ACTIVATE_CNF:
1913 case DL_ESTABLISH_CNF:
1914 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
1915 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1918 case PH_DEACTIVATE_IND:
1919 case DL_RELEASE_IND:
1920 case PH_DEACTIVATE_CNF:
1921 case DL_RELEASE_CNF:
1922 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
1923 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1927 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
1931 if (ret < 0 && errno != EWOULDBLOCK)
1932 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
1939 /* handle queued up-messages (d-channel) */
1940 while ((mb = mdequeue(&mISDNport->upqueue)))
1945 case MPH_ACTIVATE_IND:
1946 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1948 mISDNport->l1link = 1;
1951 case MPH_DEACTIVATE_IND:
1952 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1954 mISDNport->l1link = 0;
1957 case MPH_INFORMATION_IND:
1958 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1961 case L1_SIGNAL_LOS_ON:
1964 case L1_SIGNAL_LOS_OFF:
1967 case L1_SIGNAL_AIS_ON:
1970 case L1_SIGNAL_AIS_OFF:
1973 case L1_SIGNAL_RDI_ON:
1976 case L1_SIGNAL_RDI_OFF:
1979 case L1_SIGNAL_SLIP_TX:
1980 mISDNport->slip_tx++;
1982 case L1_SIGNAL_SLIP_RX:
1983 mISDNport->slip_rx++;
1988 case MT_L2ESTABLISH:
1989 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1990 add_trace("tei", NULL, "%d", l3m->pid);
1992 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
1994 if (mISDNport->l2establish)
1996 mISDNport->l2establish = 0;
1997 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1999 mISDNport->l2link = 1;
2004 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2005 add_trace("tei", NULL, "%d", l3m->pid);
2007 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2009 mISDNport->l2link = 0;
2010 if (mISDNport->l2hold)
2012 time(&mISDNport->l2establish);
2013 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2019 /* l3-data is sent to LCR */
2020 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
2027 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2029 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2030 mISDNport->l1timeout = 0;
2033 /* layer 2 establish timer */
2034 if (mISDNport->l2establish)
2036 if (now-mISDNport->l2establish > 5)
2038 mISDNport->l2establish = 0;
2039 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2042 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2043 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2044 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2045 add_trace("tei", NULL, "%d", 0);
2047 time(&mISDNport->l2establish);
2054 mISDNport = mISDNport->next;
2057 /* if we received at least one b-frame, we will return 1 */
2061 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2065 * l3m must be queued, except for MT_ASSIGN
2068 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2071 /* special MT_ASSIGN handling:
2073 * if we request a PID from mlayer, we always do it while lcr is locked.
2074 * therefore we must check the MT_ASSIGN reply first before we lock.
2075 * this is because the MT_ASSIGN reply is received with the requesting
2076 * process, not by the mlayer thread!
2077 * this means, that the reply is sent during call of the request.
2078 * we must check if we get a reply and we know that we lcr is currently
2081 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER)
2083 /* let's do some checking if someone changes stack behaviour */
2084 if (mt_assign_pid != 0)
2085 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2086 mt_assign_pid = pid;
2090 /* queue message, create, if required */
2093 l3m = alloc_l3_msg();
2095 FATAL("No memory for layer 3 message\n");
2097 mb = container_of(l3m, struct mbuffer, l3);
2100 mqueue_tail(&mISDNport->upqueue, mb);
2106 * global function to add a new card (port)
2108 struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, struct interface *interface)
2111 struct mISDNport *mISDNport, **mISDNportp;
2115 // struct mlayer3 *ml3;
2116 struct mISDN_devinfo devinfo;
2117 unsigned int protocol, prop;
2119 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2122 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2128 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2131 if (port>cnt || port<1)
2133 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2137 pri = bri = pots = nt = te = 0;
2138 devinfo.id = port - 1;
2139 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2142 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2145 /* output the port info */
2146 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2151 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2156 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2161 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2167 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2174 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2180 if (force_nt && !nt)
2182 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2187 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2190 if (pots && !bri && !pri)
2192 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2197 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2202 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2205 /* set NT by turning off TE */
2208 /* if TE an NT is supported (and not forced to NT), turn off NT */
2212 /* add mISDNport structure */
2213 mISDNportp = &mISDNport_first;
2215 mISDNportp = &((*mISDNportp)->next);
2216 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2218 *mISDNportp = mISDNport;
2220 /* if pri, must set PTP */
2241 /* allocate ressources of port */
2242 /* open layer 3 and init upqueue */
2243 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2244 prop = (1 << MISDN_FLG_L2_CLEAN);
2245 if (ptp) // ptp forced
2246 prop |= (1 << MISDN_FLG_PTP);
2247 if (nt) // supports hold/retrieve on nt-mode
2248 prop |= (1 << MISDN_FLG_NET_HOLD);
2249 if (l2hold) // supports layer 2 hold
2250 prop |= (1 << MISDN_FLG_L2_HOLD);
2251 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2252 mqueue_init(&mISDNport->upqueue);
2253 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_layer3, mISDNport);
2254 if (!mISDNport->ml3)
2256 mqueue_purge(&mISDNport->upqueue);
2257 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2265 "PORT (open failed)");
2267 mISDNport_close(mISDNport);
2272 /* if ntmode, establish L1 to send the tei removal during start */
2273 if (mISDNport->ntmode)
2277 act.prim = PH_ACTIVATE | REQUEST;
2278 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2279 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2282 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2283 usleep(10000); /* to be sure, that l1 is up */
2287 SCPY(mISDNport->name, devinfo.name);
2288 mISDNport->b_num = devinfo.nrbchan;
2289 mISDNport->portnum = port;
2290 mISDNport->ntmode = nt;
2291 mISDNport->pri = pri;
2292 mISDNport->ptp = ptp;
2293 mISDNport->l2hold = l2hold;
2294 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2296 while(i < mISDNport->b_num)
2298 mISDNport->b_state[i] = B_STATE_IDLE;
2299 mISDNport->b_socket[i] = -1;
2303 /* if ptp, pull up the link */
2304 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2306 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2307 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2308 add_trace("tei", NULL, "%d", 0);
2310 time(&mISDNport->l2establish);
2313 /* initially, we assume that the link is down, exept for nt-ptmp */
2314 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2316 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2318 start_trace(mISDNport->portnum,
2326 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2327 add_trace("channels", NULL, "%d", mISDNport->b_num);
2334 * function to free ALL cards (ports)
2336 void mISDNport_close_all(void)
2338 /* free all ports */
2339 while(mISDNport_first)
2340 mISDNport_close(mISDNport_first);
2344 * free only one port
2346 void mISDNport_close(struct mISDNport *mISDNport)
2348 struct mISDNport **mISDNportp;
2350 class PmISDN *isdnport;
2353 /* remove all port instance that are linked to this mISDNport */
2357 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2359 isdnport = (class PmISDN *)port;
2360 if (isdnport->p_m_mISDNport)
2362 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2369 /* only if we are already part of interface */
2370 if (mISDNport->ifport)
2372 start_trace(mISDNport->portnum,
2373 mISDNport->ifport->interface,
2383 /* free bchannels */
2385 while(i < mISDNport->b_num)
2387 if (mISDNport->b_socket[i] > -1)
2389 _bchannel_destroy(mISDNport, i);
2390 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2395 /* close layer 3, if open and purge upqueue */
2398 close_layer3(mISDNport->ml3);
2399 mqueue_purge(&mISDNport->upqueue);
2402 /* remove from list */
2403 mISDNportp = &mISDNport_first;
2406 if (*mISDNportp == mISDNport)
2408 *mISDNportp = (*mISDNportp)->next;
2412 mISDNportp = &((*mISDNportp)->next);
2416 FATAL("mISDNport not in list\n");
2418 FREE(mISDNport, sizeof(struct mISDNport));
2425 * global function to show all available isdn ports
2427 void mISDN_port_info(void)
2431 int useable, nt, te, pri, bri, pots;
2432 struct mISDN_devinfo devinfo;
2436 sock = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
2439 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
2443 /* get number of stacks */
2445 ret = ioctl(sock, IMGETCOUNT, &ii);
2448 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2454 printf("Found no card. Please be sure to load card drivers.\n");
2458 /* loop the number of cards and get their info */
2461 nt = te = bri = pri = pots = 0;
2465 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2468 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2472 /* output the port info */
2473 printf("Port %2d name='%s': ", i, devinfo.name);
2474 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2479 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2484 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2489 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2495 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2502 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2508 if ((te || nt) && (bri || pri || pots))
2511 if (te && nt && bri)
2512 printf("TE/NT-mode BRI S/T (for phone lines & phones)");
2513 if (te && !nt && bri)
2514 printf("TE-mode BRI S/T (for phone lines)");
2515 if (nt && !te && bri)
2516 printf("NT-mode BRI S/T (for phones)");
2517 if (te && nt && pri)
2518 printf("TE/NT-mode PRI E1 (for phone lines & E1 devices)");
2519 if (te && !nt && pri)
2520 printf("TE-mode PRI E1 (for phone lines)");
2521 if (nt && !te && pri)
2522 printf("NT-mode PRI E1 (for E1 devices)");
2523 if (te && nt && pots)
2524 printf("FXS/FXO POTS (for analog lines & phones)");
2525 if (te && !nt && pots)
2526 printf("FXS POTS (for analog lines)");
2527 if (nt && !te && pots)
2528 printf("FXO POTS (for analog phones)");
2532 printf("\n -> Analog interfaces are not supported.");
2536 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
2540 printf(" - %d B-channels\n", devinfo.nrbchan);
2543 printf(" * Port NOT useable for LCR\n");
2545 printf("--------\n");
2557 * enque data from upper buffer
2559 void PmISDN::txfromup(unsigned char *data, int length)
2561 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2562 struct mISDNhead *hh = (struct mISDNhead *)buf;
2565 if (p_m_b_index < 0)
2567 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2570 /* check if high priority tones exist
2571 * ignore data in this case
2573 if (p_tone_name[0] || p_m_crypt_msg_loops)
2576 /* preload procedure
2577 * if transmit buffer in DSP module is empty,
2578 * preload it to DSP_LOAD to prevent jitter gaps.
2580 if (p_m_load==0 && ISDN_LOAD>0)
2582 hh->prim = PH_DATA_REQ;
2584 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2585 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2587 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
2588 p_m_load += ISDN_LOAD;
2591 /* drop if load would exceed ISDN_MAXLOAD
2592 * this keeps the delay not too high
2594 if (p_m_load+length > ISDN_MAXLOAD)
2597 /* make and send frame */
2598 hh->prim = PH_DATA_REQ;
2600 memcpy(buf+MISDN_HEADER_LEN, data, length);
2601 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2603 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);