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 int 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, int mode) : Port(type, portname, settings)
96 p_m_mISDNport = mISDNport;
97 p_m_portnum = mISDNport->portnum;
105 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
106 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
114 p_m_dtmf = !mISDNport->ifport->nodtmf;
117 p_m_remote_ref = 0; /* channel shall be exported to given remote */
118 p_m_remote_id = 0; /* remote admin socket */
119 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
127 p_m_crypt_listen = 0;
128 p_m_crypt_msg_loops = 0;
129 p_m_crypt_msg_loops = 0;
130 p_m_crypt_msg_len = 0;
131 p_m_crypt_msg[0] = '\0';
132 p_m_crypt_msg_current = 0;
133 p_m_crypt_key_len = 0;
134 p_m_crypt_listen = 0;
135 p_m_crypt_listen_state = 0;
136 p_m_crypt_listen_len = 0;
137 p_m_crypt_listen_msg[0] = '\0';
138 p_m_crypt_listen_crc = 0;
139 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56)
141 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
142 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
146 /* if any channel requested by constructor */
147 if (channel == CHANNEL_ANY)
149 /* reserve channel */
151 mISDNport->b_reserved++;
154 /* reserve channel */
155 if (channel > 0) // only if constructor was called with a channel resevation
156 seize_bchannel(channel, exclusive);
158 /* we increase the number of objects: */
160 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
169 struct lcr_msg *message;
171 /* remove bchannel relation */
177 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
178 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
179 message->param.disconnectinfo.cause = 16;
180 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
181 message_put(message);
182 /* remove from list */
183 free_epointlist(p_epointlist);
186 /* we decrease the number of objects: */
187 p_m_mISDNport->use--;
188 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
195 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
197 /* init trace with given values */
198 start_trace(mISDNport?mISDNport->portnum:0,
199 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
200 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
201 port?port->p_dialinginfo.id:NULL,
204 port?port->p_serial:0,
212 static struct isdn_message {
216 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
217 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
218 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
219 {"DL_RELEASE", L2_RELEASE_REQ},
220 {"UNKNOWN", L3_UNKNOWN},
221 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
222 {"MT_SETUP", L3_SETUP_REQ},
223 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
224 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
225 {"MT_ALERTING", L3_ALERTING_REQ},
226 {"MT_CONNECT", L3_CONNECT_REQ},
227 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
228 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
229 {"MT_RELEASE", L3_RELEASE_REQ},
230 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
231 {"MT_INFORMATION", L3_INFORMATION_REQ},
232 {"MT_PROGRESS", L3_PROGRESS_REQ},
233 {"MT_NOTIFY", L3_NOTIFY_REQ},
234 {"MT_SUSPEND", L3_SUSPEND_REQ},
235 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
236 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
237 {"MT_RESUME", L3_RESUME_REQ},
238 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
239 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
240 {"MT_HOLD", L3_HOLD_REQ},
241 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
242 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
243 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
244 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
245 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
246 {"MT_FACILITY", L3_FACILITY_REQ},
247 {"MT_STATUS", L3_STATUS_REQ},
248 {"MT_RESTART", L3_RESTART_REQ},
249 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
250 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
253 static char *isdn_prim[4] = {
259 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
262 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
264 /* select message and primitive text */
266 while(isdn_message[i].name)
268 if (isdn_message[i].value == (msg&0xffffff00))
270 SCPY(msgtext, isdn_message[i].name);
275 SCAT(msgtext, isdn_prim[msg&0x00000003]);
278 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ)
282 if (mISDNport->ntmode)
284 if (direction == DIRECTION_OUT)
285 SCAT(msgtext, " N->U");
287 SCAT(msgtext, " N<-U");
290 if (direction == DIRECTION_OUT)
291 SCAT(msgtext, " U->N");
293 SCAT(msgtext, " U<-N");
298 /* init trace with given values */
299 start_trace(mISDNport?mISDNport->portnum:0,
300 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
301 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
302 port?port->p_dialinginfo.id:NULL,
305 port?port->p_serial:0,
311 * send control information to the channel (dsp-module)
313 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, char *trace_name, int trace_value)
315 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
316 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
317 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
323 ctrl->prim = PH_CONTROL_REQ;
327 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
329 PERROR("Failed to send to socket %d\n", sock);
330 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
331 if (c1 == DSP_CONF_JOIN)
332 add_trace(trace_name, NULL, "0x%08x", trace_value);
334 add_trace(trace_name, NULL, "%d", trace_value);
338 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, void *c2, int c2_len, char *trace_name, int trace_value)
340 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
341 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
342 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
348 ctrl->prim = PH_CONTROL_REQ;
351 memcpy(d, c2, c2_len);
352 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
354 PERROR("Failed to send to socket %d\n", sock);
355 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
356 add_trace(trace_name, NULL, "%d", trace_value);
362 * subfunction for bchannel_event
365 static int _bchannel_create(struct mISDNport *mISDNport, int i)
369 struct sockaddr_mISDN addr;
371 if (mISDNport->b_socket[i] > -1)
373 PERROR("Error: Socket already created for index %d\n", i);
378 //#warning testing without DSP
379 // mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_HDLC:ISDN_P_B_RAW);
380 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_L2DSPHDLC:ISDN_P_B_L2DSP);
381 if (mISDNport->b_socket[i] < 0)
383 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
387 /* set nonblocking io */
388 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
391 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
392 close(mISDNport->b_socket[i]);
393 mISDNport->b_socket[i] = -1;
397 /* bind socket to bchannel */
398 addr.family = AF_ISDN;
399 addr.dev = mISDNport->portnum-1;
400 addr.channel = i+1+(i>=15);
401 ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr));
404 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
405 close(mISDNport->b_socket[i]);
406 mISDNport->b_socket[i] = -1;
410 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
411 add_trace("channel", NULL, "%d", i+1+(i>=15));
412 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
420 * subfunction for bchannel_event
421 * activate / deactivate request
423 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
425 struct mISDNhead act;
428 if (mISDNport->b_socket[i] < 0)
430 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
432 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
434 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
437 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
438 add_trace("channel", NULL, "%d", i+1+(i>=15));
439 if (mISDNport->b_timer[i])
440 add_trace("event", NULL, "timeout recovery");
446 * subfunction for bchannel_event
449 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
454 if (mISDNport->b_socket[i] < 0)
456 handle = mISDNport->b_socket[i];
457 port = mISDNport->b_port[i];
458 mode = mISDNport->b_mode[i];
461 PERROR("bchannel index i=%d not associated with a port object\n", i);
465 /* set dsp features */
466 if (port->p_m_txdata)
467 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
468 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
469 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
470 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
471 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
472 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
473 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
474 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
475 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
477 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
479 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
480 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
481 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
483 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
484 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
485 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
486 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
487 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
488 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
489 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);
493 * subfunction for bchannel_event
496 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
498 if (mISDNport->b_socket[i] < 0)
500 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
501 add_trace("channel", NULL, "%d", i+1+(i>=15));
502 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
504 close(mISDNport->b_socket[i]);
505 mISDNport->b_socket[i] = -1;
513 A bchannel goes through the following states in this order:
516 No one is using the bchannel.
517 It is available and not linked to Port class, nor reserved.
520 The bchannel stack is created and an activation request is sent.
521 It MAY be linked to Port class, but already unlinked due to Port class removal.
524 The bchannel is active and cofigured to the Port class needs.
525 Also it is linked to a Port class, otherwhise it would be deactivated.
527 - B_STATE_DEACTIVATING
528 The bchannel is in deactivating state, due to deactivation request.
529 It may be linked to a Port class, that likes to reactivate it.
533 After deactivating bchannel, and if not used, the bchannel becomes idle again.
535 Also the bchannel may be exported, but only if the state is or becomes idle:
538 The bchannel assignment has been sent to the remove application.
541 The bchannel assignment is acknowledged by the remote application.
544 The bchannel is re-imported by mISDN port object.
548 After re-importing bchannel, and if not used, the bchannel becomes idle again.
551 A bchannel can have the following events:
554 A bchannel is required by a Port class.
557 The bchannel beomes active.
560 The bchannel is not required by Port class anymore
562 - B_EVENT_DEACTIVATED
563 The bchannel becomes inactive.
566 The bchannel is now used by remote application.
569 The bchannel is not used by remote application.
571 - B_EVENT_EXPORTREQUEST
572 The bchannel shall be exported to the remote application.
574 - B_EVENT_IMPORTREQUEST
575 The bchannel is released from the remote application.
577 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
579 if an export request is receive by remote application, p_m_remote_* is set.
580 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.)
581 - set on export request from remote application (if port is assigned)
582 - set on channel use, if requested by remote application (p_m_remote_*)
583 - cleared on drop request
585 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
586 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
587 the bchannel import/export is acknowledged with stack given.
589 if exporting, b_remote_*[index] is set to the remote socket id.
590 if importing has been acknowledged. b_remote_*[index] is cleared.
595 * process bchannel events
596 * - mISDNport is a pointer to the port's structure
597 * - i is the index of the bchannel
598 * - event is the B_EVENT_* value
599 * - port is the PmISDN class pointer
601 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
603 class PmISDN *b_port = mISDNport->b_port[i];
604 int state = mISDNport->b_state[i];
605 double timer = mISDNport->b_timer[i];
606 unsigned int p_m_remote_ref = 0;
607 unsigned int p_m_remote_id = 0;
610 char *p_m_pipeline = NULL;
611 unsigned char *p_m_crypt_key = NULL;
612 int p_m_crypt_key_len = 0;
613 int p_m_crypt_key_type = 0;
614 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
618 p_m_remote_id = b_port->p_m_remote_id;
619 p_m_remote_ref = b_port->p_m_remote_ref;
620 p_m_tx_gain = b_port->p_m_tx_gain;
621 p_m_rx_gain = b_port->p_m_rx_gain;
622 p_m_pipeline = b_port->p_m_pipeline;
623 p_m_crypt_key = b_port->p_m_crypt_key;
624 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
625 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
631 /* port must be linked in order to allow activation */
633 FATAL("bchannel must be linked to a Port class\n");
639 /* export bchannel */
640 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);
641 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
642 add_trace("type", NULL, "assign");
643 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
645 state = B_STATE_EXPORTING;
646 mISDNport->b_remote_id[i] = p_m_remote_id;
647 mISDNport->b_remote_ref[i] = p_m_remote_ref;
650 /* create stack and send activation request */
651 if (_bchannel_create(mISDNport, i))
653 _bchannel_activate(mISDNport, i, 1);
654 state = B_STATE_ACTIVATING;
655 timer = now_d + B_TIMER_ACTIVATING;
660 case B_STATE_ACTIVATING:
661 case B_STATE_EXPORTING:
662 /* do nothing, because it is already activating */
665 case B_STATE_DEACTIVATING:
666 case B_STATE_IMPORTING:
667 /* do nothing, because we must wait until we can reactivate */
671 /* problems that might ocurr:
672 * B_EVENT_USE is received when channel already in use.
673 * bchannel exported, but not freed by other port
675 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
679 case B_EVENT_EXPORTREQUEST:
680 /* special case where the bchannel is requested by remote */
683 PERROR("export request without remote channel set, please correct.\n");
689 /* in case, the bchannel is exported right after seize_bchannel */
690 /* export bchannel */
691 /* p_m_remote_id is set, when this event happens. */
692 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);
693 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
694 add_trace("type", NULL, "assign");
695 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
697 state = B_STATE_EXPORTING;
698 mISDNport->b_remote_id[i] = p_m_remote_id;
699 mISDNport->b_remote_ref[i] = p_m_remote_ref;
702 case B_STATE_ACTIVATING:
703 case B_STATE_EXPORTING:
704 /* do nothing, because it is already activating */
707 case B_STATE_DEACTIVATING:
708 case B_STATE_IMPORTING:
709 /* do nothing, because we must wait until we can reactivate */
713 /* bchannel is active, so we deactivate */
714 _bchannel_activate(mISDNport, i, 0);
715 state = B_STATE_DEACTIVATING;
716 timer = now_d + B_TIMER_DEACTIVATING;
720 /* problems that might ocurr:
721 * ... when channel already in use.
722 * bchannel exported, but not freed by other port
724 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
728 case B_EVENT_IMPORTREQUEST:
729 /* special case where the bchannel is released by remote */
732 PERROR("import request with remote channel set, please correct.\n");
739 /* bchannel is not exported */
742 case B_STATE_ACTIVATING:
743 case B_STATE_EXPORTING:
744 /* do nothing because we must wait until bchanenl is active before deactivating */
748 /* bchannel is exported, so we re-import */
749 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
750 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
751 add_trace("type", NULL, "remove");
752 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
754 state = B_STATE_IMPORTING;
757 case B_STATE_DEACTIVATING:
758 case B_STATE_IMPORTING:
759 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
763 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
767 case B_EVENT_ACTIVATED:
771 case B_STATE_ACTIVATING:
772 if (b_port && !p_m_remote_id)
774 /* bchannel is active and used by Port class, so we configure bchannel */
775 _bchannel_configure(mISDNport, i);
776 state = B_STATE_ACTIVE;
777 b_port->p_m_load = 0;
780 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
781 _bchannel_activate(mISDNport, i, 0);
782 state = B_STATE_DEACTIVATING;
783 timer = now_d + B_TIMER_DEACTIVATING;
788 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
792 case B_EVENT_EXPORTED:
795 case B_STATE_EXPORTING:
796 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
798 /* remote export done */
799 state = B_STATE_REMOTE;
802 /* bchannel is now exported, but we need bchannel back
803 * OR bchannel is not used anymore
804 * OR bchannel has been exported to an obsolete ref,
805 * so reimport, to later export to new remote */
806 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
807 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
808 add_trace("type", NULL, "remove");
809 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
811 state = B_STATE_IMPORTING;
816 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
822 FATAL("bchannel must be linked to a Port class\n");
826 /* bchannel is idle due to an error, so we do nothing */
829 case B_STATE_ACTIVATING:
830 case B_STATE_EXPORTING:
831 /* do nothing because we must wait until bchanenl is active before deactivating */
835 /* bchannel is active, so we deactivate */
836 _bchannel_activate(mISDNport, i, 0);
837 state = B_STATE_DEACTIVATING;
838 timer = now_d + B_TIMER_DEACTIVATING;
842 /* bchannel is exported, so we re-import */
843 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
844 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
845 add_trace("type", NULL, "remove");
846 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
848 state = B_STATE_IMPORTING;
851 case B_STATE_DEACTIVATING:
852 case B_STATE_IMPORTING:
853 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
857 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
861 case B_EVENT_DEACTIVATED:
866 /* ignore due to deactivation confirm after unloading */
869 case B_STATE_DEACTIVATING:
870 _bchannel_destroy(mISDNport, i);
871 state = B_STATE_IDLE;
874 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
877 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);
878 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
879 add_trace("type", NULL, "assign");
880 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
882 state = B_STATE_EXPORTING;
883 mISDNport->b_remote_id[i] = p_m_remote_id;
884 mISDNport->b_remote_ref[i] = p_m_remote_ref;
887 if (_bchannel_create(mISDNport, i))
889 _bchannel_activate(mISDNport, i, 1);
890 state = B_STATE_ACTIVATING;
891 timer = now_d + B_TIMER_ACTIVATING;
898 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
902 case B_EVENT_IMPORTED:
905 case B_STATE_IMPORTING:
906 state = B_STATE_IDLE;
907 mISDNport->b_remote_id[i] = 0;
908 mISDNport->b_remote_ref[i] = 0;
911 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
914 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);
915 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
916 add_trace("type", NULL, "assign");
917 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
919 state = B_STATE_EXPORTING;
920 mISDNport->b_remote_id[i] = p_m_remote_id;
921 mISDNport->b_remote_ref[i] = p_m_remote_ref;
924 if (_bchannel_create(mISDNport, i))
926 _bchannel_activate(mISDNport, i, 1);
927 state = B_STATE_ACTIVATING;
928 timer = now_d + B_TIMER_ACTIVATING;
935 /* ignore, because not assigned */
940 case B_EVENT_TIMEOUT:
945 /* ignore due to deactivation confirm after unloading */
948 case B_STATE_ACTIVATING:
949 _bchannel_activate(mISDNport, i, 1);
950 timer = now_d + B_TIMER_ACTIVATING;
953 case B_STATE_DEACTIVATING:
954 _bchannel_activate(mISDNport, i, 0);
955 timer = now_d + B_TIMER_DEACTIVATING;
959 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
964 PERROR("Illegal event %d, please correct.\n", event);
967 mISDNport->b_state[i] = state;
968 mISDNport->b_timer[i] = timer;
975 * check for available channel and reserve+set it.
976 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
978 * returns -(cause value) or x = channel x or 0 = no channel
979 * NOTE: no activation is done here
981 int PmISDN::seize_bchannel(int channel, int exclusive)
985 /* the channel is what we have */
986 if (p_m_b_channel == channel)
989 /* if channel already in use, release it */
994 if (channel==CHANNEL_NO || channel==0)
997 /* is channel in range ? */
999 || (channel>p_m_mISDNport->b_num && channel<16)
1000 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1001 return(-6); /* channel unacceptable */
1003 /* request exclusive channel */
1004 if (exclusive && channel>0)
1006 i = channel-1-(channel>16);
1007 if (p_m_mISDNport->b_port[i])
1008 return(-44); /* requested channel not available */
1012 /* ask for channel */
1015 i = channel-1-(channel>16);
1016 if (p_m_mISDNport->b_port[i] == NULL)
1020 /* search for channel */
1022 while(i < p_m_mISDNport->b_num)
1024 if (!p_m_mISDNport->b_port[i])
1026 channel = i+1+(i>=15);
1031 return(-34); /* no free channel */
1034 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1036 /* link Port, set parameters */
1037 p_m_mISDNport->b_port[i] = this;
1039 p_m_b_channel = channel;
1040 p_m_b_exclusive = exclusive;
1041 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1043 /* reserve channel */
1047 p_m_mISDNport->b_reserved++;
1054 * drop reserved channel and unset it.
1055 * deactivation is also done
1057 void PmISDN::drop_bchannel(void)
1059 /* unreserve channel */
1061 p_m_mISDNport->b_reserved--;
1065 if (p_m_b_index < 0)
1070 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1072 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1073 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1074 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1075 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1078 p_m_b_exclusive = 0;
1081 /* process bchannel export/import message from join */
1082 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1084 class Endpoint *epoint;
1086 class PmISDN *isdnport;
1087 struct mISDNport *mISDNport;
1092 case BCHANNEL_REQUEST:
1093 /* find the port object for the join object ref */
1094 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1096 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1099 if (!epoint->ep_portlist)
1101 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1104 if (epoint->ep_portlist->next)
1106 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);
1108 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1110 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1113 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN)
1115 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1117 isdnport = (class PmISDN *)port;
1120 if (isdnport->p_m_remote_id)
1122 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1125 mISDNport = isdnport->p_m_mISDNport;
1126 i = isdnport->p_m_b_index;
1127 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1128 add_trace("type", NULL, "export request");
1130 isdnport->p_m_remote_ref = joinremote->j_serial;
1131 isdnport->p_m_remote_id = joinremote->j_remote_id;
1132 if (mISDNport && i>=0)
1134 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1138 case BCHANNEL_RELEASE:
1139 case BCHANNEL_ASSIGN_ACK:
1140 case BCHANNEL_REMOVE_ACK:
1141 /* find mISDNport for stack ID */
1142 mISDNport = mISDNport_first;
1146 ii = mISDNport->b_num;
1149 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1155 mISDNport = mISDNport->next;
1159 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1163 if (type!=BCHANNEL_RELEASE)
1166 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1167 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1169 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1173 isdnport = mISDNport->b_port[i];
1174 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1175 add_trace("type", NULL, "import request");
1179 isdnport->p_m_remote_ref = 0;
1180 isdnport->p_m_remote_id = 0;
1182 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1186 PERROR("received wrong bchannel message type %d from remote\n", type);
1194 audio transmission procedure:
1195 -----------------------------
1198 three sources of audio transmission:
1199 - crypto-data high priority
1200 - tones high priority (also high)
1201 - remote-data low priority
1204 a variable that temporarily shows the number of samples elapsed since last transmission process.
1205 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1208 a variable that is increased whenever data is transmitted.
1209 it is decreased while time elapses. it stores the number of samples that
1210 are currently loaded to dsp module.
1211 since clock in dsp module is the same clock for user space process, these
1215 there are two levels:
1216 ISDN_LOAD will give the load that have to be kept in dsp.
1217 ISDN_MAXLOAD will give the maximum load before dropping.
1219 * procedure for low priority data
1220 see txfromup() for procedure
1221 in short: remote data is ignored during high priority tones
1223 * procedure for high priority data
1224 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1225 if no more data is available, load becomes empty again.
1228 0 ISDN_LOAD ISDN_MAXLOAD
1229 +--------------------+----------------------+
1231 +--------------------+----------------------+
1233 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1234 0 ISDN_LOAD ISDN_MAXLOAD
1235 +--------------------+----------------------+
1236 |TTTTTTTTTTTTTTTTTTTT| |
1237 +--------------------+----------------------+
1239 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1240 0 ISDN_LOAD ISDN_MAXLOAD
1241 +--------------------+----------------------+
1242 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1243 +--------------------+----------------------+
1246 int PmISDN::handler(void)
1248 struct lcr_msg *message;
1252 if ((ret = Port::handler()))
1256 if (p_m_last_tv_sec)
1258 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1259 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1262 /* set clock of first process ever in this instance */
1263 p_m_last_tv_sec = now_tv.tv_sec;
1264 p_m_last_tv_msec = now_tv.tv_usec/1000;
1266 /* process only if we have a minimum of samples, to make packets not too small */
1267 if (elapsed >= ISDN_TRANSMIT
1268 && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1270 /* set clock of last process! */
1271 p_m_last_tv_sec = now_tv.tv_sec;
1272 p_m_last_tv_msec = now_tv.tv_usec/1000;
1275 if (elapsed < p_m_load)
1276 p_m_load -= elapsed;
1280 /* to send data, tone must be active OR crypt messages must be on */
1281 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1282 && (p_m_load < ISDN_LOAD)
1283 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1285 int tosend = ISDN_LOAD - p_m_load, length;
1286 unsigned char buf[MISDN_HEADER_LEN+tosend];
1287 struct mISDNhead *frm = (struct mISDNhead *)buf;
1288 unsigned char *p = buf+MISDN_HEADER_LEN;
1290 /* copy crypto loops */
1291 while (p_m_crypt_msg_loops && tosend)
1293 /* how much do we have to send */
1294 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1297 if (length > tosend)
1300 /* copy message (part) to buffer */
1301 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1304 p_m_crypt_msg_current += length;
1305 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1308 p_m_crypt_msg_current = 0;
1309 p_m_crypt_msg_loops--;
1310 // puts("eine loop weniger");
1318 if (p_tone_name[0] && tosend)
1320 tosend -= read_audio(p, tosend);
1324 if (ISDN_LOAD - p_m_load - tosend > 0)
1326 frm->prim = PH_DATA_REQ;
1328 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1330 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);
1331 p_m_load += ISDN_LOAD - p_m_load - tosend;
1336 // NOTE: deletion is done by the child class
1338 /* handle timeouts */
1341 if (p_m_timer+p_m_timeout < now_d)
1343 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1345 /* send timeout to endpoint */
1346 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1347 message->param.state = p_state;
1348 message_put(message);
1353 return(0); /* nothing done */
1358 * whenever we get audio data from bchannel, we process it here
1360 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1362 unsigned int cont = *((unsigned int *)data);
1363 unsigned char *data_temp;
1364 unsigned int length_temp;
1365 struct lcr_msg *message;
1369 if (hh->prim == PH_CONTROL_IND)
1373 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1376 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1378 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1379 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1381 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1382 message->param.dtmf = cont & DTMF_TONE_MASK;
1383 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1384 message_put(message);
1390 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1391 add_trace("DSP-CRYPT", NULL, "error");
1393 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1394 message->param.crypt.type = CC_ERROR_IND;
1395 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1396 message_put(message);
1400 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1401 add_trace("DSP-CRYPT", NULL, "ok");
1403 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1404 message->param.crypt.type = CC_ACTBF_CONF;
1405 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1406 message_put(message);
1410 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1411 add_trace("unknown", NULL, "0x%x", cont);
1416 if (hh->prim == PH_CONTROL_IND)
1421 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1422 add_trace("unknown", NULL, "0x%x", hh->id);
1427 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ)
1431 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1432 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1435 /* see below (same condition) */
1436 if (p_state!=PORT_STATE_CONNECT
1437 && !p_m_mISDNport->tones)
1439 // printf(".");fflush(stdout);return;
1441 record(data, len, 1); // from up
1444 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1446 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1450 /* calls will not process any audio data unless
1451 * the call is connected OR tones feature is enabled.
1453 #ifndef DEBUG_COREBRIDGE
1454 if (p_state!=PORT_STATE_CONNECT
1455 && !p_m_mISDNport->tones)
1460 /* the bearer capability must be audio in order to send and receive
1461 * audio prior or after connect.
1463 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1467 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1470 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1476 record(data, len, 0); // from down
1478 /* randomize and listen to crypt message if enabled */
1479 if (p_m_crypt_listen)
1481 /* the noisy randomizer */
1485 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1487 cryptman_listen_bch(data, len);
1492 /* send data to epoint */
1493 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1499 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1500 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1501 memcpy(message->param.data.data, data_temp, message->param.data.len);
1502 message_put(message);
1503 if (length_temp <= sizeof(message->param.data.data))
1505 data_temp += sizeof(message->param.data.data);
1506 length_temp -= sizeof(message->param.data.data);
1515 void PmISDN::set_echotest(int echo)
1517 if (p_m_echo != echo)
1520 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1522 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1523 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);
1530 void PmISDN::set_tone(char *dir, char *tone)
1536 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1543 /* check if we NOT really have to use a dsp-tone */
1544 if (!options.dsptones)
1548 if (p_m_b_index > -1)
1549 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1551 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1552 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1555 Port::set_tone(dir, tone);
1561 /* now we USE dsp-tone, convert name */
1562 else if (!strcmp(tone, "dialtone"))
1564 switch(options.dsptones) {
1565 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1566 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1567 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1569 } else if (!strcmp(tone, "dialpbx"))
1571 switch(options.dsptones) {
1572 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1573 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1574 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1576 } else if (!strcmp(tone, "ringing"))
1578 switch(options.dsptones) {
1579 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1580 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1581 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1583 } else if (!strcmp(tone, "ringpbx"))
1585 switch(options.dsptones) {
1586 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1587 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1588 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1590 } else if (!strcmp(tone, "busy"))
1593 switch(options.dsptones) {
1594 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1595 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1596 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1598 } else if (!strcmp(tone, "release"))
1601 switch(options.dsptones) {
1602 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1603 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1604 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1606 } else if (!strcmp(tone, "cause_10"))
1608 else if (!strcmp(tone, "cause_11"))
1610 else if (!strcmp(tone, "cause_22"))
1612 switch(options.dsptones) {
1613 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1614 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1615 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1617 } else if (!strncmp(tone, "cause_", 6))
1618 id = TONE_SPECIAL_INFO;
1622 /* if we have a tone that is not supported by dsp */
1623 if (id==TONE_OFF && tone[0])
1631 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1632 if (p_m_b_index > -1)
1633 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1634 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);
1636 /* turn user-space tones off in cases of no tone OR dsp tone */
1637 Port::set_tone("",NULL);
1641 /* MESSAGE_mISDNSIGNAL */
1642 //extern struct lcr_msg *dddebug;
1643 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1645 switch(param->mISDNsignal.message)
1647 case mISDNSIGNAL_VOLUME:
1648 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1650 p_m_tx_gain = param->mISDNsignal.tx_gain;
1651 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1652 if (p_m_b_index > -1)
1653 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1654 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);
1656 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1657 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1659 p_m_rx_gain = param->mISDNsignal.rx_gain;
1660 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1661 if (p_m_b_index > -1)
1662 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1663 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);
1665 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1668 case mISDNSIGNAL_CONF:
1669 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1670 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1671 if (p_m_conf != param->mISDNsignal.conf)
1673 p_m_conf = param->mISDNsignal.conf;
1674 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1675 if (p_m_b_index > -1)
1676 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1677 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);
1679 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1680 /* we must set, even if currently tone forbids conf */
1681 p_m_conf = param->mISDNsignal.conf;
1682 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1685 case mISDNSIGNAL_JOINDATA:
1686 if (p_m_joindata != param->mISDNsignal.joindata)
1688 p_m_joindata = param->mISDNsignal.joindata;
1689 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1691 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1694 case mISDNSIGNAL_DELAY:
1695 if (p_m_delay != param->mISDNsignal.delay)
1697 p_m_delay = param->mISDNsignal.delay;
1698 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1699 if (p_m_b_index > -1)
1700 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1701 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);
1703 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1707 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1712 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1714 struct lcr_msg *message;
1716 switch(param->crypt.type)
1718 case CC_ACTBF_REQ: /* activate blowfish */
1720 p_m_crypt_key_len = param->crypt.len;
1721 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1723 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1724 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1725 message->param.crypt.type = CC_ERROR_IND;
1726 message_put(message);
1729 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1731 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1732 if (p_m_b_index > -1)
1733 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1734 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);
1737 case CC_DACT_REQ: /* deactivate session encryption */
1742 case CR_LISTEN_REQ: /* start listening to messages */
1743 p_m_crypt_listen = 1;
1744 p_m_crypt_listen_state = 0;
1747 case CR_UNLISTEN_REQ: /* stop listening to messages */
1748 p_m_crypt_listen = 0;
1751 case CR_MESSAGE_REQ: /* send message */
1752 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1753 if (!p_m_crypt_msg_len)
1755 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1758 p_m_crypt_msg_current = 0; /* reset */
1759 p_m_crypt_msg_loops = 6; /* enable */
1761 /* disable txmix, or we get corrupt data due to audio process */
1762 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1764 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1765 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1771 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1777 * endpoint sends messages to the port
1779 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1781 if (Port::message_epoint(epoint_id, message_id, param))
1786 case MESSAGE_DATA: /* tx-data from upper layer */
1787 txfromup(param->data.data, param->data.len);
1790 case MESSAGE_mISDNSIGNAL: /* user command */
1791 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1792 message_mISDNsignal(epoint_id, message_id, param);
1795 case MESSAGE_CRYPT: /* crypt control command */
1796 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1797 message_crypt(epoint_id, message_id, param);
1806 * main loop for processing messages from mISDN
1808 int mISDN_handler(void)
1811 struct mISDNport *mISDNport;
1812 class PmISDN *isdnport;
1814 unsigned char buffer[2048+MISDN_HEADER_LEN];
1815 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1819 /* process all ports */
1820 mISDNport = mISDNport_first;
1823 /* process all bchannels */
1825 while(i < mISDNport->b_num)
1827 /* process timer events for bchannel handling */
1828 if (mISDNport->b_timer[i])
1830 if (mISDNport->b_timer[i] <= now_d)
1831 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
1833 /* handle port of bchannel */
1834 isdnport=mISDNport->b_port[i];
1837 /* call bridges in user space OR crypto OR recording */
1838 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1840 /* rx IS required */
1841 if (isdnport->p_m_rxoff)
1844 isdnport->p_m_rxoff = 0;
1845 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1846 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1847 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1852 /* rx NOT required */
1853 if (!isdnport->p_m_rxoff)
1856 isdnport->p_m_rxoff = 1;
1857 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1858 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1859 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1864 if (isdnport->p_record)
1866 /* txdata IS required */
1867 if (!isdnport->p_m_txdata)
1870 isdnport->p_m_txdata = 1;
1871 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1872 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1873 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1878 /* txdata NOT required */
1879 if (isdnport->p_m_txdata)
1882 isdnport->p_m_txdata = 0;
1883 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1884 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1885 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1891 /* handle message from bchannel */
1892 if (mISDNport->b_socket[i] > -1)
1894 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
1895 if (ret >= (int)MISDN_HEADER_LEN)
1900 /* we don't care about confirms, we use rx data to sync tx */
1904 /* we receive audio data, we respond to it AND we send tones */
1909 case PH_CONTROL_IND:
1910 if (mISDNport->b_port[i])
1911 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1913 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
1916 case PH_ACTIVATE_IND:
1917 case DL_ESTABLISH_IND:
1918 case PH_ACTIVATE_CNF:
1919 case DL_ESTABLISH_CNF:
1920 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
1921 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1924 case PH_DEACTIVATE_IND:
1925 case DL_RELEASE_IND:
1926 case PH_DEACTIVATE_CNF:
1927 case DL_RELEASE_CNF:
1928 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
1929 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1933 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
1937 if (ret < 0 && errno != EWOULDBLOCK)
1938 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
1945 /* handle queued up-messages (d-channel) */
1946 while ((mb = mdequeue(&mISDNport->upqueue)))
1951 case MPH_ACTIVATE_IND:
1952 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1954 mISDNport->l1link = 1;
1957 case MPH_DEACTIVATE_IND:
1958 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1960 mISDNport->l1link = 0;
1963 case MPH_INFORMATION_IND:
1964 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1967 case L1_SIGNAL_LOS_ON:
1970 case L1_SIGNAL_LOS_OFF:
1973 case L1_SIGNAL_AIS_ON:
1976 case L1_SIGNAL_AIS_OFF:
1979 case L1_SIGNAL_RDI_ON:
1982 case L1_SIGNAL_RDI_OFF:
1985 case L1_SIGNAL_SLIP_TX:
1986 mISDNport->slip_tx++;
1988 case L1_SIGNAL_SLIP_RX:
1989 mISDNport->slip_rx++;
1994 case MT_L2ESTABLISH:
1995 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1996 add_trace("tei", NULL, "%d", l3m->pid);
1998 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2000 if (mISDNport->l2establish)
2002 mISDNport->l2establish = 0;
2003 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2005 mISDNport->l2link = 1;
2010 if (!mISDNport->l2establish)
2012 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2013 add_trace("tei", NULL, "%d", l3m->pid);
2016 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2018 mISDNport->l2link = 0;
2019 if (!mISDNport->l2establish && mISDNport->l2hold)
2021 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
2022 time(&mISDNport->l2establish);
2023 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2029 /* l3-data is sent to LCR */
2030 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
2037 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2039 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2040 mISDNport->l1timeout = 0;
2043 /* layer 2 establish timer */
2044 if (mISDNport->l2establish)
2046 if (now-mISDNport->l2establish > 5)
2048 mISDNport->l2establish = 0;
2049 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2052 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2053 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2054 time(&mISDNport->l2establish);
2061 mISDNport = mISDNport->next;
2064 /* if we received at least one b-frame, we will return 1 */
2068 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2072 * l3m must be queued, except for MT_ASSIGN
2075 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2078 /* special MT_ASSIGN handling:
2080 * if we request a PID from mlayer, we always do it while lcr is locked.
2081 * therefore we must check the MT_ASSIGN reply first before we lock.
2082 * this is because the MT_ASSIGN reply is received with the requesting
2083 * process, not by the mlayer thread!
2084 * this means, that the reply is sent during call of the request.
2085 * we must check if we get a reply and we know that we lcr is currently
2088 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER)
2090 /* let's do some checking if someone changes stack behaviour */
2091 if (mt_assign_pid != 0)
2092 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2093 mt_assign_pid = pid;
2097 /* queue message, create, if required */
2100 l3m = alloc_l3_msg();
2102 FATAL("No memory for layer 3 message\n");
2104 mb = container_of(l3m, struct mbuffer, l3);
2107 mqueue_tail(&mISDNport->upqueue, mb);
2113 * global function to add a new card (port)
2115 struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, struct interface *interface)
2118 struct mISDNport *mISDNport, **mISDNportp;
2122 // struct mlayer3 *ml3;
2123 struct mISDN_devinfo devinfo;
2124 unsigned int protocol, prop;
2126 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2129 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2135 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2138 if (port>cnt || port<1)
2140 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2144 pri = bri = pots = nt = te = 0;
2145 devinfo.id = port - 1;
2146 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2149 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2152 /* output the port info */
2153 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2158 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2163 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2168 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2174 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2181 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2187 if (force_nt && !nt)
2189 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2194 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2197 if (pots && !bri && !pri)
2199 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2204 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2209 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2212 /* set NT by turning off TE */
2215 /* if TE an NT is supported (and not forced to NT), turn off NT */
2219 /* add mISDNport structure */
2220 mISDNportp = &mISDNport_first;
2222 mISDNportp = &((*mISDNportp)->next);
2223 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2224 mISDNport->l1link = -1;
2226 *mISDNportp = mISDNport;
2228 /* if pri, must set PTP */
2249 /* allocate ressources of port */
2250 /* open layer 3 and init upqueue */
2251 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2252 prop = (1 << MISDN_FLG_L2_CLEAN);
2253 if (ptp) // ptp forced
2254 prop |= (1 << MISDN_FLG_PTP);
2255 if (nt) // supports hold/retrieve on nt-mode
2256 prop |= (1 << MISDN_FLG_NET_HOLD);
2257 if (l2hold) // supports layer 2 hold
2258 prop |= (1 << MISDN_FLG_L2_HOLD);
2259 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2260 mqueue_init(&mISDNport->upqueue);
2261 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_layer3, mISDNport);
2262 if (!mISDNport->ml3)
2264 mqueue_purge(&mISDNport->upqueue);
2265 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2273 "PORT (open failed)");
2275 mISDNport_close(mISDNport);
2280 /* if ntmode, establish L1 to send the tei removal during start */
2281 if (mISDNport->ntmode)
2285 act.prim = PH_ACTIVATE | REQUEST;
2286 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2287 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2290 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2291 usleep(10000); /* to be sure, that l1 is up */
2295 SCPY(mISDNport->name, devinfo.name);
2296 mISDNport->b_num = devinfo.nrbchan;
2297 mISDNport->portnum = port;
2298 mISDNport->ntmode = nt;
2299 mISDNport->pri = pri;
2300 mISDNport->ptp = ptp;
2301 mISDNport->l2hold = l2hold;
2302 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2304 while(i < mISDNport->b_num)
2306 mISDNport->b_state[i] = B_STATE_IDLE;
2307 mISDNport->b_socket[i] = -1;
2311 /* if ptp, pull up the link */
2312 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2314 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2315 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2316 add_trace("tei", NULL, "%d", 0);
2318 time(&mISDNport->l2establish);
2321 /* initially, we assume that the link is down, exept for nt-ptmp */
2322 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2324 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2326 start_trace(mISDNport->portnum,
2334 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2335 add_trace("channels", NULL, "%d", mISDNport->b_num);
2342 * function to free ALL cards (ports)
2344 void mISDNport_close_all(void)
2346 /* free all ports */
2347 while(mISDNport_first)
2348 mISDNport_close(mISDNport_first);
2352 * free only one port
2354 void mISDNport_close(struct mISDNport *mISDNport)
2356 struct mISDNport **mISDNportp;
2358 class PmISDN *isdnport;
2361 /* remove all port instance that are linked to this mISDNport */
2365 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2367 isdnport = (class PmISDN *)port;
2368 if (isdnport->p_m_mISDNport)
2370 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2377 /* only if we are already part of interface */
2378 if (mISDNport->ifport)
2380 start_trace(mISDNport->portnum,
2381 mISDNport->ifport->interface,
2391 /* free bchannels */
2393 while(i < mISDNport->b_num)
2395 if (mISDNport->b_socket[i] > -1)
2397 _bchannel_destroy(mISDNport, i);
2398 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2403 /* close layer 3, if open and purge upqueue */
2406 close_layer3(mISDNport->ml3);
2407 mqueue_purge(&mISDNport->upqueue);
2410 /* remove from list */
2411 mISDNportp = &mISDNport_first;
2414 if (*mISDNportp == mISDNport)
2416 *mISDNportp = (*mISDNportp)->next;
2420 mISDNportp = &((*mISDNportp)->next);
2424 FATAL("mISDNport not in list\n");
2426 FREE(mISDNport, sizeof(struct mISDNport));
2433 * enque data from upper buffer
2435 void PmISDN::txfromup(unsigned char *data, int length)
2437 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2438 struct mISDNhead *hh = (struct mISDNhead *)buf;
2441 if (p_m_b_index < 0)
2443 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2446 /* check if high priority tones exist
2447 * ignore data in this case
2449 if (p_tone_name[0] || p_m_crypt_msg_loops)
2452 /* preload procedure
2453 * if transmit buffer in DSP module is empty,
2454 * preload it to DSP_LOAD to prevent jitter gaps.
2456 if (p_m_load==0 && ISDN_LOAD>0)
2458 hh->prim = PH_DATA_REQ;
2460 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2461 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2463 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
2464 p_m_load += ISDN_LOAD;
2467 /* drop if load would exceed ISDN_MAXLOAD
2468 * this keeps the delay not too high
2470 if (p_m_load+length > ISDN_MAXLOAD)
2473 /* make and send frame */
2474 hh->prim = PH_DATA_REQ;
2476 memcpy(buf+MISDN_HEADER_LEN, data, length);
2477 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2479 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);