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;
779 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
780 _bchannel_activate(mISDNport, i, 0);
781 state = B_STATE_DEACTIVATING;
782 timer = now_d + B_TIMER_DEACTIVATING;
787 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
791 case B_EVENT_EXPORTED:
794 case B_STATE_EXPORTING:
795 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
797 /* remote export done */
798 state = B_STATE_REMOTE;
801 /* bchannel is now exported, but we need bchannel back
802 * OR bchannel is not used anymore
803 * OR bchannel has been exported to an obsolete ref,
804 * so reimport, to later export to new remote */
805 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
806 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
807 add_trace("type", NULL, "remove");
808 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
810 state = B_STATE_IMPORTING;
815 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
821 FATAL("bchannel must be linked to a Port class\n");
825 /* bchannel is idle due to an error, so we do nothing */
828 case B_STATE_ACTIVATING:
829 case B_STATE_EXPORTING:
830 /* do nothing because we must wait until bchanenl is active before deactivating */
834 /* bchannel is active, so we deactivate */
835 _bchannel_activate(mISDNport, i, 0);
836 state = B_STATE_DEACTIVATING;
837 timer = now_d + B_TIMER_DEACTIVATING;
841 /* bchannel is exported, so we re-import */
842 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
843 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
844 add_trace("type", NULL, "remove");
845 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
847 state = B_STATE_IMPORTING;
850 case B_STATE_DEACTIVATING:
851 case B_STATE_IMPORTING:
852 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
856 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
860 case B_EVENT_DEACTIVATED:
865 /* ignore due to deactivation confirm after unloading */
868 case B_STATE_DEACTIVATING:
869 _bchannel_destroy(mISDNport, i);
870 state = B_STATE_IDLE;
873 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
876 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);
877 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
878 add_trace("type", NULL, "assign");
879 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
881 state = B_STATE_EXPORTING;
882 mISDNport->b_remote_id[i] = p_m_remote_id;
883 mISDNport->b_remote_ref[i] = p_m_remote_ref;
886 if (_bchannel_create(mISDNport, i))
888 _bchannel_activate(mISDNport, i, 1);
889 state = B_STATE_ACTIVATING;
890 timer = now_d + B_TIMER_ACTIVATING;
897 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
901 case B_EVENT_IMPORTED:
904 case B_STATE_IMPORTING:
905 state = B_STATE_IDLE;
906 mISDNport->b_remote_id[i] = 0;
907 mISDNport->b_remote_ref[i] = 0;
910 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
913 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);
914 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
915 add_trace("type", NULL, "assign");
916 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
918 state = B_STATE_EXPORTING;
919 mISDNport->b_remote_id[i] = p_m_remote_id;
920 mISDNport->b_remote_ref[i] = p_m_remote_ref;
923 if (_bchannel_create(mISDNport, i))
925 _bchannel_activate(mISDNport, i, 1);
926 state = B_STATE_ACTIVATING;
927 timer = now_d + B_TIMER_ACTIVATING;
934 /* ignore, because not assigned */
939 case B_EVENT_TIMEOUT:
944 /* ignore due to deactivation confirm after unloading */
947 case B_STATE_ACTIVATING:
948 _bchannel_activate(mISDNport, i, 1);
949 timer = now_d + B_TIMER_ACTIVATING;
952 case B_STATE_DEACTIVATING:
953 _bchannel_activate(mISDNport, i, 0);
954 timer = now_d + B_TIMER_DEACTIVATING;
958 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
963 PERROR("Illegal event %d, please correct.\n", event);
966 mISDNport->b_state[i] = state;
967 mISDNport->b_timer[i] = timer;
974 * check for available channel and reserve+set it.
975 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
977 * returns -(cause value) or x = channel x or 0 = no channel
978 * NOTE: no activation is done here
980 int PmISDN::seize_bchannel(int channel, int exclusive)
984 /* the channel is what we have */
985 if (p_m_b_channel == channel)
988 /* if channel already in use, release it */
993 if (channel==CHANNEL_NO || channel==0)
996 /* is channel in range ? */
998 || (channel>p_m_mISDNport->b_num && channel<16)
999 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1000 return(-6); /* channel unacceptable */
1002 /* request exclusive channel */
1003 if (exclusive && channel>0)
1005 i = channel-1-(channel>16);
1006 if (p_m_mISDNport->b_port[i])
1007 return(-44); /* requested channel not available */
1011 /* ask for channel */
1014 i = channel-1-(channel>16);
1015 if (p_m_mISDNport->b_port[i] == NULL)
1019 /* search for channel */
1021 while(i < p_m_mISDNport->b_num)
1023 if (!p_m_mISDNport->b_port[i])
1025 channel = i+1+(i>=15);
1030 return(-34); /* no free channel */
1033 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1035 /* link Port, set parameters */
1036 p_m_mISDNport->b_port[i] = this;
1038 p_m_b_channel = channel;
1039 p_m_b_exclusive = exclusive;
1040 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1042 /* reserve channel */
1046 p_m_mISDNport->b_reserved++;
1053 * drop reserved channel and unset it.
1054 * deactivation is also done
1056 void PmISDN::drop_bchannel(void)
1058 /* unreserve channel */
1060 p_m_mISDNport->b_reserved--;
1064 if (p_m_b_index < 0)
1069 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1071 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1072 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1073 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1074 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1077 p_m_b_exclusive = 0;
1080 /* process bchannel export/import message from join */
1081 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1083 class Endpoint *epoint;
1085 class PmISDN *isdnport;
1086 struct mISDNport *mISDNport;
1091 case BCHANNEL_REQUEST:
1092 /* find the port object for the join object ref */
1093 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1095 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1098 if (!epoint->ep_portlist)
1100 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1103 if (epoint->ep_portlist->next)
1105 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);
1107 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1109 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1112 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN)
1114 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1116 isdnport = (class PmISDN *)port;
1119 if (isdnport->p_m_remote_id)
1121 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1124 mISDNport = isdnport->p_m_mISDNport;
1125 i = isdnport->p_m_b_index;
1126 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1127 add_trace("type", NULL, "export request");
1129 isdnport->p_m_remote_ref = joinremote->j_serial;
1130 isdnport->p_m_remote_id = joinremote->j_remote_id;
1131 if (mISDNport && i>=0)
1133 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1137 case BCHANNEL_RELEASE:
1138 case BCHANNEL_ASSIGN_ACK:
1139 case BCHANNEL_REMOVE_ACK:
1140 /* find mISDNport for stack ID */
1141 mISDNport = mISDNport_first;
1145 ii = mISDNport->b_num;
1148 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1154 mISDNport = mISDNport->next;
1158 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1162 if (type!=BCHANNEL_RELEASE)
1165 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1166 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1168 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1172 isdnport = mISDNport->b_port[i];
1173 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1174 add_trace("type", NULL, "import request");
1178 isdnport->p_m_remote_ref = 0;
1179 isdnport->p_m_remote_id = 0;
1181 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1185 PERROR("received wrong bchannel message type %d from remote\n", type);
1193 audio transmission procedure:
1194 -----------------------------
1197 three sources of audio transmission:
1198 - crypto-data high priority
1199 - tones high priority (also high)
1200 - remote-data low priority
1203 a variable that temporarily shows the number of samples elapsed since last transmission process.
1204 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1207 a variable that is increased whenever data is transmitted.
1208 it is decreased while time elapses. it stores the number of samples that
1209 are currently loaded to dsp module.
1210 since clock in dsp module is the same clock for user space process, these
1214 there are two levels:
1215 ISDN_LOAD will give the load that have to be kept in dsp.
1216 ISDN_MAXLOAD will give the maximum load before dropping.
1218 * procedure for low priority data
1219 see txfromup() for procedure
1220 in short: remote data is ignored during high priority tones
1222 * procedure for high priority data
1223 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1224 if no more data is available, load becomes empty again.
1227 0 ISDN_LOAD ISDN_MAXLOAD
1228 +--------------------+----------------------+
1230 +--------------------+----------------------+
1232 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1233 0 ISDN_LOAD ISDN_MAXLOAD
1234 +--------------------+----------------------+
1235 |TTTTTTTTTTTTTTTTTTTT| |
1236 +--------------------+----------------------+
1238 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1239 0 ISDN_LOAD ISDN_MAXLOAD
1240 +--------------------+----------------------+
1241 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1242 +--------------------+----------------------+
1245 int PmISDN::handler(void)
1247 struct lcr_msg *message;
1251 if ((ret = Port::handler()))
1255 if (p_m_last_tv_sec)
1257 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1258 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1261 /* set clock of first process ever in this instance */
1262 p_m_last_tv_sec = now_tv.tv_sec;
1263 p_m_last_tv_msec = now_tv.tv_usec/1000;
1265 /* process only if we have a minimum of samples, to make packets not too small */
1266 if (elapsed >= ISDN_TRANSMIT)
1268 /* set clock of last process! */
1269 p_m_last_tv_sec = now_tv.tv_sec;
1270 p_m_last_tv_msec = now_tv.tv_usec/1000;
1273 if (elapsed < p_m_load)
1274 p_m_load -= elapsed;
1278 /* to send data, tone must be active OR crypt messages must be on */
1279 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1280 && (p_m_load < ISDN_LOAD)
1281 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1283 int tosend = ISDN_LOAD - p_m_load, length;
1284 unsigned char buf[MISDN_HEADER_LEN+tosend];
1285 struct mISDNhead *frm = (struct mISDNhead *)buf;
1286 unsigned char *p = buf+MISDN_HEADER_LEN;
1288 /* copy crypto loops */
1289 while (p_m_crypt_msg_loops && tosend)
1291 /* how much do we have to send */
1292 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1295 if (length > tosend)
1298 /* copy message (part) to buffer */
1299 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1302 p_m_crypt_msg_current += length;
1303 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1306 p_m_crypt_msg_current = 0;
1307 p_m_crypt_msg_loops--;
1308 // puts("eine loop weniger");
1316 if (p_tone_name[0] && tosend)
1318 tosend -= read_audio(p, tosend);
1322 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && ISDN_LOAD-p_m_load-tosend > 0)
1324 frm->prim = PH_DATA_REQ;
1326 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1328 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);
1330 p_m_load += ISDN_LOAD - p_m_load - tosend;
1334 // NOTE: deletion is done by the child class
1336 /* handle timeouts */
1339 if (p_m_timer+p_m_timeout < now_d)
1341 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1343 /* send timeout to endpoint */
1344 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1345 message->param.state = p_state;
1346 message_put(message);
1351 return(0); /* nothing done */
1356 * whenever we get audio data from bchannel, we process it here
1358 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1360 unsigned int cont = *((unsigned int *)data);
1361 unsigned char *data_temp;
1362 unsigned int length_temp;
1363 struct lcr_msg *message;
1367 if (hh->prim == PH_CONTROL_IND)
1371 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1374 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1376 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1377 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1379 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1380 message->param.dtmf = cont & DTMF_TONE_MASK;
1381 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1382 message_put(message);
1388 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1389 add_trace("DSP-CRYPT", NULL, "error");
1391 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1392 message->param.crypt.type = CC_ERROR_IND;
1393 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1394 message_put(message);
1398 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1399 add_trace("DSP-CRYPT", NULL, "ok");
1401 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1402 message->param.crypt.type = CC_ACTBF_CONF;
1403 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1404 message_put(message);
1408 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1409 add_trace("unknown", NULL, "0x%x", cont);
1414 if (hh->prim == PH_CONTROL_IND)
1419 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1420 add_trace("unknown", NULL, "0x%x", hh->id);
1425 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ)
1429 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1430 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1433 /* see below (same condition) */
1434 if (p_state!=PORT_STATE_CONNECT
1435 && !p_m_mISDNport->tones)
1437 // printf(".");fflush(stdout);return;
1439 record(data, len, 1); // from up
1442 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1444 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1448 /* calls will not process any audio data unless
1449 * the call is connected OR tones feature is enabled.
1451 #ifndef DEBUG_COREBRIDGE
1452 if (p_state!=PORT_STATE_CONNECT
1453 && !p_m_mISDNport->tones)
1458 /* the bearer capability must be audio in order to send and receive
1459 * audio prior or after connect.
1461 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1465 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1468 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1474 record(data, len, 0); // from down
1476 /* randomize and listen to crypt message if enabled */
1477 if (p_m_crypt_listen)
1479 /* the noisy randomizer */
1483 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1485 cryptman_listen_bch(data, len);
1490 /* send data to epoint */
1491 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1497 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1498 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1499 memcpy(message->param.data.data, data_temp, message->param.data.len);
1500 message_put(message);
1501 if (length_temp <= sizeof(message->param.data.data))
1503 data_temp += sizeof(message->param.data.data);
1504 length_temp -= sizeof(message->param.data.data);
1513 void PmISDN::set_echotest(int echo)
1515 if (p_m_echo != echo)
1518 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1520 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1521 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);
1528 void PmISDN::set_tone(char *dir, char *tone)
1534 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1541 /* check if we NOT really have to use a dsp-tone */
1542 if (!options.dsptones)
1546 if (p_m_b_index > -1)
1547 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)
1549 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1550 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1553 Port::set_tone(dir, tone);
1559 /* now we USE dsp-tone, convert name */
1560 else if (!strcmp(tone, "dialtone"))
1562 switch(options.dsptones) {
1563 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1564 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1565 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1567 } else if (!strcmp(tone, "dialpbx"))
1569 switch(options.dsptones) {
1570 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1571 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1572 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1574 } else if (!strcmp(tone, "ringing"))
1576 switch(options.dsptones) {
1577 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1578 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1579 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1581 } else if (!strcmp(tone, "ringpbx"))
1583 switch(options.dsptones) {
1584 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1585 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1586 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1588 } else if (!strcmp(tone, "busy"))
1591 switch(options.dsptones) {
1592 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1593 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1594 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1596 } else if (!strcmp(tone, "release"))
1599 switch(options.dsptones) {
1600 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1601 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1602 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1604 } else if (!strcmp(tone, "cause_10"))
1606 else if (!strcmp(tone, "cause_11"))
1608 else if (!strcmp(tone, "cause_22"))
1610 switch(options.dsptones) {
1611 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1612 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1613 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1615 } else if (!strncmp(tone, "cause_", 6))
1616 id = TONE_SPECIAL_INFO;
1620 /* if we have a tone that is not supported by dsp */
1621 if (id==TONE_OFF && tone[0])
1629 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1630 if (p_m_b_index > -1)
1631 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)
1632 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);
1634 /* turn user-space tones off in cases of no tone OR dsp tone */
1635 Port::set_tone("",NULL);
1639 /* MESSAGE_mISDNSIGNAL */
1640 //extern struct lcr_msg *dddebug;
1641 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1643 switch(param->mISDNsignal.message)
1645 case mISDNSIGNAL_VOLUME:
1646 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1648 p_m_tx_gain = param->mISDNsignal.tx_gain;
1649 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1650 if (p_m_b_index > -1)
1651 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)
1652 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);
1654 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1655 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1657 p_m_rx_gain = param->mISDNsignal.rx_gain;
1658 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1659 if (p_m_b_index > -1)
1660 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)
1661 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);
1663 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1666 case mISDNSIGNAL_CONF:
1667 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1668 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1669 if (p_m_conf != param->mISDNsignal.conf)
1671 p_m_conf = param->mISDNsignal.conf;
1672 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1673 if (p_m_b_index > -1)
1674 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1675 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);
1677 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1678 /* we must set, even if currently tone forbids conf */
1679 p_m_conf = param->mISDNsignal.conf;
1680 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1683 case mISDNSIGNAL_JOINDATA:
1684 if (p_m_joindata != param->mISDNsignal.joindata)
1686 p_m_joindata = param->mISDNsignal.joindata;
1687 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1689 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1692 case mISDNSIGNAL_DELAY:
1693 if (p_m_delay != param->mISDNsignal.delay)
1695 p_m_delay = param->mISDNsignal.delay;
1696 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1697 if (p_m_b_index > -1)
1698 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)
1699 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);
1701 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1705 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1710 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1712 struct lcr_msg *message;
1714 switch(param->crypt.type)
1716 case CC_ACTBF_REQ: /* activate blowfish */
1718 p_m_crypt_key_len = param->crypt.len;
1719 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1721 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1722 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1723 message->param.crypt.type = CC_ERROR_IND;
1724 message_put(message);
1727 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1729 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1730 if (p_m_b_index > -1)
1731 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)
1732 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);
1735 case CC_DACT_REQ: /* deactivate session encryption */
1740 case CR_LISTEN_REQ: /* start listening to messages */
1741 p_m_crypt_listen = 1;
1742 p_m_crypt_listen_state = 0;
1745 case CR_UNLISTEN_REQ: /* stop listening to messages */
1746 p_m_crypt_listen = 0;
1749 case CR_MESSAGE_REQ: /* send message */
1750 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1751 if (!p_m_crypt_msg_len)
1753 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1756 p_m_crypt_msg_current = 0; /* reset */
1757 p_m_crypt_msg_loops = 6; /* enable */
1759 /* disable txmix, or we get corrupt data due to audio process */
1760 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1762 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1763 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1769 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1775 * endpoint sends messages to the port
1777 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1779 if (Port::message_epoint(epoint_id, message_id, param))
1784 case MESSAGE_DATA: /* tx-data from upper layer */
1785 txfromup(param->data.data, param->data.len);
1788 case MESSAGE_mISDNSIGNAL: /* user command */
1789 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1790 message_mISDNsignal(epoint_id, message_id, param);
1793 case MESSAGE_CRYPT: /* crypt control command */
1794 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1795 message_crypt(epoint_id, message_id, param);
1804 * main loop for processing messages from mISDN
1806 int mISDN_handler(void)
1809 struct mISDNport *mISDNport;
1810 class PmISDN *isdnport;
1812 unsigned char buffer[2048+MISDN_HEADER_LEN];
1813 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1817 /* process all ports */
1818 mISDNport = mISDNport_first;
1821 /* process all bchannels */
1823 while(i < mISDNport->b_num)
1825 /* process timer events for bchannel handling */
1826 if (mISDNport->b_timer[i])
1828 if (mISDNport->b_timer[i] <= now_d)
1829 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
1831 /* handle port of bchannel */
1832 isdnport=mISDNport->b_port[i];
1835 /* call bridges in user space OR crypto OR recording */
1836 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1838 /* rx IS required */
1839 if (isdnport->p_m_rxoff)
1842 isdnport->p_m_rxoff = 0;
1843 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1844 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1845 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1850 /* rx NOT required */
1851 if (!isdnport->p_m_rxoff)
1854 isdnport->p_m_rxoff = 1;
1855 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1856 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1857 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1862 if (isdnport->p_record)
1864 /* txdata IS required */
1865 if (!isdnport->p_m_txdata)
1868 isdnport->p_m_txdata = 1;
1869 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1870 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1871 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1876 /* txdata NOT required */
1877 if (isdnport->p_m_txdata)
1880 isdnport->p_m_txdata = 0;
1881 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1882 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1883 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1889 /* handle message from bchannel */
1890 if (mISDNport->b_socket[i] > -1)
1892 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
1893 if (ret >= (int)MISDN_HEADER_LEN)
1898 /* we don't care about confirms, we use rx data to sync tx */
1902 /* we receive audio data, we respond to it AND we send tones */
1907 case PH_CONTROL_IND:
1908 if (mISDNport->b_port[i])
1909 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1911 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
1914 case PH_ACTIVATE_IND:
1915 case DL_ESTABLISH_IND:
1916 case PH_ACTIVATE_CNF:
1917 case DL_ESTABLISH_CNF:
1918 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
1919 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1922 case PH_DEACTIVATE_IND:
1923 case DL_RELEASE_IND:
1924 case PH_DEACTIVATE_CNF:
1925 case DL_RELEASE_CNF:
1926 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
1927 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1931 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
1935 if (ret < 0 && errno != EWOULDBLOCK)
1936 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
1943 /* handle queued up-messages (d-channel) */
1944 while ((mb = mdequeue(&mISDNport->upqueue)))
1949 case MPH_ACTIVATE_IND:
1950 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1952 mISDNport->l1link = 1;
1955 case MPH_DEACTIVATE_IND:
1956 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1958 mISDNport->l1link = 0;
1961 case MPH_INFORMATION_IND:
1962 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1965 case L1_SIGNAL_LOS_ON:
1968 case L1_SIGNAL_LOS_OFF:
1971 case L1_SIGNAL_AIS_ON:
1974 case L1_SIGNAL_AIS_OFF:
1977 case L1_SIGNAL_RDI_ON:
1980 case L1_SIGNAL_RDI_OFF:
1983 case L1_SIGNAL_SLIP_TX:
1984 mISDNport->slip_tx++;
1986 case L1_SIGNAL_SLIP_RX:
1987 mISDNport->slip_rx++;
1992 case MT_L2ESTABLISH:
1993 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1994 add_trace("tei", NULL, "%d", l3m->pid);
1996 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
1998 if (mISDNport->l2establish)
2000 mISDNport->l2establish = 0;
2001 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2003 mISDNport->l2link = 1;
2008 if (!mISDNport->l2establish)
2010 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2011 add_trace("tei", NULL, "%d", l3m->pid);
2014 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2016 mISDNport->l2link = 0;
2017 if (!mISDNport->l2establish && mISDNport->l2hold)
2019 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
2020 time(&mISDNport->l2establish);
2021 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2027 /* l3-data is sent to LCR */
2028 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
2035 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2037 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2038 mISDNport->l1timeout = 0;
2041 /* layer 2 establish timer */
2042 if (mISDNport->l2establish)
2044 if (now-mISDNport->l2establish > 5)
2046 mISDNport->l2establish = 0;
2047 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2050 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2051 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2052 time(&mISDNport->l2establish);
2059 mISDNport = mISDNport->next;
2062 /* if we received at least one b-frame, we will return 1 */
2066 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2070 * l3m must be queued, except for MT_ASSIGN
2073 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2076 /* special MT_ASSIGN handling:
2078 * if we request a PID from mlayer, we always do it while lcr is locked.
2079 * therefore we must check the MT_ASSIGN reply first before we lock.
2080 * this is because the MT_ASSIGN reply is received with the requesting
2081 * process, not by the mlayer thread!
2082 * this means, that the reply is sent during call of the request.
2083 * we must check if we get a reply and we know that we lcr is currently
2086 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER)
2088 /* let's do some checking if someone changes stack behaviour */
2089 if (mt_assign_pid != 0)
2090 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2091 mt_assign_pid = pid;
2095 /* queue message, create, if required */
2098 l3m = alloc_l3_msg();
2100 FATAL("No memory for layer 3 message\n");
2102 mb = container_of(l3m, struct mbuffer, l3);
2105 mqueue_tail(&mISDNport->upqueue, mb);
2111 * global function to add a new card (port)
2113 struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, struct interface *interface)
2116 struct mISDNport *mISDNport, **mISDNportp;
2120 // struct mlayer3 *ml3;
2121 struct mISDN_devinfo devinfo;
2122 unsigned int protocol, prop;
2124 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2127 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2133 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2136 if (port>cnt || port<1)
2138 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2142 pri = bri = pots = nt = te = 0;
2143 devinfo.id = port - 1;
2144 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2147 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2150 /* output the port info */
2151 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2156 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2161 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2166 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2172 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2179 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2185 if (force_nt && !nt)
2187 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2192 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2195 if (pots && !bri && !pri)
2197 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2202 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2207 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2210 /* set NT by turning off TE */
2213 /* if TE an NT is supported (and not forced to NT), turn off NT */
2217 /* add mISDNport structure */
2218 mISDNportp = &mISDNport_first;
2220 mISDNportp = &((*mISDNportp)->next);
2221 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2222 mISDNport->l1link = -1;
2224 *mISDNportp = mISDNport;
2226 /* if pri, must set PTP */
2247 /* allocate ressources of port */
2248 /* open layer 3 and init upqueue */
2249 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2250 prop = (1 << MISDN_FLG_L2_CLEAN);
2251 if (ptp) // ptp forced
2252 prop |= (1 << MISDN_FLG_PTP);
2253 if (nt) // supports hold/retrieve on nt-mode
2254 prop |= (1 << MISDN_FLG_NET_HOLD);
2255 if (l2hold) // supports layer 2 hold
2256 prop |= (1 << MISDN_FLG_L2_HOLD);
2257 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2258 mqueue_init(&mISDNport->upqueue);
2259 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_layer3, mISDNport);
2260 if (!mISDNport->ml3)
2262 mqueue_purge(&mISDNport->upqueue);
2263 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2271 "PORT (open failed)");
2273 mISDNport_close(mISDNport);
2278 /* if ntmode, establish L1 to send the tei removal during start */
2279 if (mISDNport->ntmode)
2283 act.prim = PH_ACTIVATE | REQUEST;
2284 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2285 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2288 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2289 usleep(10000); /* to be sure, that l1 is up */
2293 SCPY(mISDNport->name, devinfo.name);
2294 mISDNport->b_num = devinfo.nrbchan;
2295 mISDNport->portnum = port;
2296 mISDNport->ntmode = nt;
2297 mISDNport->pri = pri;
2298 mISDNport->ptp = ptp;
2299 mISDNport->l2hold = l2hold;
2300 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2302 while(i < mISDNport->b_num)
2304 mISDNport->b_state[i] = B_STATE_IDLE;
2305 mISDNport->b_socket[i] = -1;
2309 /* if ptp, pull up the link */
2310 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2312 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2313 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2314 add_trace("tei", NULL, "%d", 0);
2316 time(&mISDNport->l2establish);
2319 /* initially, we assume that the link is down, exept for nt-ptmp */
2320 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2322 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2324 start_trace(mISDNport->portnum,
2332 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2333 add_trace("channels", NULL, "%d", mISDNport->b_num);
2340 * function to free ALL cards (ports)
2342 void mISDNport_close_all(void)
2344 /* free all ports */
2345 while(mISDNport_first)
2346 mISDNport_close(mISDNport_first);
2350 * free only one port
2352 void mISDNport_close(struct mISDNport *mISDNport)
2354 struct mISDNport **mISDNportp;
2356 class PmISDN *isdnport;
2359 /* remove all port instance that are linked to this mISDNport */
2363 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2365 isdnport = (class PmISDN *)port;
2366 if (isdnport->p_m_mISDNport)
2368 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2375 /* only if we are already part of interface */
2376 if (mISDNport->ifport)
2378 start_trace(mISDNport->portnum,
2379 mISDNport->ifport->interface,
2389 /* free bchannels */
2391 while(i < mISDNport->b_num)
2393 if (mISDNport->b_socket[i] > -1)
2395 _bchannel_destroy(mISDNport, i);
2396 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2401 /* close layer 3, if open and purge upqueue */
2404 close_layer3(mISDNport->ml3);
2405 mqueue_purge(&mISDNport->upqueue);
2408 /* remove from list */
2409 mISDNportp = &mISDNport_first;
2412 if (*mISDNportp == mISDNport)
2414 *mISDNportp = (*mISDNportp)->next;
2418 mISDNportp = &((*mISDNportp)->next);
2422 FATAL("mISDNport not in list\n");
2424 FREE(mISDNport, sizeof(struct mISDNport));
2431 * enque data from upper buffer
2433 void PmISDN::txfromup(unsigned char *data, int length)
2435 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2436 struct mISDNhead *hh = (struct mISDNhead *)buf;
2439 if (p_m_b_index < 0)
2441 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2444 /* check if high priority tones exist
2445 * ignore data in this case
2447 if (p_tone_name[0] || p_m_crypt_msg_loops)
2450 /* preload procedure
2451 * if transmit buffer in DSP module is empty,
2452 * preload it to DSP_LOAD to prevent jitter gaps.
2454 if (p_m_load==0 && ISDN_LOAD>0)
2456 hh->prim = PH_DATA_REQ;
2458 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2459 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2461 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
2462 p_m_load += ISDN_LOAD;
2465 /* drop if load would exceed ISDN_MAXLOAD
2466 * this keeps the delay not too high
2468 if (p_m_load+length > ISDN_MAXLOAD)
2471 /* make and send frame */
2472 hh->prim = PH_DATA_REQ;
2474 memcpy(buf+MISDN_HEADER_LEN, data, length);
2475 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2477 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);