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_txvol = mISDNport->ifport->interface->gain_tx;
172 p_m_rxvol = mISDNport->ifport->interface->gain_rx;
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])
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);
641 ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_txvol, "DSP-TXVOL", port->p_m_txvol);
643 ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rxvol, "DSP-RXVOL", port->p_m_rxvol);
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;
792 unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
794 unsigned long portid = mISDNport->b_addr[i];
799 p_m_remote_id = b_port->p_m_remote_id;
800 p_m_remote_ref = b_port->p_m_remote_ref;
806 /* port must be linked in order to allow activation */
808 FATAL("bchannel must be linked to a Port class\n");
814 /* export bchannel */
815 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid);
816 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
817 add_trace("type", NULL, "assign");
819 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
821 add_trace("socket", "id", "%d", portid);
824 state = B_STATE_EXPORTING;
825 mISDNport->b_remote_id[i] = p_m_remote_id;
826 mISDNport->b_remote_ref[i] = p_m_remote_ref;
829 /* create stack and send activation request */
830 if (_bchannel_create(mISDNport, i))
832 _bchannel_activate(mISDNport, i, 1);
833 state = B_STATE_ACTIVATING;
838 case B_STATE_ACTIVATING:
839 case B_STATE_EXPORTING:
840 /* do nothing, because it is already activating */
843 case B_STATE_DEACTIVATING:
844 case B_STATE_IMPORTING:
845 /* do nothing, because we must wait until we can reactivate */
849 /* problems that might ocurr:
850 * B_EVENT_USE is received when channel already in use.
851 * bchannel exported, but not freed by other port
853 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
857 case B_EVENT_EXPORTREQUEST:
858 /* special case where the bchannel is requested by remote */
861 PERROR("export request without remote channel set, please correct.\n");
867 /* in case, the bchannel is exported right after seize_bchannel */
868 /* export bchannel */
869 /* p_m_remote_id is set, when this event happens. */
870 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid);
871 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
872 add_trace("type", NULL, "assign");
874 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
876 add_trace("socket", "id", "%d", portid);
879 state = B_STATE_EXPORTING;
880 mISDNport->b_remote_id[i] = p_m_remote_id;
881 mISDNport->b_remote_ref[i] = p_m_remote_ref;
884 case B_STATE_ACTIVATING:
885 case B_STATE_EXPORTING:
886 /* do nothing, because it is already activating */
889 case B_STATE_DEACTIVATING:
890 case B_STATE_IMPORTING:
891 /* do nothing, because we must wait until we can reactivate */
895 /* bchannel is active, so we deactivate */
896 _bchannel_activate(mISDNport, i, 0);
897 state = B_STATE_DEACTIVATING;
901 /* problems that might ocurr:
902 * ... when channel already in use.
903 * bchannel exported, but not freed by other port
905 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
909 case B_EVENT_ACTIVATED:
912 case B_STATE_ACTIVATING:
913 if (b_port && !p_m_remote_id)
915 /* bchannel is active and used by Port class, so we configure bchannel */
916 _bchannel_configure(mISDNport, i);
917 state = B_STATE_ACTIVE;
920 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
921 _bchannel_activate(mISDNport, i, 0);
922 state = B_STATE_DEACTIVATING;
927 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
931 case B_EVENT_EXPORTED:
934 case B_STATE_EXPORTING:
935 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
937 /* remote export done */
938 state = B_STATE_REMOTE;
941 /* bchannel is now exported, but we need bchannel back
942 * OR bchannel is not used anymore
943 * OR bchannel has been exported to an obsolete ref,
944 * so reimport, to later export to new remote */
945 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid);
946 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
947 add_trace("type", NULL, "remove");
949 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
951 add_trace("socket", "id", "%d", portid);
954 state = B_STATE_IMPORTING;
959 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
965 FATAL("bchannel must be linked to a Port class\n");
969 /* bchannel is idle due to an error, so we do nothing */
972 case B_STATE_ACTIVATING:
973 case B_STATE_EXPORTING:
974 /* do nothing because we must wait until bchanenl is active before deactivating */
978 /* bchannel is active, so we deactivate */
979 _bchannel_activate(mISDNport, i, 0);
980 state = B_STATE_DEACTIVATING;
984 /* bchannel is exported, so we re-import */
985 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid);
986 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
987 add_trace("type", NULL, "remove");
989 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
991 add_trace("socket", "id", "%d", portid);
994 state = B_STATE_IMPORTING;
997 case B_STATE_DEACTIVATING:
998 case B_STATE_IMPORTING:
999 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
1003 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1007 case B_EVENT_DEACTIVATED:
1011 /* ignore due to deactivation confirm after unloading */
1014 case B_STATE_DEACTIVATING:
1015 _bchannel_destroy(mISDNport, i);
1016 state = B_STATE_IDLE;
1019 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
1022 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid);
1023 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1024 add_trace("type", NULL, "assign");
1026 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1028 add_trace("socket", "id", "%d", portid);
1031 state = B_STATE_EXPORTING;
1032 mISDNport->b_remote_id[i] = p_m_remote_id;
1033 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1036 if (_bchannel_create(mISDNport, i))
1038 _bchannel_activate(mISDNport, i, 1);
1039 state = B_STATE_ACTIVATING;
1046 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1050 case B_EVENT_IMPORTED:
1053 case B_STATE_IMPORTING:
1054 state = B_STATE_IDLE;
1055 mISDNport->b_remote_id[i] = 0;
1056 mISDNport->b_remote_ref[i] = 0;
1059 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
1062 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid);
1063 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1064 add_trace("type", NULL, "assign");
1066 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1068 add_trace("socket", "id", "%d", portid);
1071 state = B_STATE_EXPORTING;
1072 mISDNport->b_remote_id[i] = p_m_remote_id;
1073 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1076 if (_bchannel_create(mISDNport, i))
1078 _bchannel_activate(mISDNport, i, 1);
1079 state = B_STATE_ACTIVATING;
1086 /* ignore, because not assigned */
1092 PERROR("Illegal event %d, please correct.\n", event);
1095 mISDNport->b_state[i] = state;
1102 * check for available channel and reserve+set it.
1103 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
1104 * give exclusiv flag
1105 * returns -(cause value) or x = channel x or 0 = no channel
1106 * NOTE: no activation is done here
1108 int PmISDN::seize_bchannel(int channel, int exclusive)
1112 /* the channel is what we have */
1113 if (p_m_b_channel == channel)
1116 /* if channel already in use, release it */
1121 if (channel==CHANNEL_NO || channel==0)
1124 /* is channel in range ? */
1126 || (channel>p_m_mISDNport->b_num && channel<16)
1127 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1128 return(-6); /* channel unacceptable */
1130 /* request exclusive channel */
1131 if (exclusive && channel>0)
1133 i = channel-1-(channel>16);
1134 if (p_m_mISDNport->b_port[i])
1135 return(-44); /* requested channel not available */
1139 /* ask for channel */
1142 i = channel-1-(channel>16);
1143 if (p_m_mISDNport->b_port[i] == NULL)
1147 /* search for channel */
1149 while(i < p_m_mISDNport->b_num)
1151 if (!p_m_mISDNport->b_port[i])
1153 channel = i+1+(i>=15);
1158 return(-34); /* no free channel */
1161 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1164 p_m_mISDNport->b_port[i] = this;
1166 p_m_b_channel = channel;
1167 p_m_b_exclusive = exclusive;
1169 /* reserve channel */
1173 p_m_mISDNport->b_reserved++;
1180 * drop reserved channel and unset it.
1181 * deactivation is also done
1183 void PmISDN::drop_bchannel(void)
1185 /* unreserve channel */
1187 p_m_mISDNport->b_reserved--;
1191 if (p_m_b_index < 0)
1196 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1198 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1199 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1200 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1203 p_m_b_exclusive = 0;
1206 /* process bchannel export/import message from join */
1207 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long handle)
1209 class Endpoint *epoint;
1211 class PmISDN *isdnport;
1212 struct mISDNport *mISDNport;
1217 case BCHANNEL_REQUEST:
1218 /* find the port object for the join object ref */
1219 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1221 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1224 if (!epoint->ep_portlist)
1226 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1229 if (epoint->ep_portlist->next)
1231 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);
1233 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1235 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1238 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1240 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1242 isdnport = (class PmISDN *)port;
1245 if (isdnport->p_m_remote_id)
1247 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1250 mISDNport = isdnport->p_m_mISDNport;
1251 i = isdnport->p_m_b_index;
1252 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1253 add_trace("type", NULL, "export request");
1254 isdnport->p_m_remote_ref = joinremote->j_serial;
1255 isdnport->p_m_remote_id = joinremote->j_remote_id;
1256 if (mISDNport && i>=0)
1258 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1263 case BCHANNEL_ASSIGN_ACK:
1264 case BCHANNEL_REMOVE_ACK:
1265 /* find mISDNport for stack ID */
1266 mISDNport = mISDNport_first;
1270 ii = mISDNport->b_num;
1274 if (mISDNport->b_socket[i] == handle)
1276 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1283 mISDNport = mISDNport->next;
1287 PERROR("received assign/remove ack for handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1290 /* mISDNport may now be set or NULL */
1293 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1294 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1295 if (mISDNport && i>=0)
1296 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1300 PERROR("received wrong bchannel message type %d from remote\n", type);
1308 audio transmission procedure:
1309 -----------------------------
1312 three sources of audio transmission:
1313 - crypto-data high priority
1314 - tones high priority (also high)
1315 - remote-data low priority
1318 a variable that temporarily shows the number of samples elapsed since last transmission process.
1319 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1322 a variable that is increased whenever data is transmitted.
1323 it is decreased while time elapses. it stores the number of samples that
1324 are currently loaded to dsp module.
1325 since clock in dsp module is the same clock for user space process, these
1329 there are two levels:
1330 ISDN_LOAD will give the load that have to be kept in dsp.
1331 ISDN_MAXLOAD will give the maximum load before dropping.
1333 * procedure for low priority data
1334 see txfromup() for procedure
1335 in short: remote data is ignored during high priority tones
1337 * procedure for high priority data
1338 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1339 if no more data is available, load becomes empty again.
1342 0 ISDN_LOAD ISDN_MAXLOAD
1343 +--------------------+----------------------+
1345 +--------------------+----------------------+
1347 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1348 0 ISDN_LOAD ISDN_MAXLOAD
1349 +--------------------+----------------------+
1350 |TTTTTTTTTTTTTTTTTTTT| |
1351 +--------------------+----------------------+
1353 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1354 0 ISDN_LOAD ISDN_MAXLOAD
1355 +--------------------+----------------------+
1356 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1357 +--------------------+----------------------+
1360 int PmISDN::handler(void)
1362 struct message *message;
1366 if ((ret = Port::handler()))
1370 if (p_m_last_tv_sec)
1372 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1373 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1376 /* set clock of first process ever in this instance */
1377 p_m_last_tv_sec = now_tv.tv_sec;
1378 p_m_last_tv_msec = now_tv.tv_usec/1000;
1380 /* process only if we have a minimum of samples, to make packets not too small */
1381 if (elapsed >= ISDN_TRANSMIT)
1383 /* set clock of last process! */
1384 p_m_last_tv_sec = now_tv.tv_sec;
1385 p_m_last_tv_msec = now_tv.tv_usec/1000;
1388 if (elapsed < p_m_load)
1389 p_m_load -= elapsed;
1393 /* to send data, tone must be active OR crypt messages must be on */
1394 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1395 && (p_m_load < ISDN_LOAD)
1396 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1398 int tosend = ISDN_LOAD - p_m_load, length;
1400 unsigned char buf[MISDN_HEADER_LEN+tosend];
1401 struct mISDNhead *frm = (struct mISDNhead *)buf;
1402 unsigned long *d = buf+MISDN_HEADER_LEN;
1404 unsigned char buf[mISDN_HEADER_LEN+tosend];
1405 iframe_t *frm = (iframe_t *)buf;
1406 unsigned char *p = buf+mISDN_HEADER_LEN;
1409 /* copy crypto loops */
1410 while (p_m_crypt_msg_loops && tosend)
1412 /* how much do we have to send */
1413 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1416 if (length > tosend)
1419 /* copy message (part) to buffer */
1420 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1423 p_m_crypt_msg_current += length;
1424 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1427 p_m_crypt_msg_current = 0;
1428 p_m_crypt_msg_loops--;
1429 // puts("eine loop weniger");
1437 if (p_tone_name[0] && tosend)
1439 tosend -= read_audio(p, tosend);
1444 frm->prim = DL_DATA_REQ;
1446 ret = sendto(handle, buffer, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1448 PERROR("Failed to send to socket %d\n", handle);
1450 frm->prim = DL_DATA | REQUEST;
1451 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1453 frm->len = ISDN_LOAD - p_m_load - tosend;
1456 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1457 p_m_load += frm->len;
1461 // NOTE: deletion is done by the child class
1463 /* handle timeouts */
1466 if (p_m_timer+p_m_timeout < now_d)
1468 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1470 /* send timeout to endpoint */
1471 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1472 message->param.state = p_state;
1473 message_put(message);
1478 return(0); /* nothing done */
1483 * whenever we get audio data from bchannel, we process it here
1486 void PmISDN::bchannel_receive(mISDNhead *hh, unsigned char *data, int len)
1488 unsigned long cont = *((unsigned long *)data);
1490 void PmISDN::bchannel_receive(iframe_t *frm)
1493 unsigned long cont = *((unsigned long *)&frm->data.p);
1494 unsigned char *data =(unsigned char *)&frm->data.p;
1496 unsigned char *data_temp;
1497 unsigned long length_temp;
1498 struct message *message;
1503 if (hh->prim == PH_CONTROL_IND)
1505 if (frm->prim == (PH_CONTROL | INDICATION))
1510 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1513 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1515 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1516 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1518 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1519 message->param.dtmf = cont & DTMF_TONE_MASK;
1520 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1521 message_put(message);
1527 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1528 add_trace("DSP-CRYPT", NULL, "error");
1530 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1531 message->param.crypt.type = CC_ERROR_IND;
1532 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1533 message_put(message);
1537 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1538 add_trace("DSP-CRYPT", NULL, "ok");
1540 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1541 message->param.crypt.type = CC_ACTBF_CONF;
1542 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1543 message_put(message);
1547 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1548 add_trace("unknown", NULL, "0x%x", cont);
1554 if (hh->prim == PH_SIGNAL_IND)
1556 if (frm->prim == (PH_SIGNAL | INDICATION))
1564 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1565 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1568 /* see below (same condition) */
1569 if (p_state!=PORT_STATE_CONNECT
1570 && !p_m_mISDNport->tones)
1572 // printf(".");fflush(stdout);return;
1574 record(data, len, 1); // from up
1578 chan_trace_header(p_m_mISDNport, this, "BCHANNEL signal", DIRECTION_IN);
1579 add_trace("unknown", NULL, "0x%x", frm->dinfo);
1585 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1587 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1589 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1591 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1595 /* calls will not process any audio data unless
1596 * the call is connected OR interface features audio during call setup.
1598 //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);
1599 #ifndef DEBUG_COREBRIDGE
1600 if (p_state!=PORT_STATE_CONNECT
1601 && !p_m_mISDNport->tones)
1605 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1608 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1614 record(data, len, 0); // from down
1616 /* randomize and listen to crypt message if enabled */
1617 if (p_m_crypt_listen)
1619 /* the noisy randomizer */
1623 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1625 cryptman_listen_bch(data, len);
1630 /* send data to epoint */
1631 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1637 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1638 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1639 memcpy(message->param.data.data, data_temp, message->param.data.len);
1640 message_put(message);
1641 if (length_temp <= sizeof(message->param.data.data))
1643 data_temp += sizeof(message->param.data.data);
1644 length_temp -= sizeof(message->param.data.data);
1653 void PmISDN::set_echotest(int echo)
1655 if (p_m_echo != echo)
1658 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1660 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1662 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);
1664 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);
1672 void PmISDN::set_tone(char *dir, char *tone)
1678 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1685 /* check if we NOT really have to use a dsp-tone */
1686 if (!options.dsptones)
1690 if (p_m_b_index >= 0)
1691 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1693 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1695 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1697 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1701 Port::set_tone(dir, tone);
1707 /* now we USE dsp-tone, convert name */
1708 else if (!strcmp(tone, "dialtone"))
1710 switch(options.dsptones) {
1711 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1712 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1713 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1715 } else if (!strcmp(tone, "dialpbx"))
1717 switch(options.dsptones) {
1718 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1719 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1720 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1722 } else if (!strcmp(tone, "ringing"))
1724 switch(options.dsptones) {
1725 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1726 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1727 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1729 } else if (!strcmp(tone, "ringpbx"))
1731 switch(options.dsptones) {
1732 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1733 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1734 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1736 } else if (!strcmp(tone, "busy"))
1739 switch(options.dsptones) {
1740 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1741 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1742 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1744 } else if (!strcmp(tone, "release"))
1747 switch(options.dsptones) {
1748 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1749 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1750 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1752 } else if (!strcmp(tone, "cause_10"))
1754 else if (!strcmp(tone, "cause_11"))
1756 else if (!strcmp(tone, "cause_22"))
1758 switch(options.dsptones) {
1759 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1760 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1761 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1763 } else if (!strncmp(tone, "cause_", 6))
1764 id = TONE_SPECIAL_INFO;
1768 /* if we have a tone that is not supported by dsp */
1769 if (id==TONE_OFF && tone[0])
1777 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1778 if (p_m_b_index >= 0)
1779 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1781 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);
1783 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);
1786 /* turn user-space tones off in cases of no tone OR dsp tone */
1787 Port::set_tone("",NULL);
1791 /* MESSAGE_mISDNSIGNAL */
1792 //extern struct message *dddebug;
1793 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1795 switch(param->mISDNsignal.message)
1797 case mISDNSIGNAL_VOLUME:
1798 if (p_m_txvol != param->mISDNsignal.txvol)
1800 p_m_txvol = param->mISDNsignal.txvol;
1801 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
1802 if (p_m_b_index >= 0)
1803 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1805 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_TX, p_m_txvol, "DSP-TXVOL", p_m_txvol);
1807 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_TX, p_m_txvol, "DSP-TXVOL", p_m_txvol);
1810 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rxvol);
1811 if (p_m_rxvol != param->mISDNsignal.rxvol)
1813 p_m_rxvol = param->mISDNsignal.rxvol;
1814 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
1815 if (p_m_b_index >= 0)
1816 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1818 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_RX, p_m_rxvol, "DSP-RXVOL", p_m_rxvol);
1820 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_RX, p_m_rxvol, "DSP-RXVOL", p_m_rxvol);
1823 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rxvol);
1826 case mISDNSIGNAL_CONF:
1827 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1828 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1829 if (p_m_conf != param->mISDNsignal.conf)
1831 p_m_conf = param->mISDNsignal.conf;
1832 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1833 if (p_m_b_index >= 0)
1834 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1836 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);
1838 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);
1841 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1842 /* we must set, even if currently tone forbids conf */
1843 p_m_conf = param->mISDNsignal.conf;
1844 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1847 case mISDNSIGNAL_JOINDATA:
1848 if (p_m_joindata != param->mISDNsignal.joindata)
1850 p_m_joindata = param->mISDNsignal.joindata;
1851 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1853 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1856 case mISDNSIGNAL_DELAY:
1857 if (p_m_delay != param->mISDNsignal.delay)
1859 p_m_delay = param->mISDNsignal.delay;
1860 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1861 if (p_m_b_index >= 0)
1862 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1864 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);
1866 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);
1869 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1873 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1878 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1880 struct message *message;
1882 switch(param->crypt.type)
1884 case CC_ACTBF_REQ: /* activate blowfish */
1886 p_m_crypt_key_len = param->crypt.len;
1887 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1889 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1890 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1891 message->param.crypt.type = CC_ERROR_IND;
1892 message_put(message);
1895 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1897 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1898 if (p_m_b_index >= 0)
1899 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1901 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);
1903 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);
1907 case CC_DACT_REQ: /* deactivate session encryption */
1912 case CR_LISTEN_REQ: /* start listening to messages */
1913 p_m_crypt_listen = 1;
1914 p_m_crypt_listen_state = 0;
1917 case CR_UNLISTEN_REQ: /* stop listening to messages */
1918 p_m_crypt_listen = 0;
1921 case CR_MESSAGE_REQ: /* send message */
1922 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1923 if (!p_m_crypt_msg_len)
1925 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1928 p_m_crypt_msg_current = 0; /* reset */
1929 p_m_crypt_msg_loops = 6; /* enable */
1931 /* disable txmix, or we get corrupt data due to audio process */
1932 if (p_m_txmix && p_m_b_index>=0)
1934 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1936 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1938 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1945 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1951 * endpoint sends messages to the port
1953 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1955 if (Port::message_epoint(epoint_id, message_id, param))
1960 case MESSAGE_DATA: /* tx-data from upper layer */
1961 txfromup(param->data.data, param->data.len);
1964 case MESSAGE_mISDNSIGNAL: /* user command */
1965 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1966 message_mISDNsignal(epoint_id, message_id, param);
1969 case MESSAGE_CRYPT: /* crypt control command */
1970 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1971 message_crypt(epoint_id, message_id, param);
1980 * main loop for processing messages from mISDN
1983 int mISDN_handler(void)
1986 struct mISDNport *mISDNport;
1987 class PmISDN *isdnport;
1989 char buffer[2048+MISDN_HEADER_LEN];
1990 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1992 /* process all ports */
1993 mISDNport = mISDNport_first;
1996 /* process all bchannels */
1998 while(i < mISDNport->b_num)
2000 /* handle port of bchannel */
2001 isdnport=mISDNport->b_port[i];
2004 /* call bridges in user space OR crypto OR recording */
2005 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2007 /* rx IS required */
2008 if (isdnport->p_m_rxoff)
2011 isdnport->p_m_rxoff = 0;
2012 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2013 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2014 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2019 /* rx NOT required */
2020 if (!isdnport->p_m_rxoff)
2023 isdnport->p_m_rxoff = 1;
2024 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\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_OFF, 0, "DSP-RXOFF", 1);
2031 if (isdnport->p_record)
2033 /* txdata IS required */
2034 if (!isdnport->p_m_txdata)
2037 isdnport->p_m_txdata = 1;
2038 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2039 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2040 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2045 /* txdata NOT required */
2046 if (isdnport->p_m_txdata)
2049 isdnport->p_m_txdata = 0;
2050 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\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_OFF, 0, "DSP-TXDATA", 0);
2058 /* handle message from bchannel */
2059 if (mISDNport->b_stack[i] > -1)
2061 ret = recv(mISDNport->b_stack[i], buffer, sizeof(buffer), 0);
2062 if (ret >= MISDN_HEADER_LEN)
2067 /* we don't care about confirms, we use rx data to sync tx */
2072 /* we receive audio data, we respond to it AND we send tones */
2076 case PH_CONTROL_IND:
2077 if (mISDNport->b_port[i])
2078 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2080 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_stack[i]);
2083 case PH_ACTIVATE_IND:
2084 case DL_ESTABLISH_IND:
2085 case PH_ACTIVATE_CONF:
2086 case DL_ESTABLISH_CONF:
2087 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
2088 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2091 case PH_DEACTIVATE_IND:
2092 case DL_RELEASE_IND:
2093 case PH_DEACTIVATE_CONF:
2094 case DL_RELEASE_CONF:
2095 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
2096 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2100 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], msg->len);
2104 if (ret < 0 && errno != EWOULDBLOCK)
2105 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
2112 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2114 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2115 mISDNport->l1timeout = 0;
2118 /* layer 2 establish timer */
2119 if (mISDNport->l2establish)
2121 if (now-mISDNport->l2establish > 5)
2124 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2125 mISDNport->ml3->to_layer2(mISDNport->ml3, DL_ESTABLISH_REQ);
2126 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_REQ, DIRECTION_OUT);
2133 mISDNport = mISDNport->next;
2136 /* if we received at least one b-frame, we will return 1 */
2140 int mISDN_handler(void)
2143 struct mISDNport *mISDNport;
2144 class PmISDN *isdnport;
2149 mISDNuser_head_t *hh;
2152 /* the que avoids loopbacks when replying to stack after receiving
2154 mISDNport = mISDNport_first;
2157 /* process turning on/off rx */
2159 while(i < mISDNport->b_num)
2161 isdnport=mISDNport->b_port[i];
2164 /* call bridges in user space OR crypto OR recording */
2165 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2167 /* rx IS required */
2168 if (isdnport->p_m_rxoff)
2171 isdnport->p_m_rxoff = 0;
2172 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2173 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2174 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2179 /* rx NOT required */
2180 if (!isdnport->p_m_rxoff)
2183 isdnport->p_m_rxoff = 1;
2184 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\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_OFF, 0, "DSP-RXOFF", 1);
2191 if (isdnport->p_record)
2193 /* txdata IS required */
2194 if (!isdnport->p_m_txdata)
2197 isdnport->p_m_txdata = 1;
2198 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2199 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2200 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2205 /* txdata NOT required */
2206 if (isdnport->p_m_txdata)
2209 isdnport->p_m_txdata = 0;
2210 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\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_OFF, 0, "DSP-TXDATA", 0);
2220 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2222 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2223 mISDNport->l1timeout = 0;
2226 if (mISDNport->l2establish)
2228 if (now-mISDNport->l2establish > 5)
2230 if (mISDNport->ntmode)
2232 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2233 time(&mISDNport->l2establish);
2235 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2236 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2241 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2242 time(&mISDNport->l2establish);
2244 act.prim = DL_ESTABLISH | REQUEST;
2245 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2248 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2250 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
2255 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2257 if (mISDNport->ntmode)
2259 hh = (mISDNuser_head_t *)dmsg->data;
2260 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);
2261 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2265 frm = (iframe_t *)dmsg->data;
2266 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2267 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2268 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);
2269 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2274 mISDNport = mISDNport->next;
2277 /* no device, no read */
2278 if (mISDNdevice < 0)
2281 /* get message from kernel */
2282 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2284 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2288 if (errno == EAGAIN)
2290 FATAL("Failed to do mISDN_read()\n");
2295 // printf("%s: ERROR: mISDN_read() returns nothing\n");
2299 frm = (iframe_t *)msg->data;
2304 case MGR_DELLAYER | CONFIRM:
2305 case MGR_INITTIMER | CONFIRM:
2306 case MGR_ADDTIMER | CONFIRM:
2307 case MGR_DELTIMER | CONFIRM:
2308 case MGR_REMOVETIMER | CONFIRM:
2313 /* handle timer events from mISDN for NT-stack
2314 * note: they do not associate with a stack */
2315 if (frm->prim == (MGR_TIMER | INDICATION))
2319 /* find mISDNport */
2320 mISDNport = mISDNport_first;
2324 if (mISDNport->ntmode)
2326 it = mISDNport->nst.tlist;
2330 if (it->id == (int)frm->addr)
2337 mISDNport = mISDNport->next;
2341 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2342 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2344 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2345 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2346 ret = it->function(it->data);
2349 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2354 /* find the mISDNport that belongs to the stack */
2355 mISDNport = mISDNport_first;
2358 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2360 mISDNport = mISDNport->next;
2364 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2369 if (!(frm->addr&FLG_CHILD_STACK))
2374 case MGR_SHORTSTATUS | INDICATION:
2375 case MGR_SHORTSTATUS | CONFIRM:
2376 switch(frm->dinfo) {
2377 case SSTATUS_L1_ACTIVATED:
2378 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2381 case SSTATUS_L1_DEACTIVATED:
2382 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2385 case SSTATUS_L2_ESTABLISHED:
2386 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
2389 case SSTATUS_L2_RELEASED:
2390 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
2396 case PH_ACTIVATE | CONFIRM:
2397 case PH_ACTIVATE | INDICATION:
2398 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2400 if (mISDNport->ntmode)
2402 mISDNport->l1link = 1;
2403 setup_queue(mISDNport, 1);
2407 mISDNport->l1link = 1;
2408 setup_queue(mISDNport, 1);
2411 case PH_DEACTIVATE | CONFIRM:
2412 case PH_DEACTIVATE | INDICATION:
2413 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2415 if (mISDNport->ntmode)
2417 mISDNport->l1link = 0;
2418 setup_queue(mISDNport, 0);
2422 mISDNport->l1link = 0;
2423 setup_queue(mISDNport, 0);
2426 case PH_CONTROL | CONFIRM:
2427 case PH_CONTROL | INDICATION:
2428 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2431 case DL_ESTABLISH | INDICATION:
2432 case DL_ESTABLISH | CONFIRM:
2433 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2435 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2437 if (mISDNport->l2establish)
2439 mISDNport->l2establish = 0;
2440 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2442 mISDNport->l2link = 1;
2445 case DL_RELEASE | INDICATION:
2446 case DL_RELEASE | CONFIRM:
2447 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2449 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2451 mISDNport->l2link = 0;
2454 time(&mISDNport->l2establish);
2455 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2461 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);
2462 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2464 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2467 if (mISDNport->ntmode)
2469 /* l1-data enters the nt-mode library */
2470 nst = &mISDNport->nst;
2471 if (nst->l1_l2(nst, msg))
2476 /* l3-data is sent to pbx */
2477 if (stack2manager_te(mISDNport, msg))
2488 /* we don't care about confirms, we use rx data to sync tx */
2489 case PH_DATA | CONFIRM:
2490 case DL_DATA | CONFIRM:
2493 /* we receive audio data, we respond to it AND we send tones */
2494 case PH_DATA | INDICATION:
2495 case DL_DATA | INDICATION:
2496 case PH_CONTROL | INDICATION:
2497 case PH_SIGNAL | INDICATION:
2499 while(i < mISDNport->b_num)
2501 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2505 if (i == mISDNport->b_num)
2507 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2510 if (mISDNport->b_port[i])
2512 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2513 mISDNport->b_port[i]->bchannel_receive(frm);
2515 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2518 case PH_ACTIVATE | INDICATION:
2519 case DL_ESTABLISH | INDICATION:
2520 case PH_ACTIVATE | CONFIRM:
2521 case DL_ESTABLISH | CONFIRM:
2522 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2524 while(i < mISDNport->b_num)
2526 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2530 if (i == mISDNport->b_num)
2532 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2535 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2538 case PH_DEACTIVATE | INDICATION:
2539 case DL_RELEASE | INDICATION:
2540 case PH_DEACTIVATE | CONFIRM:
2541 case DL_RELEASE | CONFIRM:
2542 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2544 while(i < mISDNport->b_num)
2546 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2550 if (i == mISDNport->b_num)
2552 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2555 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2559 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2570 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2572 struct mISDNport *mISDNport = ml3->private;
2574 if (cmd == MT_ASSIGN)
2580 achtung MT_ASSIGN kommt hier an
2586 case MGR_SHORTSTATUS_IND:
2587 case MGR_SHORTSTATUS_CONF:
2588 switch(frm->dinfo) {
2589 case SSTATUS_L1_ACTIVATED:
2590 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE_IND, DIRECTION_IN);
2593 case SSTATUS_L1_DEACTIVATED:
2594 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE_IND, DIRECTION_IN);
2597 case SSTATUS_L2_ESTABLISHED:
2598 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_IND, DIRECTION_IN);
2601 case SSTATUS_L2_RELEASED:
2602 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE_IND, DIRECTION_IN);
2608 case PH_ACTIVATE_CONF:
2609 case PH_ACTIVATE_IND:
2610 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2613 mISDNport->l1link = 1;
2615 if (mISDNport->ntmode)
2616 setup_queue(mISDNport, 1);
2620 case PH_DEACTIVATE | CONFIRM:
2621 case PH_DEACTIVATE | INDICATION:
2622 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2625 mISDNport->l1link = 0;
2626 raus mit der setup-queue, da dies im stack geschieht
2628 if (mISDNport->ntmode)
2629 setup_queue(mISDNport, 0);
2633 case PH_CONTROL_CONFIRM:
2634 case PH_CONTROL_INDICATION:
2635 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2638 case DL_ESTABLISH_IND:
2639 case DL_ESTABLISH_CONF:
2640 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2642 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2644 if (mISDNport->l2establish)
2646 mISDNport->l2establish = 0;
2647 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2649 mISDNport->l2link = 1;
2652 case DL_RELEASE_IND:
2653 case DL_RELEASE_CONF:
2654 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2657 mISDNport->l2link = 0;
2660 time(&mISDNport->l2establish);
2661 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2666 /* l3-data is sent to LCR */
2667 message_from_mlayer3(mISDNport, cmd, pid, l3m);
2683 * global function to add a new card (port)
2685 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, int force_nt, struct interface *interface)
2688 unsigned char buff[1025];
2689 iframe_t *frm = (iframe_t *)buff;
2690 struct mISDNport *mISDNport, **mISDNportp;
2692 int pri, bri, ports;
2695 struct mlayer3 *ml3;
2696 struct mISDN_devinfo devinfo;
2698 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2701 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2705 // interface_info_t ii;
2709 stack_info_t *stinf;
2711 /* query port's requirements */
2712 cnt = mISDN_get_stack_count(mISDNdevice);
2717 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2720 if (port>cnt || port<1)
2722 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2726 pri = bri = ports = nt = te = 0;
2728 devinfo.id = port - 1;
2729 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
2732 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2735 /* output the port info */
2736 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2741 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2747 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2754 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2761 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2768 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2774 if (force_nt && !nt)
2776 PERROR_RUNTIME("Port %d does not support NT-mode.\n", port);
2781 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2784 if (pots && !bri && !pri)
2786 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2791 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2796 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2799 /* force nt, by turning off TE */
2802 /* if TE an NT is supported (and not forced to NT), turn off NT */
2806 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
2809 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
2812 stinf = (stack_info_t *)&frm->data.p;
2813 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2815 case ISDN_PID_L0_TE_S0:
2816 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
2818 case ISDN_PID_L0_NT_S0:
2819 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
2822 case ISDN_PID_L0_TE_E1:
2823 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
2826 case ISDN_PID_L0_NT_E1:
2827 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
2832 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
2838 if (stinf->pid.protocol[1] == 0)
2840 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
2843 if (stinf->pid.protocol[2])
2845 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
2852 if (stinf->pid.protocol[1] == 0)
2854 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
2857 if (stinf->pid.protocol[2] == 0)
2859 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
2862 if (stinf->pid.protocol[3] == 0)
2864 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
2868 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2870 case ISDN_PID_L3_DSS1USER:
2874 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
2878 if (stinf->pid.protocol[4])
2880 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
2886 /* add mISDNport structure */
2887 mISDNportp = &mISDNport_first;
2889 mISDNportp = &((*mISDNportp)->next);
2890 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2892 *mISDNportp = mISDNport;
2894 /* allocate ressources of port */
2897 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NETWORK;
2902 prop |= FLG_FORCE_PTMP;
2903 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_dchannel, mISDNport);
2904 if (!mISDNport->ml3)
2906 PERROR_RUNTIME("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2911 /* if ntmode, establish L1 to send the tei removal during start */
2912 if (mISDNport->ntmode)
2916 act.prim = PH_ACTIVATE | REQUEST;
2917 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2918 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2921 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2922 usleep(10000); /* to be sure, that l1 is up */
2926 SCPY(mISDNport->name, devinfo.name);
2927 mISDNport->b_num = devinfo.nrbchan;
2929 msg_queue_init(&mISDNport->downqueue);
2930 mISDNport->d_stid = stinf->id;
2931 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
2932 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
2934 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
2938 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
2943 /* create layer intance */
2944 memset(&li, 0, sizeof(li));
2945 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
2948 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
2949 li.pid.layermask = ISDN_LAYER((nt?2:4));
2950 li.st = mISDNport->d_stid;
2951 ret = mISDN_new_layer(mISDNdevice, &li);
2954 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
2956 mISDNport_close(mISDNport);
2959 mISDNport->upper_id = li.id;
2960 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
2963 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
2966 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
2967 if (mISDNport->lower_id < 0)
2969 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
2972 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
2973 if (mISDNport->upper_id < 0)
2975 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2978 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
2980 /* if ntmode, establish L1 to send the tei removal during start */
2981 if (mISDNport->ntmode)
2985 act.prim = PH_ACTIVATE | REQUEST;
2986 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2987 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2990 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2991 usleep(10000); /* to be sure, that l1 is up */
2994 /* create nst (nt-mode only) */
2997 mgr = &mISDNport->mgr;
2998 nst = &mISDNport->nst;
3003 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
3004 nst->device = mISDNdevice;
3006 nst->d_stid = mISDNport->d_stid;
3008 nst->feature = FEATURE_NET_HOLD;
3010 nst->feature |= FEATURE_NET_PTP;
3012 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
3015 while(i < mISDNport->b_num)
3017 nst->b_stid[i] = mISDNport->b_stid[i];
3021 nst->l1_id = mISDNport->lower_id;
3022 nst->l2_id = mISDNport->upper_id;
3025 msg_queue_init(&nst->down_queue);
3031 mISDNport->b_num = stinf->childcnt;
3033 mISDNport->portnum = port;
3034 mISDNport->ntmode = nt;
3035 mISDNport->pri = pri;
3036 mISDNport->ptp = ptp;
3037 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
3039 while(i < mISDNport->b_num)
3041 mISDNport->b_state[i] = B_STATE_IDLE;
3043 mISDNport->b_socket = -1;
3045 mISDNport->b_stid[i] = stinf->child[i];
3046 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
3051 /* if te-mode, query state link */
3052 if (!mISDNport->ntmode)
3056 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
3057 act.prim = MGR_SHORTSTATUS | REQUEST;
3058 act.addr = mISDNport->upper_id | MSG_BROADCAST;
3059 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
3061 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3063 /* if ptp AND te-mode, pull up the link */
3064 if (mISDNport->ptp && !mISDNport->ntmode)
3068 act.prim = DL_ESTABLISH | REQUEST;
3069 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
3072 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3074 /* if ptp AND nt-mode, pull up the link */
3075 if (mISDNport->ptp && mISDNport->ntmode)
3079 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
3080 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
3083 /* initially, we assume that the link is down, exept for nt-ptmp */
3084 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
3086 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
3088 start_trace(mISDNport->portnum,
3096 add_trace("channels", NULL, "%d", mISDNport->b_num);
3103 * function to free ALL cards (ports)
3105 void mISDNport_close_all(void)
3107 /* free all ports */
3108 while(mISDNport_first)
3109 mISDNport_close(mISDNport_first);
3113 * free only one port
3115 void mISDNport_close(struct mISDNport *mISDNport)
3117 struct mISDNport **mISDNportp;
3119 class PmISDN *isdnport;
3121 unsigned char buf[32];
3124 /* remove all port instance that are linked to this mISDNport */
3128 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
3130 isdnport = (class PmISDN *)port;
3131 if (isdnport->p_m_mISDNport)
3133 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
3140 /* only if we are already part of interface */
3141 if (mISDNport->ifport)
3143 start_trace(mISDNport->portnum,
3144 mISDNport->ifport->interface,
3154 /* free bchannels */
3156 while(i < mISDNport->b_num)
3158 if (mISDNport->b_addr[i])
3160 _bchannel_destroy(mISDNport, i);
3161 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
3167 close_layer3(mISDNport->ml3);
3169 /* free ressources of port */
3170 msg_queue_purge(&mISDNport->downqueue);
3173 if (mISDNport->ntmode)
3175 nst = &mISDNport->nst;
3176 if (nst->manager) /* to see if initialized */
3178 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");
3179 cleanup_Isdnl3(nst);
3180 cleanup_Isdnl2(nst);
3183 msg_queue_purge(&nst->down_queue);
3184 if (nst->phd_down_msg)
3185 FREE(nst->phd_down_msg, 0);
3189 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
3190 if (mISDNport->d_stid)
3192 if (mISDNport->upper_id)
3193 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
3197 /* remove from list */
3198 mISDNportp = &mISDNport_first;
3201 if (*mISDNportp == mISDNport)
3203 *mISDNportp = (*mISDNportp)->next;
3207 mISDNportp = &((*mISDNportp)->next);
3211 FATAL("mISDNport not in list\n");
3213 FREE(mISDNport, sizeof(struct mISDNport));
3220 * global function to show all available isdn ports
3222 void mISDN_port_info(void)
3226 int useable, nt, te, pri, bri, pots;
3227 unsigned char buff[1025];
3228 iframe_t *frm = (iframe_t *)buff;
3230 struct mISDN_devinfo devinfo;
3234 socket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
3237 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
3241 /* get number of stacks */
3243 ret = ioctl(socket, IMGETCOUNT, &ii);
3246 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
3250 stack_info_t *stinf;
3254 if ((device = mISDN_open()) < 0)
3256 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));
3260 /* get number of stacks */
3262 ii = mISDN_get_stack_count(device);
3267 printf("Found no card. Please be sure to load card drivers.\n");
3271 /* loop the number of cards and get their info */
3274 nt = te = bri = pri = pots = 0;
3279 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
3282 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3286 /* output the port info */
3287 printf("Port %2d name='%s': ", i, devinfo.name);
3288 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3293 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3299 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3306 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3313 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3320 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3326 if ((te || nt) && (bri || pri || ports))
3330 printf("TE-mode BRI S/T interface line (for phone lines)");
3332 printf("NT-mode BRI S/T interface port (for phones)");
3334 printf("TE-mode PRI E1 interface line (for phone lines)");
3336 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3338 printf("FXS POTS interface port (for analog lines)");
3340 printf("FXO POTS interface port (for analog phones)");
3344 printf("\n -> Analog interfaces are not supported.");
3348 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3352 printf(" - %d B-channels\n", devinfo.nfbchan);
3354 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3357 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3360 stinf = (stack_info_t *)&frm->data.p;
3362 /* output the port info */
3363 printf("Port %2d: ", i);
3364 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3366 case ISDN_PID_L0_TE_S0:
3370 printf("TE-mode BRI S/T interface line (for phone lines)");
3372 case ISDN_PID_L0_NT_S0:
3376 printf("NT-mode BRI S/T interface port (for phones)");
3378 case ISDN_PID_L0_TE_E1:
3382 printf("TE-mode PRI E1 interface line (for phone lines)");
3384 case ISDN_PID_L0_NT_E1:
3388 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3392 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3398 if (stinf->pid.protocol[1] == 0)
3401 printf(" -> Missing layer 1 NT-mode protocol.\n");
3404 while(p <= MAX_LAYER_NR) {
3405 if (stinf->pid.protocol[p])
3408 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3415 printf(" -> Interface is Point-To-Point (PRI).\n");
3417 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3422 if (stinf->pid.protocol[1] == 0)
3425 printf(" -> Missing layer 1 protocol.\n");
3427 if (stinf->pid.protocol[2] == 0)
3430 printf(" -> Missing layer 2 protocol.\n");
3432 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3434 printf(" -> Interface is Poin-To-Point.\n");
3436 if (stinf->pid.protocol[3] == 0)
3439 printf(" -> Missing layer 3 protocol.\n");
3442 printf(" -> Protocol: ");
3443 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3445 case ISDN_PID_L3_DSS1USER:
3446 printf("DSS1 (Euro ISDN)");
3451 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3456 while(p <= MAX_LAYER_NR) {
3457 if (stinf->pid.protocol[p])
3460 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3465 printf(" - %d B-channels\n", stinf->childcnt);
3469 printf(" * Port NOT useable for LCR\n");
3471 printf("--------\n");
3482 if ((ret = mISDN_close(device)))
3483 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3489 * enque data from upper buffer
3491 void PmISDN::txfromup(unsigned char *data, int length)
3494 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3495 struct mISDNhead *frm = (struct mISDNhead *)buf;
3497 if (p_m_b_index < 0)
3499 if (!p_m_mISDNport->b_socket[p_m_b_index])
3502 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3503 iframe_t *frm = (iframe_t *)buf;
3505 if (p_m_b_index < 0)
3507 if (!p_m_mISDNport->b_addr[p_m_b_index])
3511 /* check if high priority tones exist
3512 * ignore data in this case
3514 if (p_tone_name[0] || p_m_crypt_msg_loops)
3517 /* preload procedure
3518 * if transmit buffer in DSP module is empty,
3519 * preload it to DSP_LOAD to prevent jitter gaps.
3521 if (p_m_load==0 && ISDN_LOAD>0)
3524 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
3525 frm->len = ISDN_LOAD;
3526 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
3527 p_m_load += frm->len;
3530 /* drop if load would exceed ISDN_MAXLOAD
3531 * this keeps the delay not too high
3533 if (p_m_load+length > ISDN_MAXLOAD)
3536 /* make and send frame */
3538 frm->prim = DL_DATA_REQ;
3540 memcpy(buf+MISDN_HEADER_LEN, data, length);
3541 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
3543 PERROR("Failed to send to socket %d\n", handle);
3545 frm->prim = DL_DATA | REQUEST;
3546 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3549 memcpy(buf+mISDN_HEADER_LEN, data, length);
3550 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);