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_join(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_join(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_join(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_join(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_join(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_join(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_join(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_join(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 /* find the port object for the join object ref */
1135 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1137 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1140 if (!epoint->ep_portlist)
1142 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1145 if (epoint->ep_portlist->next)
1147 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);
1149 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1151 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1154 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN)
1156 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1158 isdnport = (class PmISDN *)port;
1161 if (!isdnport->p_m_remote_id)
1163 PERROR("join %d recevied bchannel release from remote, but channel is already released.\n", joinremote->j_serial);
1166 mISDNport = isdnport->p_m_mISDNport;
1167 i = isdnport->p_m_b_index;
1168 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1169 add_trace("type", NULL, "export request");
1171 isdnport->p_m_remote_ref = 0;
1172 isdnport->p_m_remote_id = 0;
1173 if (mISDNport && i>=0)
1175 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1179 case BCHANNEL_ASSIGN_ACK:
1180 case BCHANNEL_REMOVE_ACK:
1181 /* find mISDNport for stack ID */
1182 mISDNport = mISDNport_first;
1186 ii = mISDNport->b_num;
1189 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1195 mISDNport = mISDNport->next;
1199 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1202 /* mISDNport may now be set or NULL */
1205 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1206 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1208 if (mISDNport && i>=0)
1209 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1212 PERROR("received wrong bchannel message type %d from remote\n", type);
1220 audio transmission procedure:
1221 -----------------------------
1224 three sources of audio transmission:
1225 - crypto-data high priority
1226 - tones high priority (also high)
1227 - remote-data low priority
1230 a variable that temporarily shows the number of samples elapsed since last transmission process.
1231 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1234 a variable that is increased whenever data is transmitted.
1235 it is decreased while time elapses. it stores the number of samples that
1236 are currently loaded to dsp module.
1237 since clock in dsp module is the same clock for user space process, these
1241 there are two levels:
1242 ISDN_LOAD will give the load that have to be kept in dsp.
1243 ISDN_MAXLOAD will give the maximum load before dropping.
1245 * procedure for low priority data
1246 see txfromup() for procedure
1247 in short: remote data is ignored during high priority tones
1249 * procedure for high priority data
1250 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1251 if no more data is available, load becomes empty again.
1254 0 ISDN_LOAD ISDN_MAXLOAD
1255 +--------------------+----------------------+
1257 +--------------------+----------------------+
1259 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1260 0 ISDN_LOAD ISDN_MAXLOAD
1261 +--------------------+----------------------+
1262 |TTTTTTTTTTTTTTTTTTTT| |
1263 +--------------------+----------------------+
1265 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1266 0 ISDN_LOAD ISDN_MAXLOAD
1267 +--------------------+----------------------+
1268 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1269 +--------------------+----------------------+
1272 int PmISDN::handler(void)
1274 struct lcr_msg *message;
1278 if ((ret = Port::handler()))
1282 if (p_m_last_tv_sec)
1284 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1285 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1288 /* set clock of first process ever in this instance */
1289 p_m_last_tv_sec = now_tv.tv_sec;
1290 p_m_last_tv_msec = now_tv.tv_usec/1000;
1292 /* process only if we have a minimum of samples, to make packets not too small */
1293 if (elapsed >= ISDN_TRANSMIT)
1295 /* set clock of last process! */
1296 p_m_last_tv_sec = now_tv.tv_sec;
1297 p_m_last_tv_msec = now_tv.tv_usec/1000;
1300 if (elapsed < p_m_load)
1301 p_m_load -= elapsed;
1305 /* to send data, tone must be active OR crypt messages must be on */
1306 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1307 && (p_m_load < ISDN_LOAD)
1308 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1310 int tosend = ISDN_LOAD - p_m_load, length;
1311 unsigned char buf[MISDN_HEADER_LEN+tosend];
1312 struct mISDNhead *frm = (struct mISDNhead *)buf;
1313 unsigned char *p = buf+MISDN_HEADER_LEN;
1315 /* copy crypto loops */
1316 while (p_m_crypt_msg_loops && tosend)
1318 /* how much do we have to send */
1319 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1322 if (length > tosend)
1325 /* copy message (part) to buffer */
1326 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1329 p_m_crypt_msg_current += length;
1330 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1333 p_m_crypt_msg_current = 0;
1334 p_m_crypt_msg_loops--;
1335 // puts("eine loop weniger");
1343 if (p_tone_name[0] && tosend)
1345 tosend -= read_audio(p, tosend);
1349 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && ISDN_LOAD-p_m_load-tosend > 0)
1351 frm->prim = PH_DATA_REQ;
1353 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1355 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);
1357 p_m_load += ISDN_LOAD - p_m_load - tosend;
1361 // NOTE: deletion is done by the child class
1363 /* handle timeouts */
1366 if (p_m_timer+p_m_timeout < now_d)
1368 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1370 /* send timeout to endpoint */
1371 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1372 message->param.state = p_state;
1373 message_put(message);
1378 return(0); /* nothing done */
1383 * whenever we get audio data from bchannel, we process it here
1385 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1387 unsigned long cont = *((unsigned long *)data);
1388 unsigned char *data_temp;
1389 unsigned long length_temp;
1390 struct lcr_msg *message;
1394 if (hh->prim == PH_CONTROL_IND)
1398 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1401 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1403 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1404 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1406 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1407 message->param.dtmf = cont & DTMF_TONE_MASK;
1408 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1409 message_put(message);
1415 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1416 add_trace("DSP-CRYPT", NULL, "error");
1418 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1419 message->param.crypt.type = CC_ERROR_IND;
1420 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1421 message_put(message);
1425 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1426 add_trace("DSP-CRYPT", NULL, "ok");
1428 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1429 message->param.crypt.type = CC_ACTBF_CONF;
1430 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1431 message_put(message);
1435 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1436 add_trace("unknown", NULL, "0x%x", cont);
1441 if (hh->prim == PH_CONTROL_IND)
1446 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1447 add_trace("unknown", NULL, "0x%x", hh->id);
1452 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ)
1456 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1457 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1460 /* see below (same condition) */
1461 if (p_state!=PORT_STATE_CONNECT
1462 && !p_m_mISDNport->tones)
1464 // printf(".");fflush(stdout);return;
1466 record(data, len, 1); // from up
1469 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1471 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1475 /* calls will not process any audio data unless
1476 * the call is connected OR tones feature is enabled.
1478 #ifndef DEBUG_COREBRIDGE
1479 if (p_state!=PORT_STATE_CONNECT
1480 && !p_m_mISDNport->tones)
1485 /* the bearer capability must be audio in order to send and receive
1486 * audio prior or after connect.
1488 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1492 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1495 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1501 record(data, len, 0); // from down
1503 /* randomize and listen to crypt message if enabled */
1504 if (p_m_crypt_listen)
1506 /* the noisy randomizer */
1510 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1512 cryptman_listen_bch(data, len);
1517 /* send data to epoint */
1518 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1524 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1525 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1526 memcpy(message->param.data.data, data_temp, message->param.data.len);
1527 message_put(message);
1528 if (length_temp <= sizeof(message->param.data.data))
1530 data_temp += sizeof(message->param.data.data);
1531 length_temp -= sizeof(message->param.data.data);
1540 void PmISDN::set_echotest(int echo)
1542 if (p_m_echo != echo)
1545 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1547 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1548 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);
1555 void PmISDN::set_tone(char *dir, char *tone)
1561 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1568 /* check if we NOT really have to use a dsp-tone */
1569 if (!options.dsptones)
1573 if (p_m_b_index > -1)
1574 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1576 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1577 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1580 Port::set_tone(dir, tone);
1586 /* now we USE dsp-tone, convert name */
1587 else if (!strcmp(tone, "dialtone"))
1589 switch(options.dsptones) {
1590 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1591 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1592 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1594 } else if (!strcmp(tone, "dialpbx"))
1596 switch(options.dsptones) {
1597 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1598 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1599 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1601 } else if (!strcmp(tone, "ringing"))
1603 switch(options.dsptones) {
1604 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1605 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1606 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1608 } else if (!strcmp(tone, "ringpbx"))
1610 switch(options.dsptones) {
1611 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1612 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1613 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1615 } else if (!strcmp(tone, "busy"))
1618 switch(options.dsptones) {
1619 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1620 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1621 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1623 } else if (!strcmp(tone, "release"))
1626 switch(options.dsptones) {
1627 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1628 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1629 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1631 } else if (!strcmp(tone, "cause_10"))
1633 else if (!strcmp(tone, "cause_11"))
1635 else if (!strcmp(tone, "cause_22"))
1637 switch(options.dsptones) {
1638 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1639 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1640 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1642 } else if (!strncmp(tone, "cause_", 6))
1643 id = TONE_SPECIAL_INFO;
1647 /* if we have a tone that is not supported by dsp */
1648 if (id==TONE_OFF && tone[0])
1656 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1657 if (p_m_b_index > -1)
1658 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1659 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);
1661 /* turn user-space tones off in cases of no tone OR dsp tone */
1662 Port::set_tone("",NULL);
1666 /* MESSAGE_mISDNSIGNAL */
1667 //extern struct lcr_msg *dddebug;
1668 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1670 switch(param->mISDNsignal.message)
1672 case mISDNSIGNAL_VOLUME:
1673 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1675 p_m_tx_gain = param->mISDNsignal.tx_gain;
1676 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1677 if (p_m_b_index > -1)
1678 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1679 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);
1681 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1682 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1684 p_m_rx_gain = param->mISDNsignal.rx_gain;
1685 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1686 if (p_m_b_index > -1)
1687 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1688 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);
1690 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1693 case mISDNSIGNAL_CONF:
1694 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1695 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1696 if (p_m_conf != param->mISDNsignal.conf)
1698 p_m_conf = param->mISDNsignal.conf;
1699 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1700 if (p_m_b_index > -1)
1701 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1702 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);
1704 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1705 /* we must set, even if currently tone forbids conf */
1706 p_m_conf = param->mISDNsignal.conf;
1707 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1710 case mISDNSIGNAL_JOINDATA:
1711 if (p_m_joindata != param->mISDNsignal.joindata)
1713 p_m_joindata = param->mISDNsignal.joindata;
1714 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1716 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1719 case mISDNSIGNAL_DELAY:
1720 if (p_m_delay != param->mISDNsignal.delay)
1722 p_m_delay = param->mISDNsignal.delay;
1723 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1724 if (p_m_b_index > -1)
1725 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1726 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);
1728 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1732 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1737 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1739 struct lcr_msg *message;
1741 switch(param->crypt.type)
1743 case CC_ACTBF_REQ: /* activate blowfish */
1745 p_m_crypt_key_len = param->crypt.len;
1746 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1748 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1749 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1750 message->param.crypt.type = CC_ERROR_IND;
1751 message_put(message);
1754 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1756 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1757 if (p_m_b_index > -1)
1758 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1759 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);
1762 case CC_DACT_REQ: /* deactivate session encryption */
1767 case CR_LISTEN_REQ: /* start listening to messages */
1768 p_m_crypt_listen = 1;
1769 p_m_crypt_listen_state = 0;
1772 case CR_UNLISTEN_REQ: /* stop listening to messages */
1773 p_m_crypt_listen = 0;
1776 case CR_MESSAGE_REQ: /* send message */
1777 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1778 if (!p_m_crypt_msg_len)
1780 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1783 p_m_crypt_msg_current = 0; /* reset */
1784 p_m_crypt_msg_loops = 6; /* enable */
1786 /* disable txmix, or we get corrupt data due to audio process */
1787 if (p_m_txmix && p_m_b_index>=0)
1789 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1790 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1796 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1802 * endpoint sends messages to the port
1804 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1806 if (Port::message_epoint(epoint_id, message_id, param))
1811 case MESSAGE_DATA: /* tx-data from upper layer */
1812 txfromup(param->data.data, param->data.len);
1815 case MESSAGE_mISDNSIGNAL: /* user command */
1816 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1817 message_mISDNsignal(epoint_id, message_id, param);
1820 case MESSAGE_CRYPT: /* crypt control command */
1821 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1822 message_crypt(epoint_id, message_id, param);
1831 * main loop for processing messages from mISDN
1833 int mISDN_handler(void)
1836 struct mISDNport *mISDNport;
1837 class PmISDN *isdnport;
1839 unsigned char buffer[2048+MISDN_HEADER_LEN];
1840 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1844 /* process all ports */
1845 mISDNport = mISDNport_first;
1848 /* process all bchannels */
1850 while(i < mISDNport->b_num)
1852 /* process timer events for bchannel handling */
1853 if (mISDNport->b_timer[i])
1855 if (mISDNport->b_timer[i] <= now_d)
1856 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
1858 /* handle port of bchannel */
1859 isdnport=mISDNport->b_port[i];
1862 /* call bridges in user space OR crypto OR recording */
1863 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1865 /* rx IS required */
1866 if (isdnport->p_m_rxoff)
1869 isdnport->p_m_rxoff = 0;
1870 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1871 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1872 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1877 /* rx NOT required */
1878 if (!isdnport->p_m_rxoff)
1881 isdnport->p_m_rxoff = 1;
1882 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1883 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1884 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1889 if (isdnport->p_record)
1891 /* txdata IS required */
1892 if (!isdnport->p_m_txdata)
1895 isdnport->p_m_txdata = 1;
1896 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1897 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1898 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1903 /* txdata NOT required */
1904 if (isdnport->p_m_txdata)
1907 isdnport->p_m_txdata = 0;
1908 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1909 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1910 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1916 /* handle message from bchannel */
1917 if (mISDNport->b_socket[i] > -1)
1919 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
1920 if (ret >= (int)MISDN_HEADER_LEN)
1925 /* we don't care about confirms, we use rx data to sync tx */
1929 /* we receive audio data, we respond to it AND we send tones */
1934 case PH_CONTROL_IND:
1935 if (mISDNport->b_port[i])
1936 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1938 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
1941 case PH_ACTIVATE_IND:
1942 case DL_ESTABLISH_IND:
1943 case PH_ACTIVATE_CNF:
1944 case DL_ESTABLISH_CNF:
1945 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
1946 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1949 case PH_DEACTIVATE_IND:
1950 case DL_RELEASE_IND:
1951 case PH_DEACTIVATE_CNF:
1952 case DL_RELEASE_CNF:
1953 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
1954 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1958 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
1962 if (ret < 0 && errno != EWOULDBLOCK)
1963 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
1970 /* handle queued up-messages (d-channel) */
1971 while ((mb = mdequeue(&mISDNport->upqueue)))
1976 case MPH_ACTIVATE_IND:
1977 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1979 mISDNport->l1link = 1;
1982 case MPH_DEACTIVATE_IND:
1983 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1985 mISDNport->l1link = 0;
1988 case MPH_INFORMATION_IND:
1989 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1992 case L1_SIGNAL_LOS_ON:
1995 case L1_SIGNAL_LOS_OFF:
1998 case L1_SIGNAL_AIS_ON:
2001 case L1_SIGNAL_AIS_OFF:
2004 case L1_SIGNAL_RDI_ON:
2007 case L1_SIGNAL_RDI_OFF:
2010 case L1_SIGNAL_SLIP_TX:
2011 mISDNport->slip_tx++;
2013 case L1_SIGNAL_SLIP_RX:
2014 mISDNport->slip_rx++;
2019 case MT_L2ESTABLISH:
2020 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
2021 add_trace("tei", NULL, "%d", l3m->pid);
2023 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2025 if (mISDNport->l2establish)
2027 mISDNport->l2establish = 0;
2028 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2030 mISDNport->l2link = 1;
2035 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2036 add_trace("tei", NULL, "%d", l3m->pid);
2038 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2040 mISDNport->l2link = 0;
2041 if (mISDNport->l2hold)
2043 time(&mISDNport->l2establish);
2044 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2050 /* l3-data is sent to LCR */
2051 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
2058 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2060 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2061 mISDNport->l1timeout = 0;
2064 /* layer 2 establish timer */
2065 if (mISDNport->l2establish)
2067 if (now-mISDNport->l2establish > 5)
2069 mISDNport->l2establish = 0;
2070 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2073 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2074 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2075 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2076 add_trace("tei", NULL, "%d", 0);
2078 time(&mISDNport->l2establish);
2085 mISDNport = mISDNport->next;
2088 /* if we received at least one b-frame, we will return 1 */
2092 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2096 * l3m must be queued, except for MT_ASSIGN
2099 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2102 /* special MT_ASSIGN handling:
2104 * if we request a PID from mlayer, we always do it while lcr is locked.
2105 * therefore we must check the MT_ASSIGN reply first before we lock.
2106 * this is because the MT_ASSIGN reply is received with the requesting
2107 * process, not by the mlayer thread!
2108 * this means, that the reply is sent during call of the request.
2109 * we must check if we get a reply and we know that we lcr is currently
2112 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER)
2114 /* let's do some checking if someone changes stack behaviour */
2115 if (mt_assign_pid != 0)
2116 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2117 mt_assign_pid = pid;
2121 /* queue message, create, if required */
2124 l3m = alloc_l3_msg();
2126 FATAL("No memory for layer 3 message\n");
2128 mb = container_of(l3m, struct mbuffer, l3);
2131 mqueue_tail(&mISDNport->upqueue, mb);
2137 * global function to add a new card (port)
2139 struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, struct interface *interface)
2142 struct mISDNport *mISDNport, **mISDNportp;
2146 // struct mlayer3 *ml3;
2147 struct mISDN_devinfo devinfo;
2148 unsigned int protocol, prop;
2150 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2153 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2159 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2162 if (port>cnt || port<1)
2164 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2168 pri = bri = pots = nt = te = 0;
2169 devinfo.id = port - 1;
2170 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2173 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2176 /* output the port info */
2177 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2182 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2187 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2192 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2198 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2205 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2211 if (force_nt && !nt)
2213 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2218 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2221 if (pots && !bri && !pri)
2223 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2228 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2233 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2236 /* set NT by turning off TE */
2239 /* if TE an NT is supported (and not forced to NT), turn off NT */
2243 /* add mISDNport structure */
2244 mISDNportp = &mISDNport_first;
2246 mISDNportp = &((*mISDNportp)->next);
2247 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2249 *mISDNportp = mISDNport;
2251 /* if pri, must set PTP */
2272 /* allocate ressources of port */
2273 /* open layer 3 and init upqueue */
2274 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2275 prop = (1 << MISDN_FLG_L2_CLEAN);
2276 if (ptp) // ptp forced
2277 prop |= (1 << MISDN_FLG_PTP);
2278 if (nt) // supports hold/retrieve on nt-mode
2279 prop |= (1 << MISDN_FLG_NET_HOLD);
2280 if (l2hold) // supports layer 2 hold
2281 prop |= (1 << MISDN_FLG_L2_HOLD);
2282 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2283 mqueue_init(&mISDNport->upqueue);
2284 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_layer3, mISDNport);
2285 if (!mISDNport->ml3)
2287 mqueue_purge(&mISDNport->upqueue);
2288 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2296 "PORT (open failed)");
2298 mISDNport_close(mISDNport);
2303 /* if ntmode, establish L1 to send the tei removal during start */
2304 if (mISDNport->ntmode)
2308 act.prim = PH_ACTIVATE | REQUEST;
2309 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2310 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2313 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2314 usleep(10000); /* to be sure, that l1 is up */
2318 SCPY(mISDNport->name, devinfo.name);
2319 mISDNport->b_num = devinfo.nrbchan;
2320 mISDNport->portnum = port;
2321 mISDNport->ntmode = nt;
2322 mISDNport->pri = pri;
2323 mISDNport->ptp = ptp;
2324 mISDNport->l2hold = l2hold;
2325 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2327 while(i < mISDNport->b_num)
2329 mISDNport->b_state[i] = B_STATE_IDLE;
2330 mISDNport->b_socket[i] = -1;
2334 /* if ptp, pull up the link */
2335 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2337 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2338 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2339 add_trace("tei", NULL, "%d", 0);
2341 time(&mISDNport->l2establish);
2344 /* initially, we assume that the link is down, exept for nt-ptmp */
2345 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2347 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2349 start_trace(mISDNport->portnum,
2357 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2358 add_trace("channels", NULL, "%d", mISDNport->b_num);
2365 * function to free ALL cards (ports)
2367 void mISDNport_close_all(void)
2369 /* free all ports */
2370 while(mISDNport_first)
2371 mISDNport_close(mISDNport_first);
2375 * free only one port
2377 void mISDNport_close(struct mISDNport *mISDNport)
2379 struct mISDNport **mISDNportp;
2381 class PmISDN *isdnport;
2384 /* remove all port instance that are linked to this mISDNport */
2388 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2390 isdnport = (class PmISDN *)port;
2391 if (isdnport->p_m_mISDNport)
2393 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2400 /* only if we are already part of interface */
2401 if (mISDNport->ifport)
2403 start_trace(mISDNport->portnum,
2404 mISDNport->ifport->interface,
2414 /* free bchannels */
2416 while(i < mISDNport->b_num)
2418 if (mISDNport->b_socket[i] > -1)
2420 _bchannel_destroy(mISDNport, i);
2421 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2426 /* close layer 3, if open and purge upqueue */
2429 close_layer3(mISDNport->ml3);
2430 mqueue_purge(&mISDNport->upqueue);
2433 /* remove from list */
2434 mISDNportp = &mISDNport_first;
2437 if (*mISDNportp == mISDNport)
2439 *mISDNportp = (*mISDNportp)->next;
2443 mISDNportp = &((*mISDNportp)->next);
2447 FATAL("mISDNport not in list\n");
2449 FREE(mISDNport, sizeof(struct mISDNport));
2456 * global function to show all available isdn ports
2458 void mISDN_port_info(void)
2462 int useable, nt, te, pri, bri, pots;
2463 struct mISDN_devinfo devinfo;
2467 sock = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
2470 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
2474 /* get number of stacks */
2476 ret = ioctl(sock, IMGETCOUNT, &ii);
2479 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2485 printf("Found no card. Please be sure to load card drivers.\n");
2489 /* loop the number of cards and get their info */
2492 nt = te = bri = pri = pots = 0;
2496 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2499 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2503 /* output the port info */
2504 printf("Port %2d name='%s': ", i, devinfo.name);
2505 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2510 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2515 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2520 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2526 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2533 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2539 if ((te || nt) && (bri || pri || pots))
2542 if (te && nt && bri)
2543 printf("TE/NT-mode BRI S/T (for phone lines & phones)");
2544 if (te && !nt && bri)
2545 printf("TE-mode BRI S/T (for phone lines)");
2546 if (nt && !te && bri)
2547 printf("NT-mode BRI S/T (for phones)");
2548 if (te && nt && pri)
2549 printf("TE/NT-mode PRI E1 (for phone lines & E1 devices)");
2550 if (te && !nt && pri)
2551 printf("TE-mode PRI E1 (for phone lines)");
2552 if (nt && !te && pri)
2553 printf("NT-mode PRI E1 (for E1 devices)");
2554 if (te && nt && pots)
2555 printf("FXS/FXO POTS (for analog lines & phones)");
2556 if (te && !nt && pots)
2557 printf("FXS POTS (for analog lines)");
2558 if (nt && !te && pots)
2559 printf("FXO POTS (for analog phones)");
2563 printf("\n -> Analog interfaces are not supported.");
2567 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
2571 printf(" - %d B-channels\n", devinfo.nrbchan);
2574 printf(" * Port NOT useable for LCR\n");
2576 printf("--------\n");
2588 * enque data from upper buffer
2590 void PmISDN::txfromup(unsigned char *data, int length)
2592 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2593 struct mISDNhead *hh = (struct mISDNhead *)buf;
2596 if (p_m_b_index < 0)
2598 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2601 /* check if high priority tones exist
2602 * ignore data in this case
2604 if (p_tone_name[0] || p_m_crypt_msg_loops)
2607 /* preload procedure
2608 * if transmit buffer in DSP module is empty,
2609 * preload it to DSP_LOAD to prevent jitter gaps.
2611 if (p_m_load==0 && ISDN_LOAD>0)
2613 hh->prim = PH_DATA_REQ;
2615 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2616 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2618 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
2619 p_m_load += ISDN_LOAD;
2622 /* drop if load would exceed ISDN_MAXLOAD
2623 * this keeps the delay not too high
2625 if (p_m_load+length > ISDN_MAXLOAD)
2628 /* make and send frame */
2629 hh->prim = PH_DATA_REQ;
2631 memcpy(buf+MISDN_HEADER_LEN, data, length);
2632 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2634 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);