1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 and sip **
10 \*****************************************************************************/
16 #include <sys/ioctl.h>
17 #include <sys/types.h>
21 #include <netinet/udp.h>
22 #include <netinet/in.h>
24 #include <sys/socket.h>
26 #include <linux/mISDNif.h>
31 #include <mISDNuser/net_l2.h>
35 #ifndef ISDN_PID_L4_B_USER
36 #define ISDN_PID_L4_B_USER 0x440000ff
39 /* list of mISDN ports */
40 struct mISDNport *mISDNport_first;
42 /* noise randomizer */
43 unsigned char mISDN_rand[256];
44 int mISDN_rand_count = 0;
49 int mISDN_initialize(void)
51 /* try to open raw socket to check kernel */
52 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
55 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
59 /* initialize stuff of the NT lib */
60 if (options.deb & DEBUG_STACK)
62 global_debug = 0xffffffff & ~DBGM_MSG;
63 // global_debug = DBGM_L3DATA;
65 global_debug = DBGM_MAN;
66 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
67 if (options.deb & DEBUG_LOG)
68 mISDN_debug_init(global_debug, debug_log, debug_log, debug_log);
70 mISDN_debug_init(global_debug, NULL, NULL, NULL);
73 init_layer3(4); // buffer of 4
78 void mISDN_deinitialize(void)
88 int entity = 0; /* used for udevice */
89 int mISDNdevice = -1; /* the device handler and port list */
91 int mISDN_initialize(void)
94 unsigned char buff[1025];
95 iframe_t *frm = (iframe_t *)buff;
98 /* initialize stuff of the NT lib */
99 if (options.deb & DEBUG_STACK)
101 global_debug = 0xffffffff & ~DBGM_MSG;
102 // global_debug = DBGM_L3DATA;
104 global_debug = DBGM_MAN;
105 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
106 if (options.deb & DEBUG_LOG)
107 debug_init(global_debug, debug_log, debug_log, debug_log);
109 debug_init(global_debug, NULL, NULL, NULL);
112 /* open mISDNdevice if not already open */
118 fprintf(stderr, "cannot open mISDN device ret=%d errno=%d (%s) Check for mISDN modules!\nAlso did you create \"/dev/mISDN\"? Do: \"mknod /dev/mISDN c 46 0\"\n", ret, errno, strerror(errno));
122 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
124 /* create entity for layer 3 TE-mode */
125 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
126 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
127 if (ret < (int)mISDN_HEADER_LEN)
130 FATAL("Cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
132 entity = frm->dinfo & 0xffff;
135 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
140 void mISDN_deinitialize(void)
142 unsigned char buff[1025];
146 if (mISDNdevice >= 0)
149 mISDN_write_frame(mISDNdevice, buff, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
151 mISDN_close(mISDNdevice);
153 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
161 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : Port(type, portname, settings)
163 p_m_mISDNport = mISDNport;
164 p_m_portnum = mISDNport->portnum;
171 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
172 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
180 p_m_dtmf = !mISDNport->ifport->nodtmf;
183 p_m_remote_ref = 0; /* channel shall be exported to given remote */
184 p_m_remote_id = 0; /* channel shall be exported to given remote */
185 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
193 p_m_crypt_listen = 0;
194 p_m_crypt_msg_loops = 0;
195 p_m_crypt_msg_loops = 0;
196 p_m_crypt_msg_len = 0;
197 p_m_crypt_msg[0] = '\0';
198 p_m_crypt_msg_current = 0;
199 p_m_crypt_key_len = 0;
200 p_m_crypt_listen = 0;
201 p_m_crypt_listen_state = 0;
202 p_m_crypt_listen_len = 0;
203 p_m_crypt_listen_msg[0] = '\0';
204 p_m_crypt_listen_crc = 0;
205 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56)
207 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
208 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
212 /* if any channel requested by constructor */
213 if (channel == CHANNEL_ANY)
215 /* reserve channel */
217 mISDNport->b_reserved++;
220 /* reserve channel */
221 if (channel > 0) // only if constructor was called with a channel resevation
222 seize_bchannel(channel, exclusive);
224 /* we increase the number of objects: */
226 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
235 struct message *message;
237 /* remove bchannel relation */
243 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
244 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
245 message->param.disconnectinfo.cause = 16;
246 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
247 message_put(message);
248 /* remove from list */
249 free_epointlist(p_epointlist);
252 /* we decrease the number of objects: */
253 p_m_mISDNport->use--;
254 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
261 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
263 /* init trace with given values */
264 start_trace(mISDNport?mISDNport->portnum:0,
265 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
266 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
267 port?port->p_dialinginfo.id:NULL,
270 port?port->p_serial:0,
278 static struct isdn_message {
282 {"TIMEOUT", CC_TIMEOUT},
284 {"SETUP_ACK", CC_SETUP_ACKNOWLEDGE},
285 {"PROCEEDING", CC_PROCEEDING},
286 {"ALERTING", CC_ALERTING},
287 {"CONNECT", CC_CONNECT},
288 {"CONNECT RES", CC_CONNECT},
289 {"CONNECT_ACK", CC_CONNECT_ACKNOWLEDGE},
290 {"DISCONNECT", CC_DISCONNECT},
291 {"RELEASE", CC_RELEASE},
292 {"RELEASE_COMP", CC_RELEASE_COMPLETE},
293 {"INFORMATION", CC_INFORMATION},
294 {"PROGRESS", CC_PROGRESS},
295 {"NOTIFY", CC_NOTIFY},
296 {"SUSPEND", CC_SUSPEND},
297 {"SUSPEND_ACK", CC_SUSPEND_ACKNOWLEDGE},
298 {"SUSPEND_REJ", CC_SUSPEND_REJECT},
299 {"RESUME", CC_RESUME},
300 {"RESUME_ACK", CC_RESUME_ACKNOWLEDGE},
301 {"RESUME_REJ", CC_RESUME_REJECT},
303 {"HOLD_ACK", CC_HOLD_ACKNOWLEDGE},
304 {"HOLD_REJ", CC_HOLD_REJECT},
305 {"RETRIEVE", CC_RETRIEVE},
306 {"RETRIEVE_ACK", CC_RETRIEVE_ACKNOWLEDGE},
307 {"RETRIEVE_REJ", CC_RETRIEVE_REJECT},
308 {"FACILITY", CC_FACILITY},
309 {"STATUS", CC_STATUS},
310 {"RESTART", CC_RESTART},
311 {"RELEASE_CR", CC_RELEASE_CR},
312 {"NEW_CR", CC_NEW_CR},
313 {"DL_ESTABLISH", DL_ESTABLISH},
314 {"DL_RELEASE", DL_RELEASE},
315 {"PH_ACTIVATE", PH_ACTIVATE},
316 {"PH_DEACTIVATE", PH_DEACTIVATE},
320 static char *isdn_prim[4] = {
326 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long prim, int direction)
329 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
331 /* select message and primitive text */
333 while(isdn_message[i].name)
335 if (isdn_message[i].value == (prim&0xffffff00))
337 SCPY(msgtext, isdn_message[i].name);
342 SCAT(msgtext, isdn_prim[prim&0x00000003]);
345 if (direction && (prim&0xffffff00)!=CC_NEW_CR && (prim&0xffffff00)!=CC_RELEASE_CR)
349 if (mISDNport->ntmode)
351 if (direction == DIRECTION_OUT)
352 SCAT(msgtext, " N->U");
354 SCAT(msgtext, " N<-U");
357 if (direction == DIRECTION_OUT)
358 SCAT(msgtext, " U->N");
360 SCAT(msgtext, " U<-N");
365 /* init trace with given values */
366 start_trace(mISDNport?mISDNport->portnum:0,
367 mISDNport?mISDNport->ifport->interface:NULL,
368 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
369 port?port->p_dialinginfo.id:NULL,
372 port?port->p_serial:0,
378 * send control information to the channel (dsp-module)
380 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long handle, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
383 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
384 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
385 unsigned long *d = buffer+MISDN_HEADER_LEN;
388 ctrl->prim = PH_CONTROL_REQ;
392 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
394 PERROR("Failed to send to socket %d\n", handle);
396 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
397 iframe_t *ctrl = (iframe_t *)buffer;
398 unsigned long *d = (unsigned long *)&ctrl->data.p;
400 ctrl->prim = PH_CONTROL | REQUEST;
401 ctrl->addr = handle | FLG_MSG_DOWN;
403 ctrl->len = sizeof(int)*2;
406 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
408 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
409 if (c1 == CMX_CONF_JOIN)
410 add_trace(trace_name, NULL, "0x%08x", trace_value);
412 add_trace(trace_name, NULL, "%d", trace_value);
416 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long handle, unsigned long c1, void *c2, int c2_len, char *trace_name, int trace_value)
419 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
420 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
421 unsigned long *d = buffer+MISDN_HEADER_LEN;
424 ctrl->prim = PH_CONTROL_REQ;
427 memcpy(d, c2, c2_len);
428 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
430 PERROR("Failed to send to socket %d\n", handle);
432 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
433 iframe_t *ctrl = (iframe_t *)buffer;
434 unsigned long *d = (unsigned long *)&ctrl->data.p;
436 ctrl->prim = PH_CONTROL | REQUEST;
437 ctrl->addr = handle | FLG_MSG_DOWN;
439 ctrl->len = sizeof(int)+c2_len;
441 memcpy(d, c2, c2_len);
442 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
444 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
445 add_trace(trace_name, NULL, "%d", trace_value);
451 * subfunction for bchannel_event
454 static int _bchannel_create(struct mISDNport *mISDNport, int i)
456 unsigned char buff[1024];
459 unsigned long on = 1;
460 struct sockadd_mISDN addr;
462 if (mISDNport->b_socket[i])
464 PERROR("Error: Socket already created for index %d\n", i);
469 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
470 if (mISDNport->b_socket[i] < 0)
472 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
476 /* set nonblocking io */
477 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
480 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
481 close(mISDNport->b_socket[i]);
482 mISDNport->b_socket[i] = -1;
486 /* bind socket to bchannel */
487 addr.family = AF_ISDN;
488 addr.dev = mISDNport->port-1;
489 addr.channel = i+1+(i>=15);
490 ret = bind(di->bchan, (struct sockaddr *)&addr, sizeof(addr));
493 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
494 close(mISDNport->b_socket[i]);
495 mISDNport->b_socket[i] = -1;
499 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
500 add_trace("channel", NULL, "%d", i+1+(i>=15));
501 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
507 if (!mISDNport->b_stid[i])
509 PERROR("Error: no stack for index %d\n", i);
512 if (mISDNport->b_addr[i])
514 PERROR("Error: stack already created for index %d\n", i);
518 /* create new layer */
519 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
520 memset(&li, 0, sizeof(li));
521 memset(&pid, 0, sizeof(pid));
524 li.st = mISDNport->b_stid[i];
525 UCPY(li.name, "B L4");
526 li.pid.layermask = ISDN_LAYER((4));
527 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
528 ret = mISDN_new_layer(mISDNdevice, &li);
532 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
535 mISDNport->b_addr[i] = li.id;
538 goto failed_new_layer;
540 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
542 /* create new stack */
543 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
544 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
545 pid.protocol[3] = ISDN_PID_L3_B_DSP;
546 pid.protocol[4] = ISDN_PID_L4_B_USER;
547 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
548 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
552 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
553 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
556 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
561 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
562 if (!mISDNport->b_addr[i])
564 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
565 add_trace("channel", NULL, "%d", i+1+(i>=15));
566 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
567 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
574 mISDNport->b_addr[i] = 0;
580 * subfunction for bchannel_event
581 * activate / deactivate request
583 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
586 struct mISDNhead act;
589 act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ;
591 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
593 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
597 /* activate bchannel */
598 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
599 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
602 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
606 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
607 add_trace("channel", NULL, "%d", i+1+(i>=15));
613 * subfunction for bchannel_event
616 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
622 handle = mISDNport->b_socket[i];
624 unsigned long handle;
626 handle = mISDNport->b_addr[i];
628 port = mISDNport->b_port[i];
631 PERROR("bchannel index i=%d not associated with a port object\n", i);
635 /* set dsp features */
636 if (port->p_m_txdata)
637 ph_control(mISDNport, port, handle, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
639 ph_control(mISDNport, port, handle, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
640 if (port->p_m_tx_gain)
641 ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
642 if (port->p_m_rx_gain)
643 ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
644 if (port->p_m_pipeline[0])
645 ph_control_block(mISDNport, port, handle, PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
647 ph_control(mISDNport, port, handle, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
649 ph_control(mISDNport, port, handle, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
651 ph_control(mISDNport, port, handle, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
653 ph_control(mISDNport, port, handle, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
654 // if (port->p_m_txmix)
655 // ph_control(mISDNport, port, handle, CMX_MIX_ON, 0, "DSP-MIX", 1);
657 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
659 ph_control_block(mISDNport, port, handle, BF_ENABLE_KEY, port->p_m_crypt_key, port->p_m_crypt_key_len, "DSP-CRYPT", port->p_m_crypt_key_len);
663 * subfunction for bchannel_event
666 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
669 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
670 add_trace("channel", NULL, "%d", i+1+(i>=15));
671 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
673 if (mISDNport->b_socket[i] > -1)
675 close(mISDNport->b_socket[i]);
676 mISDNport->b_socket[i] = -1;
679 unsigned char buff[1024];
681 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
682 add_trace("channel", NULL, "%d", i+1+(i>=15));
683 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
684 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
686 /* remove our stack only if set */
687 if (mISDNport->b_addr[i])
689 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
690 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
691 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
692 mISDNport->b_addr[i] = 0;
702 A bchannel goes through the following states in this order:
705 No one is using the bchannel.
706 It is available and not linked to Port class, nor reserved.
709 The bchannel stack is created and an activation request is sent.
710 It MAY be linked to Port class, but already unlinked due to Port class removal.
713 The bchannel is active and cofigured to the Port class needs.
714 Also it is linked to a Port class, otherwhise it would be deactivated.
716 - B_STATE_DEACTIVATING
717 The bchannel is in deactivating state, due to deactivation request.
718 It may be linked to a Port class, that likes to reactivate it.
722 After deactivating bchannel, and if not used, the bchannel becomes idle again.
724 Also the bchannel may be exported, but only if the state is or becomes idle:
727 The bchannel assignment has been sent to the remove application.
730 The bchannel assignment is acknowledged by the remote application.
733 The bchannel is re-imported by mISDN port object.
737 After re-importing bchannel, and if not used, the bchannel becomes idle again.
740 A bchannel can have the following events:
743 A bchannel is required by a Port class.
744 The bchannel shall be exported to the remote application.
747 The bchannel beomes active.
750 The bchannel is not required by Port class anymore
752 - B_EVENT_DEACTIVATED
753 The bchannel becomes inactive.
756 The bchannel is now used by remote application.
759 The bchannel is not used by remote application.
761 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
763 if an export request is receive by remote application, p_m_remote_* is set.
764 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.)
765 - set on export request from remote application (if port is assigned)
766 - set on channel use, if requested by remote application (p_m_remote_*)
767 - cleared on drop request
769 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
770 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
771 the bchannel import/export is acknowledged with stack given.
773 if exporting, b_remote_*[index] is set to the remote socket id.
774 if importing has been acknowledged. b_remote_*[index] is cleared.
779 * process bchannel events
780 * - mISDNport is a pointer to the port's structure
781 * - i is the index of the bchannel
782 * - event is the B_EVENT_* value
783 * - port is the PmISDN class pointer
785 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
787 class PmISDN *b_port = mISDNport->b_port[i];
788 int state = mISDNport->b_state[i];
789 unsigned long p_m_remote_ref = 0;
790 unsigned long p_m_remote_id = 0;
793 char *p_m_pipeline = NULL;
794 unsigned char *p_m_crypt_key = NULL;
795 int p_m_crypt_key_len = 0;
796 int p_m_crypt_key_type = 0;
798 unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
800 unsigned long portid = mISDNport->b_stid[i];
805 p_m_remote_id = b_port->p_m_remote_id;
806 p_m_remote_ref = b_port->p_m_remote_ref;
807 p_m_tx_gain = b_port->p_m_tx_gain;
808 p_m_rx_gain = b_port->p_m_rx_gain;
809 p_m_pipeline = b_port->p_m_pipeline;
810 p_m_crypt_key = b_port->p_m_crypt_key;
811 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
812 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
818 /* port must be linked in order to allow activation */
820 FATAL("bchannel must be linked to a Port class\n");
826 /* export bchannel */
827 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
828 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
829 add_trace("type", NULL, "assign");
831 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
833 add_trace("socket", "id", "%d", portid);
836 state = B_STATE_EXPORTING;
837 mISDNport->b_remote_id[i] = p_m_remote_id;
838 mISDNport->b_remote_ref[i] = p_m_remote_ref;
841 /* create stack and send activation request */
842 if (_bchannel_create(mISDNport, i))
844 _bchannel_activate(mISDNport, i, 1);
845 state = B_STATE_ACTIVATING;
850 case B_STATE_ACTIVATING:
851 case B_STATE_EXPORTING:
852 /* do nothing, because it is already activating */
855 case B_STATE_DEACTIVATING:
856 case B_STATE_IMPORTING:
857 /* do nothing, because we must wait until we can reactivate */
861 /* problems that might ocurr:
862 * B_EVENT_USE is received when channel already in use.
863 * bchannel exported, but not freed by other port
865 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
869 case B_EVENT_EXPORTREQUEST:
870 /* special case where the bchannel is requested by remote */
873 PERROR("export request without remote channel set, please correct.\n");
879 /* in case, the bchannel is exported right after seize_bchannel */
880 /* export bchannel */
881 /* p_m_remote_id is set, when this event happens. */
882 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
883 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
884 add_trace("type", NULL, "assign");
886 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
888 add_trace("socket", "id", "%d", portid);
891 state = B_STATE_EXPORTING;
892 mISDNport->b_remote_id[i] = p_m_remote_id;
893 mISDNport->b_remote_ref[i] = p_m_remote_ref;
896 case B_STATE_ACTIVATING:
897 case B_STATE_EXPORTING:
898 /* do nothing, because it is already activating */
901 case B_STATE_DEACTIVATING:
902 case B_STATE_IMPORTING:
903 /* do nothing, because we must wait until we can reactivate */
907 /* bchannel is active, so we deactivate */
908 _bchannel_activate(mISDNport, i, 0);
909 state = B_STATE_DEACTIVATING;
913 /* problems that might ocurr:
914 * ... when channel already in use.
915 * bchannel exported, but not freed by other port
917 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
921 case B_EVENT_ACTIVATED:
924 case B_STATE_ACTIVATING:
925 if (b_port && !p_m_remote_id)
927 /* bchannel is active and used by Port class, so we configure bchannel */
928 _bchannel_configure(mISDNport, i);
929 state = B_STATE_ACTIVE;
932 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
933 _bchannel_activate(mISDNport, i, 0);
934 state = B_STATE_DEACTIVATING;
939 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
943 case B_EVENT_EXPORTED:
946 case B_STATE_EXPORTING:
947 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
949 /* remote export done */
950 state = B_STATE_REMOTE;
953 /* bchannel is now exported, but we need bchannel back
954 * OR bchannel is not used anymore
955 * OR bchannel has been exported to an obsolete ref,
956 * so reimport, to later export to new remote */
957 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
958 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
959 add_trace("type", NULL, "remove");
961 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
963 add_trace("socket", "id", "%d", portid);
966 state = B_STATE_IMPORTING;
971 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
977 FATAL("bchannel must be linked to a Port class\n");
981 /* bchannel is idle due to an error, so we do nothing */
984 case B_STATE_ACTIVATING:
985 case B_STATE_EXPORTING:
986 /* do nothing because we must wait until bchanenl is active before deactivating */
990 /* bchannel is active, so we deactivate */
991 _bchannel_activate(mISDNport, i, 0);
992 state = B_STATE_DEACTIVATING;
996 /* bchannel is exported, so we re-import */
997 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
998 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
999 add_trace("type", NULL, "remove");
1001 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1003 add_trace("socket", "id", "%d", portid);
1006 state = B_STATE_IMPORTING;
1009 case B_STATE_DEACTIVATING:
1010 case B_STATE_IMPORTING:
1011 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
1015 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1019 case B_EVENT_DEACTIVATED:
1023 /* ignore due to deactivation confirm after unloading */
1026 case B_STATE_DEACTIVATING:
1027 _bchannel_destroy(mISDNport, i);
1028 state = B_STATE_IDLE;
1031 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
1034 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
1035 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1036 add_trace("type", NULL, "assign");
1038 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1040 add_trace("socket", "id", "%d", portid);
1043 state = B_STATE_EXPORTING;
1044 mISDNport->b_remote_id[i] = p_m_remote_id;
1045 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1048 if (_bchannel_create(mISDNport, i))
1050 _bchannel_activate(mISDNport, i, 1);
1051 state = B_STATE_ACTIVATING;
1058 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1062 case B_EVENT_IMPORTED:
1065 case B_STATE_IMPORTING:
1066 state = B_STATE_IDLE;
1067 mISDNport->b_remote_id[i] = 0;
1068 mISDNport->b_remote_ref[i] = 0;
1071 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
1074 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
1075 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1076 add_trace("type", NULL, "assign");
1078 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1080 add_trace("socket", "id", "%d", portid);
1083 state = B_STATE_EXPORTING;
1084 mISDNport->b_remote_id[i] = p_m_remote_id;
1085 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1088 if (_bchannel_create(mISDNport, i))
1090 _bchannel_activate(mISDNport, i, 1);
1091 state = B_STATE_ACTIVATING;
1098 /* ignore, because not assigned */
1104 PERROR("Illegal event %d, please correct.\n", event);
1107 mISDNport->b_state[i] = state;
1114 * check for available channel and reserve+set it.
1115 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
1116 * give exclusiv flag
1117 * returns -(cause value) or x = channel x or 0 = no channel
1118 * NOTE: no activation is done here
1120 int PmISDN::seize_bchannel(int channel, int exclusive)
1124 /* the channel is what we have */
1125 if (p_m_b_channel == channel)
1128 /* if channel already in use, release it */
1133 if (channel==CHANNEL_NO || channel==0)
1136 /* is channel in range ? */
1138 || (channel>p_m_mISDNport->b_num && channel<16)
1139 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1140 return(-6); /* channel unacceptable */
1142 /* request exclusive channel */
1143 if (exclusive && channel>0)
1145 i = channel-1-(channel>16);
1146 if (p_m_mISDNport->b_port[i])
1147 return(-44); /* requested channel not available */
1151 /* ask for channel */
1154 i = channel-1-(channel>16);
1155 if (p_m_mISDNport->b_port[i] == NULL)
1159 /* search for channel */
1161 while(i < p_m_mISDNport->b_num)
1163 if (!p_m_mISDNport->b_port[i])
1165 channel = i+1+(i>=15);
1170 return(-34); /* no free channel */
1173 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1176 p_m_mISDNport->b_port[i] = this;
1178 p_m_b_channel = channel;
1179 p_m_b_exclusive = exclusive;
1181 /* reserve channel */
1185 p_m_mISDNport->b_reserved++;
1192 * drop reserved channel and unset it.
1193 * deactivation is also done
1195 void PmISDN::drop_bchannel(void)
1197 /* unreserve channel */
1199 p_m_mISDNport->b_reserved--;
1203 if (p_m_b_index < 0)
1208 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1210 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1211 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1212 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1215 p_m_b_exclusive = 0;
1218 /* process bchannel export/import message from join */
1219 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long handle)
1221 class Endpoint *epoint;
1223 class PmISDN *isdnport;
1224 struct mISDNport *mISDNport;
1229 case BCHANNEL_REQUEST:
1230 /* find the port object for the join object ref */
1231 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1233 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1236 if (!epoint->ep_portlist)
1238 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1241 if (epoint->ep_portlist->next)
1243 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);
1245 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1247 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1250 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1252 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1254 isdnport = (class PmISDN *)port;
1257 if (isdnport->p_m_remote_id)
1259 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1262 mISDNport = isdnport->p_m_mISDNport;
1263 i = isdnport->p_m_b_index;
1264 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1265 add_trace("type", NULL, "export request");
1266 isdnport->p_m_remote_ref = joinremote->j_serial;
1267 isdnport->p_m_remote_id = joinremote->j_remote_id;
1268 if (mISDNport && i>=0)
1270 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1275 case BCHANNEL_ASSIGN_ACK:
1276 case BCHANNEL_REMOVE_ACK:
1277 /* find mISDNport for stack ID */
1278 mISDNport = mISDNport_first;
1282 ii = mISDNport->b_num;
1286 if (mISDNport->b_socket[i] == handle)
1288 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1295 mISDNport = mISDNport->next;
1299 PERROR("received assign/remove ack for handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1302 /* mISDNport may now be set or NULL */
1305 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1306 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1307 if (mISDNport && i>=0)
1308 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1312 PERROR("received wrong bchannel message type %d from remote\n", type);
1320 audio transmission procedure:
1321 -----------------------------
1324 three sources of audio transmission:
1325 - crypto-data high priority
1326 - tones high priority (also high)
1327 - remote-data low priority
1330 a variable that temporarily shows the number of samples elapsed since last transmission process.
1331 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1334 a variable that is increased whenever data is transmitted.
1335 it is decreased while time elapses. it stores the number of samples that
1336 are currently loaded to dsp module.
1337 since clock in dsp module is the same clock for user space process, these
1341 there are two levels:
1342 ISDN_LOAD will give the load that have to be kept in dsp.
1343 ISDN_MAXLOAD will give the maximum load before dropping.
1345 * procedure for low priority data
1346 see txfromup() for procedure
1347 in short: remote data is ignored during high priority tones
1349 * procedure for high priority data
1350 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1351 if no more data is available, load becomes empty again.
1354 0 ISDN_LOAD ISDN_MAXLOAD
1355 +--------------------+----------------------+
1357 +--------------------+----------------------+
1359 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1360 0 ISDN_LOAD ISDN_MAXLOAD
1361 +--------------------+----------------------+
1362 |TTTTTTTTTTTTTTTTTTTT| |
1363 +--------------------+----------------------+
1365 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1366 0 ISDN_LOAD ISDN_MAXLOAD
1367 +--------------------+----------------------+
1368 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1369 +--------------------+----------------------+
1372 int PmISDN::handler(void)
1374 struct message *message;
1378 if ((ret = Port::handler()))
1382 if (p_m_last_tv_sec)
1384 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1385 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1388 /* set clock of first process ever in this instance */
1389 p_m_last_tv_sec = now_tv.tv_sec;
1390 p_m_last_tv_msec = now_tv.tv_usec/1000;
1392 /* process only if we have a minimum of samples, to make packets not too small */
1393 if (elapsed >= ISDN_TRANSMIT)
1395 /* set clock of last process! */
1396 p_m_last_tv_sec = now_tv.tv_sec;
1397 p_m_last_tv_msec = now_tv.tv_usec/1000;
1400 if (elapsed < p_m_load)
1401 p_m_load -= elapsed;
1405 /* to send data, tone must be active OR crypt messages must be on */
1406 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1407 && (p_m_load < ISDN_LOAD)
1408 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1410 int tosend = ISDN_LOAD - p_m_load, length;
1412 unsigned char buf[MISDN_HEADER_LEN+tosend];
1413 struct mISDNhead *frm = (struct mISDNhead *)buf;
1414 unsigned long *d = buf+MISDN_HEADER_LEN;
1416 unsigned char buf[mISDN_HEADER_LEN+tosend];
1417 iframe_t *frm = (iframe_t *)buf;
1418 unsigned char *p = buf+mISDN_HEADER_LEN;
1421 /* copy crypto loops */
1422 while (p_m_crypt_msg_loops && tosend)
1424 /* how much do we have to send */
1425 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1428 if (length > tosend)
1431 /* copy message (part) to buffer */
1432 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1435 p_m_crypt_msg_current += length;
1436 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1439 p_m_crypt_msg_current = 0;
1440 p_m_crypt_msg_loops--;
1441 // puts("eine loop weniger");
1449 if (p_tone_name[0] && tosend)
1451 tosend -= read_audio(p, tosend);
1456 frm->prim = DL_DATA_REQ;
1458 ret = sendto(handle, buffer, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1460 PERROR("Failed to send to socket %d\n", handle);
1462 frm->prim = DL_DATA | REQUEST;
1463 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1465 frm->len = ISDN_LOAD - p_m_load - tosend;
1468 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1469 p_m_load += frm->len;
1473 // NOTE: deletion is done by the child class
1475 /* handle timeouts */
1478 if (p_m_timer+p_m_timeout < now_d)
1480 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1482 /* send timeout to endpoint */
1483 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1484 message->param.state = p_state;
1485 message_put(message);
1490 return(0); /* nothing done */
1495 * whenever we get audio data from bchannel, we process it here
1498 void PmISDN::bchannel_receive(mISDNhead *hh, unsigned char *data, int len)
1500 unsigned long cont = *((unsigned long *)data);
1502 void PmISDN::bchannel_receive(iframe_t *frm)
1505 unsigned long cont = *((unsigned long *)&frm->data.p);
1506 unsigned char *data =(unsigned char *)&frm->data.p;
1508 unsigned char *data_temp;
1509 unsigned long length_temp;
1510 struct message *message;
1515 if (hh->prim == PH_CONTROL_IND)
1517 if (frm->prim == (PH_CONTROL | INDICATION))
1522 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1525 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1527 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1528 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1530 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1531 message->param.dtmf = cont & DTMF_TONE_MASK;
1532 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1533 message_put(message);
1539 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1540 add_trace("DSP-CRYPT", NULL, "error");
1542 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1543 message->param.crypt.type = CC_ERROR_IND;
1544 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1545 message_put(message);
1549 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1550 add_trace("DSP-CRYPT", NULL, "ok");
1552 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1553 message->param.crypt.type = CC_ACTBF_CONF;
1554 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1555 message_put(message);
1559 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1560 add_trace("unknown", NULL, "0x%x", cont);
1566 if (hh->prim == PH_SIGNAL_IND)
1568 if (frm->prim == (PH_SIGNAL | INDICATION))
1576 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1577 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1580 /* see below (same condition) */
1581 if (p_state!=PORT_STATE_CONNECT
1582 && !p_m_mISDNport->tones)
1584 // printf(".");fflush(stdout);return;
1586 record(data, len, 1); // from up
1590 chan_trace_header(p_m_mISDNport, this, "BCHANNEL signal", DIRECTION_IN);
1591 add_trace("unknown", NULL, "0x%x", frm->dinfo);
1597 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1599 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1601 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1603 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1607 /* calls will not process any audio data unless
1608 * the call is connected OR interface features audio during call setup.
1610 //printf("%d -> %d prim=%x joindata=%d tones=%d\n", p_serial, ACTIVE_EPOINT(p_epointlist), frm->prim, p_m_joindata, p_m_mISDNport->earlyb);
1611 #ifndef DEBUG_COREBRIDGE
1612 if (p_state!=PORT_STATE_CONNECT
1613 && !p_m_mISDNport->tones)
1617 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1620 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1626 record(data, len, 0); // from down
1628 /* randomize and listen to crypt message if enabled */
1629 if (p_m_crypt_listen)
1631 /* the noisy randomizer */
1635 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1637 cryptman_listen_bch(data, len);
1642 /* send data to epoint */
1643 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1649 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1650 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1651 memcpy(message->param.data.data, data_temp, message->param.data.len);
1652 message_put(message);
1653 if (length_temp <= sizeof(message->param.data.data))
1655 data_temp += sizeof(message->param.data.data);
1656 length_temp -= sizeof(message->param.data.data);
1665 void PmISDN::set_echotest(int echo)
1667 if (p_m_echo != echo)
1670 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1672 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1674 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_echo?CMX_ECHO_ON:CMX_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1676 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_echo?CMX_ECHO_ON:CMX_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1684 void PmISDN::set_tone(char *dir, char *tone)
1690 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1697 /* check if we NOT really have to use a dsp-tone */
1698 if (!options.dsptones)
1702 if (p_m_b_index >= 0)
1703 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1705 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1707 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1709 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1713 Port::set_tone(dir, tone);
1719 /* now we USE dsp-tone, convert name */
1720 else if (!strcmp(tone, "dialtone"))
1722 switch(options.dsptones) {
1723 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1724 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1725 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1727 } else if (!strcmp(tone, "dialpbx"))
1729 switch(options.dsptones) {
1730 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1731 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1732 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1734 } else if (!strcmp(tone, "ringing"))
1736 switch(options.dsptones) {
1737 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1738 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1739 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1741 } else if (!strcmp(tone, "ringpbx"))
1743 switch(options.dsptones) {
1744 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1745 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1746 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1748 } else if (!strcmp(tone, "busy"))
1751 switch(options.dsptones) {
1752 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1753 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1754 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1756 } else if (!strcmp(tone, "release"))
1759 switch(options.dsptones) {
1760 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1761 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1762 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1764 } else if (!strcmp(tone, "cause_10"))
1766 else if (!strcmp(tone, "cause_11"))
1768 else if (!strcmp(tone, "cause_22"))
1770 switch(options.dsptones) {
1771 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1772 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1773 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1775 } else if (!strncmp(tone, "cause_", 6))
1776 id = TONE_SPECIAL_INFO;
1780 /* if we have a tone that is not supported by dsp */
1781 if (id==TONE_OFF && tone[0])
1789 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1790 if (p_m_b_index >= 0)
1791 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1793 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_tone?TONE_PATT_ON:TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1795 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_tone?TONE_PATT_ON:TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1798 /* turn user-space tones off in cases of no tone OR dsp tone */
1799 Port::set_tone("",NULL);
1803 /* MESSAGE_mISDNSIGNAL */
1804 //extern struct message *dddebug;
1805 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1807 switch(param->mISDNsignal.message)
1809 case mISDNSIGNAL_VOLUME:
1810 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1812 p_m_tx_gain = param->mISDNsignal.tx_gain;
1813 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1814 if (p_m_b_index >= 0)
1815 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1817 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1819 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1822 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1823 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1825 p_m_rx_gain = param->mISDNsignal.rx_gain;
1826 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1827 if (p_m_b_index >= 0)
1828 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1830 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1832 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1835 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1838 case mISDNSIGNAL_CONF:
1839 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1840 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1841 if (p_m_conf != param->mISDNsignal.conf)
1843 p_m_conf = param->mISDNsignal.conf;
1844 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1845 if (p_m_b_index >= 0)
1846 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1848 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], (p_m_conf)?CMX_CONF_JOIN:CMX_CONF_SPLIT, p_m_conf, "DSP-CONF", p_m_conf);
1850 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], (p_m_conf)?CMX_CONF_JOIN:CMX_CONF_SPLIT, p_m_conf, "DSP-CONF", p_m_conf);
1853 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1854 /* we must set, even if currently tone forbids conf */
1855 p_m_conf = param->mISDNsignal.conf;
1856 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1859 case mISDNSIGNAL_JOINDATA:
1860 if (p_m_joindata != param->mISDNsignal.joindata)
1862 p_m_joindata = param->mISDNsignal.joindata;
1863 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1865 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1868 case mISDNSIGNAL_DELAY:
1869 if (p_m_delay != param->mISDNsignal.delay)
1871 p_m_delay = param->mISDNsignal.delay;
1872 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1873 if (p_m_b_index >= 0)
1874 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1876 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_delay?CMX_DELAY:CMX_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
1878 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_delay?CMX_DELAY:CMX_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
1881 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1885 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1890 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1892 struct message *message;
1894 switch(param->crypt.type)
1896 case CC_ACTBF_REQ: /* activate blowfish */
1898 p_m_crypt_key_len = param->crypt.len;
1899 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1901 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1902 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1903 message->param.crypt.type = CC_ERROR_IND;
1904 message_put(message);
1907 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1909 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1910 if (p_m_b_index >= 0)
1911 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1913 ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_crypt?BF_ENABLE_KEY:BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len);
1915 ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_crypt?BF_ENABLE_KEY:BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len);
1919 case CC_DACT_REQ: /* deactivate session encryption */
1924 case CR_LISTEN_REQ: /* start listening to messages */
1925 p_m_crypt_listen = 1;
1926 p_m_crypt_listen_state = 0;
1929 case CR_UNLISTEN_REQ: /* stop listening to messages */
1930 p_m_crypt_listen = 0;
1933 case CR_MESSAGE_REQ: /* send message */
1934 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1935 if (!p_m_crypt_msg_len)
1937 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1940 p_m_crypt_msg_current = 0; /* reset */
1941 p_m_crypt_msg_loops = 6; /* enable */
1943 /* disable txmix, or we get corrupt data due to audio process */
1944 if (p_m_txmix && p_m_b_index>=0)
1946 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1948 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1950 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1957 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1963 * endpoint sends messages to the port
1965 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1967 if (Port::message_epoint(epoint_id, message_id, param))
1972 case MESSAGE_DATA: /* tx-data from upper layer */
1973 txfromup(param->data.data, param->data.len);
1976 case MESSAGE_mISDNSIGNAL: /* user command */
1977 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1978 message_mISDNsignal(epoint_id, message_id, param);
1981 case MESSAGE_CRYPT: /* crypt control command */
1982 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1983 message_crypt(epoint_id, message_id, param);
1992 * main loop for processing messages from mISDN
1995 int mISDN_handler(void)
1998 struct mISDNport *mISDNport;
1999 class PmISDN *isdnport;
2001 char buffer[2048+MISDN_HEADER_LEN];
2002 struct mISDNhead *hh = (struct mISDNhead *)buffer;
2004 /* process all ports */
2005 mISDNport = mISDNport_first;
2008 /* process all bchannels */
2010 while(i < mISDNport->b_num)
2012 /* handle port of bchannel */
2013 isdnport=mISDNport->b_port[i];
2016 /* call bridges in user space OR crypto OR recording */
2017 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2019 /* rx IS required */
2020 if (isdnport->p_m_rxoff)
2023 isdnport->p_m_rxoff = 0;
2024 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2025 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2026 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2031 /* rx NOT required */
2032 if (!isdnport->p_m_rxoff)
2035 isdnport->p_m_rxoff = 1;
2036 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2037 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2038 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2043 if (isdnport->p_record)
2045 /* txdata IS required */
2046 if (!isdnport->p_m_txdata)
2049 isdnport->p_m_txdata = 1;
2050 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2051 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2052 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2057 /* txdata NOT required */
2058 if (isdnport->p_m_txdata)
2061 isdnport->p_m_txdata = 0;
2062 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2063 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2064 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2070 /* handle message from bchannel */
2071 if (mISDNport->b_stack[i] > -1)
2073 ret = recv(mISDNport->b_stack[i], buffer, sizeof(buffer), 0);
2074 if (ret >= MISDN_HEADER_LEN)
2079 /* we don't care about confirms, we use rx data to sync tx */
2084 /* we receive audio data, we respond to it AND we send tones */
2088 case PH_CONTROL_IND:
2089 if (mISDNport->b_port[i])
2090 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2092 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_stack[i]);
2095 case PH_ACTIVATE_IND:
2096 case DL_ESTABLISH_IND:
2097 case PH_ACTIVATE_CONF:
2098 case DL_ESTABLISH_CONF:
2099 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
2100 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2103 case PH_DEACTIVATE_IND:
2104 case DL_RELEASE_IND:
2105 case PH_DEACTIVATE_CONF:
2106 case DL_RELEASE_CONF:
2107 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
2108 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2112 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], msg->len);
2116 if (ret < 0 && errno != EWOULDBLOCK)
2117 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
2124 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2126 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2127 mISDNport->l1timeout = 0;
2130 /* layer 2 establish timer */
2131 if (mISDNport->l2establish)
2133 if (now-mISDNport->l2establish > 5)
2136 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2137 mISDNport->ml3->to_layer2(mISDNport->ml3, DL_ESTABLISH_REQ);
2138 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_REQ, DIRECTION_OUT);
2145 mISDNport = mISDNport->next;
2148 /* if we received at least one b-frame, we will return 1 */
2152 int mISDN_handler(void)
2155 struct mISDNport *mISDNport;
2156 class PmISDN *isdnport;
2161 mISDNuser_head_t *hh;
2164 /* the que avoids loopbacks when replying to stack after receiving
2166 mISDNport = mISDNport_first;
2169 /* process turning on/off rx */
2171 while(i < mISDNport->b_num)
2173 isdnport=mISDNport->b_port[i];
2176 /* call bridges in user space OR crypto OR recording */
2177 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2179 /* rx IS required */
2180 if (isdnport->p_m_rxoff)
2183 isdnport->p_m_rxoff = 0;
2184 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2185 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2186 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2191 /* rx NOT required */
2192 if (!isdnport->p_m_rxoff)
2195 isdnport->p_m_rxoff = 1;
2196 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2197 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2198 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2203 if (isdnport->p_record)
2205 /* txdata IS required */
2206 if (!isdnport->p_m_txdata)
2209 isdnport->p_m_txdata = 1;
2210 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2211 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2212 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2217 /* txdata NOT required */
2218 if (isdnport->p_m_txdata)
2221 isdnport->p_m_txdata = 0;
2222 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2223 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2224 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2232 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2234 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2235 mISDNport->l1timeout = 0;
2238 if (mISDNport->l2establish)
2240 if (now-mISDNport->l2establish > 5)
2242 if (mISDNport->ntmode)
2244 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2245 time(&mISDNport->l2establish);
2247 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2248 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2253 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2254 time(&mISDNport->l2establish);
2256 act.prim = DL_ESTABLISH | REQUEST;
2257 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2260 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2262 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
2267 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2269 if (mISDNport->ntmode)
2271 hh = (mISDNuser_head_t *)dmsg->data;
2272 PDEBUG(DEBUG_ISDN, "sending queued NT l3-down-message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", hh->prim, hh->dinfo, dmsg->len);
2273 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2277 frm = (iframe_t *)dmsg->data;
2278 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2279 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2280 PDEBUG(DEBUG_ISDN, "sending queued TE l3-down-message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", frm->prim, frm->dinfo, dmsg->len);
2281 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2286 mISDNport = mISDNport->next;
2289 /* no device, no read */
2290 if (mISDNdevice < 0)
2293 /* get message from kernel */
2294 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2296 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2300 if (errno == EAGAIN)
2302 FATAL("Failed to do mISDN_read()\n");
2307 // printf("%s: ERROR: mISDN_read() returns nothing\n");
2311 frm = (iframe_t *)msg->data;
2316 case MGR_DELLAYER | CONFIRM:
2317 case MGR_INITTIMER | CONFIRM:
2318 case MGR_ADDTIMER | CONFIRM:
2319 case MGR_DELTIMER | CONFIRM:
2320 case MGR_REMOVETIMER | CONFIRM:
2325 /* handle timer events from mISDN for NT-stack
2326 * note: they do not associate with a stack */
2327 if (frm->prim == (MGR_TIMER | INDICATION))
2331 /* find mISDNport */
2332 mISDNport = mISDNport_first;
2336 if (mISDNport->ntmode)
2338 it = mISDNport->nst.tlist;
2342 if (it->id == (int)frm->addr)
2349 mISDNport = mISDNport->next;
2353 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2354 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2356 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2357 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2358 ret = it->function(it->data);
2361 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2366 /* find the mISDNport that belongs to the stack */
2367 mISDNport = mISDNport_first;
2370 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2372 mISDNport = mISDNport->next;
2376 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2381 if (!(frm->addr&FLG_CHILD_STACK))
2386 case MGR_SHORTSTATUS | INDICATION:
2387 case MGR_SHORTSTATUS | CONFIRM:
2388 switch(frm->dinfo) {
2389 case SSTATUS_L1_ACTIVATED:
2390 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2393 case SSTATUS_L1_DEACTIVATED:
2394 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2397 case SSTATUS_L2_ESTABLISHED:
2398 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
2401 case SSTATUS_L2_RELEASED:
2402 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
2408 case PH_ACTIVATE | CONFIRM:
2409 case PH_ACTIVATE | INDICATION:
2410 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2412 if (mISDNport->ntmode)
2414 mISDNport->l1link = 1;
2415 setup_queue(mISDNport, 1);
2419 mISDNport->l1link = 1;
2420 setup_queue(mISDNport, 1);
2423 case PH_DEACTIVATE | CONFIRM:
2424 case PH_DEACTIVATE | INDICATION:
2425 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2427 if (mISDNport->ntmode)
2429 mISDNport->l1link = 0;
2430 setup_queue(mISDNport, 0);
2434 mISDNport->l1link = 0;
2435 setup_queue(mISDNport, 0);
2438 case PH_CONTROL | CONFIRM:
2439 case PH_CONTROL | INDICATION:
2440 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2443 case DL_ESTABLISH | INDICATION:
2444 case DL_ESTABLISH | CONFIRM:
2445 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2447 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2449 if (mISDNport->l2establish)
2451 mISDNport->l2establish = 0;
2452 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2454 mISDNport->l2link = 1;
2457 case DL_RELEASE | INDICATION:
2458 case DL_RELEASE | CONFIRM:
2459 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2461 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2463 mISDNport->l2link = 0;
2466 time(&mISDNport->l2establish);
2467 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2473 PDEBUG(DEBUG_STACK, "GOT d-msg from %s port %d prim 0x%x dinfo 0x%x addr 0x%x\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, frm->prim, frm->dinfo, frm->addr);
2474 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2476 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2479 if (mISDNport->ntmode)
2481 /* l1-data enters the nt-mode library */
2482 nst = &mISDNport->nst;
2483 if (nst->l1_l2(nst, msg))
2488 /* l3-data is sent to pbx */
2489 if (stack2manager_te(mISDNport, msg))
2500 /* we don't care about confirms, we use rx data to sync tx */
2501 case PH_DATA | CONFIRM:
2502 case DL_DATA | CONFIRM:
2505 /* we receive audio data, we respond to it AND we send tones */
2506 case PH_DATA | INDICATION:
2507 case DL_DATA | INDICATION:
2508 case PH_CONTROL | INDICATION:
2509 case PH_SIGNAL | INDICATION:
2511 while(i < mISDNport->b_num)
2513 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2517 if (i == mISDNport->b_num)
2519 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2522 if (mISDNport->b_port[i])
2524 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2525 mISDNport->b_port[i]->bchannel_receive(frm);
2527 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2530 case PH_ACTIVATE | INDICATION:
2531 case DL_ESTABLISH | INDICATION:
2532 case PH_ACTIVATE | CONFIRM:
2533 case DL_ESTABLISH | CONFIRM:
2534 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2536 while(i < mISDNport->b_num)
2538 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2542 if (i == mISDNport->b_num)
2544 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2547 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2550 case PH_DEACTIVATE | INDICATION:
2551 case DL_RELEASE | INDICATION:
2552 case PH_DEACTIVATE | CONFIRM:
2553 case DL_RELEASE | CONFIRM:
2554 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2556 while(i < mISDNport->b_num)
2558 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2562 if (i == mISDNport->b_num)
2564 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2567 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2571 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2582 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2584 struct mISDNport *mISDNport = ml3->private;
2586 if (cmd == MT_ASSIGN)
2592 achtung MT_ASSIGN kommt hier an
2598 case MGR_SHORTSTATUS_IND:
2599 case MGR_SHORTSTATUS_CONF:
2600 switch(frm->dinfo) {
2601 case SSTATUS_L1_ACTIVATED:
2602 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE_IND, DIRECTION_IN);
2605 case SSTATUS_L1_DEACTIVATED:
2606 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE_IND, DIRECTION_IN);
2609 case SSTATUS_L2_ESTABLISHED:
2610 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_IND, DIRECTION_IN);
2613 case SSTATUS_L2_RELEASED:
2614 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE_IND, DIRECTION_IN);
2620 case PH_ACTIVATE_CONF:
2621 case PH_ACTIVATE_IND:
2622 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2625 mISDNport->l1link = 1;
2627 if (mISDNport->ntmode)
2628 setup_queue(mISDNport, 1);
2632 case PH_DEACTIVATE | CONFIRM:
2633 case PH_DEACTIVATE | INDICATION:
2634 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2637 mISDNport->l1link = 0;
2638 raus mit der setup-queue, da dies im stack geschieht
2640 if (mISDNport->ntmode)
2641 setup_queue(mISDNport, 0);
2645 case PH_CONTROL_CONFIRM:
2646 case PH_CONTROL_INDICATION:
2647 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2650 case DL_ESTABLISH_IND:
2651 case DL_ESTABLISH_CONF:
2652 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2654 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2656 if (mISDNport->l2establish)
2658 mISDNport->l2establish = 0;
2659 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2661 mISDNport->l2link = 1;
2664 case DL_RELEASE_IND:
2665 case DL_RELEASE_CONF:
2666 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2669 mISDNport->l2link = 0;
2672 time(&mISDNport->l2establish);
2673 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2678 /* l3-data is sent to LCR */
2679 message_from_mlayer3(mISDNport, cmd, pid, l3m);
2695 * global function to add a new card (port)
2697 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, int force_nt, struct interface *interface)
2700 unsigned char buff[1025];
2701 iframe_t *frm = (iframe_t *)buff;
2702 struct mISDNport *mISDNport, **mISDNportp;
2704 int pri, bri, ports;
2707 struct mlayer3 *ml3;
2708 struct mISDN_devinfo devinfo;
2710 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2713 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2717 // interface_info_t ii;
2721 stack_info_t *stinf;
2723 /* query port's requirements */
2724 cnt = mISDN_get_stack_count(mISDNdevice);
2729 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2732 if (port>cnt || port<1)
2734 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2738 pri = bri = ports = nt = te = 0;
2740 devinfo.id = port - 1;
2741 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
2744 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2747 /* output the port info */
2748 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2753 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2759 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2766 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2773 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2780 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2786 if (force_nt && !nt)
2788 PERROR_RUNTIME("Port %d does not support NT-mode.\n", port);
2793 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2796 if (pots && !bri && !pri)
2798 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2803 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2808 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2811 /* force nt, by turning off TE */
2814 /* if TE an NT is supported (and not forced to NT), turn off NT */
2818 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
2821 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
2824 stinf = (stack_info_t *)&frm->data.p;
2825 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2827 case ISDN_PID_L0_TE_S0:
2828 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
2830 case ISDN_PID_L0_NT_S0:
2831 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
2834 case ISDN_PID_L0_TE_E1:
2835 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
2838 case ISDN_PID_L0_NT_E1:
2839 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
2844 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
2850 if (stinf->pid.protocol[1] == 0)
2852 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
2855 if (stinf->pid.protocol[2])
2857 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
2864 if (stinf->pid.protocol[1] == 0)
2866 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
2869 if (stinf->pid.protocol[2] == 0)
2871 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
2874 if (stinf->pid.protocol[3] == 0)
2876 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
2880 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2882 case ISDN_PID_L3_DSS1USER:
2886 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
2890 if (stinf->pid.protocol[4])
2892 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
2898 /* add mISDNport structure */
2899 mISDNportp = &mISDNport_first;
2901 mISDNportp = &((*mISDNportp)->next);
2902 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2904 *mISDNportp = mISDNport;
2906 /* allocate ressources of port */
2909 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NETWORK;
2914 prop |= FLG_FORCE_PTMP;
2915 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_dchannel, mISDNport);
2916 if (!mISDNport->ml3)
2918 PERROR_RUNTIME("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2923 /* if ntmode, establish L1 to send the tei removal during start */
2924 if (mISDNport->ntmode)
2928 act.prim = PH_ACTIVATE | REQUEST;
2929 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2930 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2933 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2934 usleep(10000); /* to be sure, that l1 is up */
2938 SCPY(mISDNport->name, devinfo.name);
2939 mISDNport->b_num = devinfo.nrbchan;
2941 msg_queue_init(&mISDNport->downqueue);
2942 mISDNport->d_stid = stinf->id;
2943 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
2944 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
2946 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
2950 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
2955 /* create layer intance */
2956 memset(&li, 0, sizeof(li));
2957 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
2960 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
2961 li.pid.layermask = ISDN_LAYER((nt?2:4));
2962 li.st = mISDNport->d_stid;
2963 ret = mISDN_new_layer(mISDNdevice, &li);
2966 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
2968 mISDNport_close(mISDNport);
2971 mISDNport->upper_id = li.id;
2972 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
2975 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
2978 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
2979 if (mISDNport->lower_id < 0)
2981 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
2984 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
2985 if (mISDNport->upper_id < 0)
2987 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2990 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
2992 /* if ntmode, establish L1 to send the tei removal during start */
2993 if (mISDNport->ntmode)
2997 act.prim = PH_ACTIVATE | REQUEST;
2998 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2999 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3002 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3003 usleep(10000); /* to be sure, that l1 is up */
3006 /* create nst (nt-mode only) */
3009 mgr = &mISDNport->mgr;
3010 nst = &mISDNport->nst;
3015 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
3016 nst->device = mISDNdevice;
3018 nst->d_stid = mISDNport->d_stid;
3020 nst->feature = FEATURE_NET_HOLD;
3022 nst->feature |= FEATURE_NET_PTP;
3024 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
3027 while(i < mISDNport->b_num)
3029 nst->b_stid[i] = mISDNport->b_stid[i];
3033 nst->l1_id = mISDNport->lower_id;
3034 nst->l2_id = mISDNport->upper_id;
3037 msg_queue_init(&nst->down_queue);
3043 mISDNport->b_num = stinf->childcnt;
3045 mISDNport->portnum = port;
3046 mISDNport->ntmode = nt;
3047 mISDNport->pri = pri;
3048 mISDNport->ptp = ptp;
3049 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
3051 while(i < mISDNport->b_num)
3053 mISDNport->b_state[i] = B_STATE_IDLE;
3055 mISDNport->b_socket = -1;
3057 mISDNport->b_stid[i] = stinf->child[i];
3058 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
3063 /* if te-mode, query state link */
3064 if (!mISDNport->ntmode)
3068 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
3069 act.prim = MGR_SHORTSTATUS | REQUEST;
3070 act.addr = mISDNport->upper_id | MSG_BROADCAST;
3071 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
3073 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3075 /* if ptp AND te-mode, pull up the link */
3076 if (mISDNport->ptp && !mISDNport->ntmode)
3080 act.prim = DL_ESTABLISH | REQUEST;
3081 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
3084 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3086 /* if ptp AND nt-mode, pull up the link */
3087 if (mISDNport->ptp && mISDNport->ntmode)
3091 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
3092 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
3095 /* initially, we assume that the link is down, exept for nt-ptmp */
3096 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
3098 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
3100 start_trace(mISDNport->portnum,
3108 add_trace("channels", NULL, "%d", mISDNport->b_num);
3115 * function to free ALL cards (ports)
3117 void mISDNport_close_all(void)
3119 /* free all ports */
3120 while(mISDNport_first)
3121 mISDNport_close(mISDNport_first);
3125 * free only one port
3127 void mISDNport_close(struct mISDNport *mISDNport)
3129 struct mISDNport **mISDNportp;
3131 class PmISDN *isdnport;
3133 unsigned char buf[32];
3136 /* remove all port instance that are linked to this mISDNport */
3140 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
3142 isdnport = (class PmISDN *)port;
3143 if (isdnport->p_m_mISDNport)
3145 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
3152 /* only if we are already part of interface */
3153 if (mISDNport->ifport)
3155 start_trace(mISDNport->portnum,
3156 mISDNport->ifport->interface,
3166 /* free bchannels */
3168 while(i < mISDNport->b_num)
3170 if (mISDNport->b_addr[i])
3172 _bchannel_destroy(mISDNport, i);
3173 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
3179 close_layer3(mISDNport->ml3);
3181 /* free ressources of port */
3182 msg_queue_purge(&mISDNport->downqueue);
3185 if (mISDNport->ntmode)
3187 nst = &mISDNport->nst;
3188 if (nst->manager) /* to see if initialized */
3190 PDEBUG(DEBUG_STACK, "the following messages are ok: one L3 process always exists (broadcast process) and some L2 instances (broadcast + current telephone's instances)\n");
3191 cleanup_Isdnl3(nst);
3192 cleanup_Isdnl2(nst);
3195 msg_queue_purge(&nst->down_queue);
3196 if (nst->phd_down_msg)
3197 FREE(nst->phd_down_msg, 0);
3201 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
3202 if (mISDNport->d_stid)
3204 if (mISDNport->upper_id)
3205 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
3209 /* remove from list */
3210 mISDNportp = &mISDNport_first;
3213 if (*mISDNportp == mISDNport)
3215 *mISDNportp = (*mISDNportp)->next;
3219 mISDNportp = &((*mISDNportp)->next);
3223 FATAL("mISDNport not in list\n");
3225 FREE(mISDNport, sizeof(struct mISDNport));
3232 * global function to show all available isdn ports
3234 void mISDN_port_info(void)
3238 int useable, nt, te, pri, bri, pots;
3239 unsigned char buff[1025];
3240 iframe_t *frm = (iframe_t *)buff;
3242 struct mISDN_devinfo devinfo;
3246 socket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
3249 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
3253 /* get number of stacks */
3255 ret = ioctl(socket, IMGETCOUNT, &ii);
3258 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
3262 stack_info_t *stinf;
3266 if ((device = mISDN_open()) < 0)
3268 fprintf(stderr, "Cannot open mISDN device ret=%d errno=%d (%s) Check for mISDN modules!\nAlso did you create \"/dev/mISDN\"? Do: \"mknod /dev/mISDN c 46 0\"\n", device, errno, strerror(errno));
3272 /* get number of stacks */
3274 ii = mISDN_get_stack_count(device);
3279 printf("Found no card. Please be sure to load card drivers.\n");
3283 /* loop the number of cards and get their info */
3286 nt = te = bri = pri = pots = 0;
3291 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
3294 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3298 /* output the port info */
3299 printf("Port %2d name='%s': ", i, devinfo.name);
3300 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3305 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3311 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3318 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3325 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3332 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3338 if ((te || nt) && (bri || pri || ports))
3342 printf("TE-mode BRI S/T interface line (for phone lines)");
3344 printf("NT-mode BRI S/T interface port (for phones)");
3346 printf("TE-mode PRI E1 interface line (for phone lines)");
3348 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3350 printf("FXS POTS interface port (for analog lines)");
3352 printf("FXO POTS interface port (for analog phones)");
3356 printf("\n -> Analog interfaces are not supported.");
3360 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3364 printf(" - %d B-channels\n", devinfo.nfbchan);
3366 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3369 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3372 stinf = (stack_info_t *)&frm->data.p;
3374 /* output the port info */
3375 printf("Port %2d: ", i);
3376 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3378 case ISDN_PID_L0_TE_S0:
3382 printf("TE-mode BRI S/T interface line (for phone lines)");
3384 case ISDN_PID_L0_NT_S0:
3388 printf("NT-mode BRI S/T interface port (for phones)");
3390 case ISDN_PID_L0_TE_E1:
3394 printf("TE-mode PRI E1 interface line (for phone lines)");
3396 case ISDN_PID_L0_NT_E1:
3400 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3404 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3410 if (stinf->pid.protocol[1] == 0)
3413 printf(" -> Missing layer 1 NT-mode protocol.\n");
3416 while(p <= MAX_LAYER_NR) {
3417 if (stinf->pid.protocol[p])
3420 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3427 printf(" -> Interface is Point-To-Point (PRI).\n");
3429 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3434 if (stinf->pid.protocol[1] == 0)
3437 printf(" -> Missing layer 1 protocol.\n");
3439 if (stinf->pid.protocol[2] == 0)
3442 printf(" -> Missing layer 2 protocol.\n");
3444 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3446 printf(" -> Interface is Poin-To-Point.\n");
3448 if (stinf->pid.protocol[3] == 0)
3451 printf(" -> Missing layer 3 protocol.\n");
3454 printf(" -> Protocol: ");
3455 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3457 case ISDN_PID_L3_DSS1USER:
3458 printf("DSS1 (Euro ISDN)");
3463 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3468 while(p <= MAX_LAYER_NR) {
3469 if (stinf->pid.protocol[p])
3472 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3477 printf(" - %d B-channels\n", stinf->childcnt);
3481 printf(" * Port NOT useable for LCR\n");
3483 printf("--------\n");
3494 if ((ret = mISDN_close(device)))
3495 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3501 * enque data from upper buffer
3503 void PmISDN::txfromup(unsigned char *data, int length)
3506 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3507 struct mISDNhead *frm = (struct mISDNhead *)buf;
3509 if (p_m_b_index < 0)
3511 if (!p_m_mISDNport->b_socket[p_m_b_index])
3514 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3515 iframe_t *frm = (iframe_t *)buf;
3517 if (p_m_b_index < 0)
3519 if (!p_m_mISDNport->b_addr[p_m_b_index])
3523 /* check if high priority tones exist
3524 * ignore data in this case
3526 if (p_tone_name[0] || p_m_crypt_msg_loops)
3529 /* preload procedure
3530 * if transmit buffer in DSP module is empty,
3531 * preload it to DSP_LOAD to prevent jitter gaps.
3533 if (p_m_load==0 && ISDN_LOAD>0)
3536 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
3537 frm->len = ISDN_LOAD;
3538 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
3539 p_m_load += frm->len;
3542 /* drop if load would exceed ISDN_MAXLOAD
3543 * this keeps the delay not too high
3545 if (p_m_load+length > ISDN_MAXLOAD)
3548 /* make and send frame */
3550 frm->prim = DL_DATA_REQ;
3552 memcpy(buf+MISDN_HEADER_LEN, data, length);
3553 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
3555 PERROR("Failed to send to socket %d\n", handle);
3557 frm->prim = DL_DATA | REQUEST;
3558 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3561 memcpy(buf+mISDN_HEADER_LEN, data, length);
3562 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);