1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 **
10 \*****************************************************************************/
16 #define MISDN_OLD_AF_COMPATIBILITY 1
17 #include <compat_af_isdn.h>
22 #ifdef __compiler_offsetof
23 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
25 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
29 #define container_of(ptr, type, member) ({ \
30 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
31 (type *)( (char *)__mptr - offsetof(type,member) );})
34 // timeouts if activating/deactivating response from mISDN got lost
35 #define B_TIMER_ACTIVATING 1 // seconds
36 #define B_TIMER_DEACTIVATING 1 // seconds
38 /* list of mISDN ports */
39 struct mISDNport *mISDNport_first;
41 /* noise randomizer */
42 unsigned char mISDN_rand[256];
43 int mISDN_rand_count = 0;
45 unsigned int mt_assign_pid = ~0;
49 int mISDN_initialize(void)
55 /* try to open raw socket to check kernel */
56 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
57 if (mISDNsocket < 0) {
58 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
63 init_layer3(4); // buffer of 4
65 /* open debug, if enabled and not only stack debugging */
67 SPRINT(filename, "%s/debug.log", LOG_DIR);
68 debug_fp = fopen(filename, "a");
71 if (options.deb & DEBUG_STACK) {
72 SPRINT(filename, "%s/debug_mISDN.log", LOG_DIR);
73 mISDN_debug_init(0xfffffeff, filename, filename, filename);
75 mISDN_debug_init(0, NULL, NULL, NULL);
80 void mISDN_deinitialize(void)
97 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings)
99 p_m_mISDNport = mISDNport;
100 p_m_portnum = mISDNport->portnum;
108 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
109 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
118 p_m_inband_send_on = 0;
119 p_m_inband_receive_on = 0;
120 p_m_dtmf = !mISDNport->ifport->nodtmf;
123 p_m_remote_ref = 0; /* channel shall be exported to given remote */
124 p_m_remote_id = 0; /* remote admin socket */
125 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
133 p_m_crypt_listen = 0;
134 p_m_crypt_msg_loops = 0;
135 p_m_crypt_msg_loops = 0;
136 p_m_crypt_msg_len = 0;
137 p_m_crypt_msg[0] = '\0';
138 p_m_crypt_msg_current = 0;
139 p_m_crypt_key_len = 0;
140 p_m_crypt_listen = 0;
141 p_m_crypt_listen_state = 0;
142 p_m_crypt_listen_len = 0;
143 p_m_crypt_listen_msg[0] = '\0';
144 p_m_crypt_listen_crc = 0;
145 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
146 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
147 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
151 /* if any channel requested by constructor */
152 if (channel == CHANNEL_ANY) {
153 /* reserve channel */
155 mISDNport->b_reserved++;
158 /* reserve channel */
159 if (channel > 0) // only if constructor was called with a channel resevation
160 seize_bchannel(channel, exclusive);
162 /* we increase the number of objects: */
164 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
165 //inband_receive_on();
174 struct lcr_msg *message;
176 /* remove bchannel relation */
180 while (p_epointlist) {
181 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
182 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
183 message->param.disconnectinfo.cause = 16;
184 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
185 message_put(message);
186 /* remove from list */
187 free_epointlist(p_epointlist);
190 /* we decrease the number of objects: */
191 p_m_mISDNport->use--;
192 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
199 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
201 /* init trace with given values */
202 start_trace(mISDNport?mISDNport->portnum:-1,
203 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
204 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
205 port?port->p_dialinginfo.id:NULL,
208 port?port->p_serial:0,
216 static struct isdn_message {
220 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
221 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
222 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
223 {"DL_RELEASE", L2_RELEASE_REQ},
224 {"UNKNOWN", L3_UNKNOWN_REQ},
225 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
226 {"MT_SETUP", L3_SETUP_REQ},
227 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
228 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
229 {"MT_ALERTING", L3_ALERTING_REQ},
230 {"MT_CONNECT", L3_CONNECT_REQ},
231 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
232 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
233 {"MT_RELEASE", L3_RELEASE_REQ},
234 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
235 {"MT_INFORMATION", L3_INFORMATION_REQ},
236 {"MT_PROGRESS", L3_PROGRESS_REQ},
237 {"MT_NOTIFY", L3_NOTIFY_REQ},
238 {"MT_SUSPEND", L3_SUSPEND_REQ},
239 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
240 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
241 {"MT_RESUME", L3_RESUME_REQ},
242 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
243 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
244 {"MT_HOLD", L3_HOLD_REQ},
245 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
246 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
247 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
248 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
249 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
250 {"MT_FACILITY", L3_FACILITY_REQ},
251 {"MT_STATUS", L3_STATUS_REQ},
252 {"MT_RESTART", L3_RESTART_REQ},
253 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
254 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
257 static const char *isdn_prim[4] = {
263 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
268 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
269 /* select message and primitive text */
271 while(isdn_message[i].name) {
272 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
273 if (isdn_message[i].value == (msg&0xffffff00)) {
274 SCPY(msgtext, isdn_message[i].name);
279 SCAT(msgtext, isdn_prim[msg&0x00000003]);
282 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
284 if (mISDNport->ntmode) {
285 if (direction == DIRECTION_OUT)
286 SCAT(msgtext, " N->U");
288 SCAT(msgtext, " N<-U");
290 if (direction == DIRECTION_OUT)
291 SCAT(msgtext, " U->N");
293 SCAT(msgtext, " U<-N");
298 /* init trace with given values */
299 start_trace(mISDNport?mISDNport->portnum:-1,
300 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
301 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
302 port?port->p_dialinginfo.id:NULL,
305 port?port->p_serial:0,
311 * send control information to the channel (dsp-module)
313 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
315 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
316 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
317 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
323 ctrl->prim = PH_CONTROL_REQ;
327 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
329 PERROR("Failed to send to socket %d\n", sock);
330 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
331 if (c1 == DSP_CONF_JOIN)
332 add_trace(trace_name, NULL, "0x%08x", trace_value);
334 add_trace(trace_name, NULL, "%d", trace_value);
338 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, void *c2, int c2_len, const char *trace_name, int trace_value)
340 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
341 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
342 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
348 ctrl->prim = PH_CONTROL_REQ;
351 memcpy(d, c2, c2_len);
352 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
354 PERROR("Failed to send to socket %d\n", sock);
355 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
356 add_trace(trace_name, NULL, "%d", trace_value);
362 * subfunction for bchannel_event
365 static int _bchannel_create(struct mISDNport *mISDNport, int i)
369 struct sockaddr_mISDN addr;
371 if (mISDNport->b_socket[i] > -1) {
372 PERROR("Error: Socket already created for index %d\n", i);
377 //#warning testing without DSP
378 // mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_HDLC:ISDN_P_B_RAW);
379 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_L2DSPHDLC:ISDN_P_B_L2DSP);
380 if (mISDNport->b_socket[i] < 0) {
381 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
385 /* set nonblocking io */
386 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
388 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
389 close(mISDNport->b_socket[i]);
390 mISDNport->b_socket[i] = -1;
394 /* bind socket to bchannel */
395 addr.family = AF_ISDN;
396 addr.dev = mISDNport->portnum;
397 addr.channel = i+1+(i>=15);
398 ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr));
400 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer (errno=%d). Did you load mISDN_dsp.ko?\n", i, errno);
401 close(mISDNport->b_socket[i]);
402 mISDNport->b_socket[i] = -1;
406 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
407 add_trace("channel", NULL, "%d", i+1+(i>=15));
408 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
416 * subfunction for bchannel_event
417 * activate / deactivate request
419 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
421 struct mISDNhead act;
424 if (mISDNport->b_socket[i] < 0)
426 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
428 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
430 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
433 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
434 add_trace("channel", NULL, "%d", i+1+(i>=15));
435 if (mISDNport->b_timer[i])
436 add_trace("event", NULL, "timeout recovery");
442 * subfunction for bchannel_event
445 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
450 if (mISDNport->b_socket[i] < 0)
452 handle = mISDNport->b_socket[i];
453 port = mISDNport->b_port[i];
454 mode = mISDNport->b_mode[i];
456 PERROR("bchannel index i=%d not associated with a port object\n", i);
460 /* set dsp features */
461 if (port->p_m_txdata)
462 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
463 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
464 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
465 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
466 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
467 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
468 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
469 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
470 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
471 if (port->p_m_conf && !port->p_m_mute)
472 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
474 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
475 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
476 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
478 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
479 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
480 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
481 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
482 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
483 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
484 ph_control_block(mISDNport, port, handle, DSP_BF_ENABLE_KEY, port->p_m_crypt_key, port->p_m_crypt_key_len, "DSP-CRYPT", port->p_m_crypt_key_len);
488 void PmISDN::set_conf(int oldconf, int newconf)
490 if (oldconf != newconf) {
491 PDEBUG(DEBUG_BCHANNEL, "we change conference from conf=%d to conf=%d.\n", oldconf, newconf);
492 if (p_m_b_index > -1)
493 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
494 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], (newconf)?DSP_CONF_JOIN:DSP_CONF_SPLIT, newconf, "DSP-CONF", newconf);
496 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", newconf);
501 * subfunction for bchannel_event
504 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
506 if (mISDNport->b_socket[i] < 0)
508 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
509 add_trace("channel", NULL, "%d", i+1+(i>=15));
510 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
512 close(mISDNport->b_socket[i]);
513 mISDNport->b_socket[i] = -1;
521 A bchannel goes through the following states in this order:
524 No one is using the bchannel.
525 It is available and not linked to Port class, nor reserved.
528 The bchannel stack is created and an activation request is sent.
529 It MAY be linked to Port class, but already unlinked due to Port class removal.
532 The bchannel is active and cofigured to the Port class needs.
533 Also it is linked to a Port class, otherwhise it would be deactivated.
535 - B_STATE_DEACTIVATING
536 The bchannel is in deactivating state, due to deactivation request.
537 It may be linked to a Port class, that likes to reactivate it.
541 After deactivating bchannel, and if not used, the bchannel becomes idle again.
543 Also the bchannel may be exported, but only if the state is or becomes idle:
546 The bchannel assignment has been sent to the remove application.
549 The bchannel assignment is acknowledged by the remote application.
552 The bchannel is re-imported by mISDN port object.
556 After re-importing bchannel, and if not used, the bchannel becomes idle again.
559 A bchannel can have the following events:
562 A bchannel is required by a Port class.
565 The bchannel beomes active.
568 The bchannel is not required by Port class anymore
570 - B_EVENT_DEACTIVATED
571 The bchannel becomes inactive.
574 The bchannel is now used by remote application.
577 The bchannel is not used by remote application.
579 - B_EVENT_EXPORTREQUEST
580 The bchannel shall be exported to the remote application.
582 - B_EVENT_IMPORTREQUEST
583 The bchannel is released from the remote application.
585 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
587 if an export request is receive by remote application, p_m_remote_* is set.
588 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.)
589 - set on export request from remote application (if port is assigned)
590 - set on channel use, if requested by remote application (p_m_remote_*)
591 - cleared on drop request
593 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
594 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
595 the bchannel import/export is acknowledged with stack given.
597 if exporting, b_remote_*[index] is set to the remote socket id.
598 if importing has been acknowledged. b_remote_*[index] is cleared.
603 * process bchannel events
604 * - mISDNport is a pointer to the port's structure
605 * - i is the index of the bchannel
606 * - event is the B_EVENT_* value
607 * - port is the PmISDN class pointer
609 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
611 class PmISDN *b_port = mISDNport->b_port[i];
612 int state = mISDNport->b_state[i];
613 double timer = mISDNport->b_timer[i];
614 unsigned int p_m_remote_ref = 0;
615 unsigned int p_m_remote_id = 0;
618 char *p_m_pipeline = NULL;
619 unsigned char *p_m_crypt_key = NULL;
620 int p_m_crypt_key_len = 0;
621 int p_m_crypt_key_type = 0;
622 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
625 p_m_remote_id = b_port->p_m_remote_id;
626 p_m_remote_ref = b_port->p_m_remote_ref;
627 p_m_tx_gain = b_port->p_m_tx_gain;
628 p_m_rx_gain = b_port->p_m_rx_gain;
629 p_m_pipeline = b_port->p_m_pipeline;
630 p_m_crypt_key = b_port->p_m_crypt_key;
631 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
632 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
637 /* port must be linked in order to allow activation */
639 FATAL("bchannel must be linked to a Port class\n");
642 if (p_m_remote_ref) {
643 /* export bchannel */
644 message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
645 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
646 add_trace("type", NULL, "assign");
647 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
649 state = B_STATE_EXPORTING;
650 mISDNport->b_remote_id[i] = p_m_remote_id;
651 mISDNport->b_remote_ref[i] = p_m_remote_ref;
653 /* create stack and send activation request */
654 if (_bchannel_create(mISDNport, i)) {
655 _bchannel_activate(mISDNport, i, 1);
656 state = B_STATE_ACTIVATING;
657 timer = now_d + B_TIMER_ACTIVATING;
662 case B_STATE_ACTIVATING:
663 case B_STATE_EXPORTING:
664 /* do nothing, because it is already activating */
667 case B_STATE_DEACTIVATING:
668 case B_STATE_IMPORTING:
669 /* do nothing, because we must wait until we can reactivate */
673 /* problems that might ocurr:
674 * B_EVENT_USE is received when channel already in use.
675 * bchannel exported, but not freed by other port
677 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
681 case B_EVENT_EXPORTREQUEST:
682 /* special case where the bchannel is requested by remote */
683 if (!p_m_remote_ref) {
684 PERROR("export request without remote channel set, please correct.\n");
689 /* in case, the bchannel is exported right after seize_bchannel */
690 /* export bchannel */
691 /* p_m_remote_id is set, when this event happens. */
692 message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
693 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
694 add_trace("type", NULL, "assign");
695 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
697 state = B_STATE_EXPORTING;
698 mISDNport->b_remote_id[i] = p_m_remote_id;
699 mISDNport->b_remote_ref[i] = p_m_remote_ref;
702 case B_STATE_ACTIVATING:
703 case B_STATE_EXPORTING:
704 /* do nothing, because it is already activating */
707 case B_STATE_DEACTIVATING:
708 case B_STATE_IMPORTING:
709 /* do nothing, because we must wait until we can reactivate */
713 /* bchannel is active, so we deactivate */
714 _bchannel_activate(mISDNport, i, 0);
715 state = B_STATE_DEACTIVATING;
716 timer = now_d + B_TIMER_DEACTIVATING;
720 /* problems that might ocurr:
721 * ... when channel already in use.
722 * bchannel exported, but not freed by other port
724 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
728 case B_EVENT_IMPORTREQUEST:
729 /* special case where the bchannel is released by remote */
730 if (p_m_remote_ref) {
731 PERROR("import request with remote channel set, please correct.\n");
737 /* bchannel is not exported */
740 case B_STATE_ACTIVATING:
741 case B_STATE_EXPORTING:
742 /* do nothing because we must wait until bchanenl is active before deactivating */
746 /* bchannel is exported, so we re-import */
747 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
748 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
749 add_trace("type", NULL, "remove");
750 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
752 state = B_STATE_IMPORTING;
755 case B_STATE_DEACTIVATING:
756 case B_STATE_IMPORTING:
757 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
761 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
765 case B_EVENT_ACTIVATED:
768 case B_STATE_ACTIVATING:
769 if (b_port && !p_m_remote_id) {
770 /* bchannel is active and used by Port class, so we configure bchannel */
771 _bchannel_configure(mISDNport, i);
772 state = B_STATE_ACTIVE;
773 b_port->p_m_load = 0;
775 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
776 _bchannel_activate(mISDNport, i, 0);
777 state = B_STATE_DEACTIVATING;
778 timer = now_d + B_TIMER_DEACTIVATING;
783 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
787 case B_EVENT_EXPORTED:
789 case B_STATE_EXPORTING:
790 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) {
791 /* remote export done */
792 state = B_STATE_REMOTE;
794 /* bchannel is now exported, but we need bchannel back
795 * OR bchannel is not used anymore
796 * OR bchannel has been exported to an obsolete ref,
797 * so reimport, to later export to new remote */
798 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
799 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
800 add_trace("type", NULL, "remove");
801 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
803 state = B_STATE_IMPORTING;
808 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
814 FATAL("bchannel must be linked to a Port class\n");
817 /* bchannel is idle due to an error, so we do nothing */
820 case B_STATE_ACTIVATING:
821 case B_STATE_EXPORTING:
822 /* do nothing because we must wait until bchanenl is active before deactivating */
826 /* bchannel is active, so we deactivate */
827 _bchannel_activate(mISDNport, i, 0);
828 state = B_STATE_DEACTIVATING;
829 timer = now_d + B_TIMER_DEACTIVATING;
833 /* bchannel is exported, so we re-import */
834 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
835 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
836 add_trace("type", NULL, "remove");
837 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
839 state = B_STATE_IMPORTING;
842 case B_STATE_DEACTIVATING:
843 case B_STATE_IMPORTING:
844 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
848 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
852 case B_EVENT_DEACTIVATED:
856 /* ignore due to deactivation confirm after unloading */
859 case B_STATE_DEACTIVATING:
860 _bchannel_destroy(mISDNport, i);
861 state = B_STATE_IDLE;
863 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
864 if (p_m_remote_ref) {
865 message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
866 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
867 add_trace("type", NULL, "assign");
868 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
870 state = B_STATE_EXPORTING;
871 mISDNport->b_remote_id[i] = p_m_remote_id;
872 mISDNport->b_remote_ref[i] = p_m_remote_ref;
874 if (_bchannel_create(mISDNport, i)) {
875 _bchannel_activate(mISDNport, i, 1);
876 state = B_STATE_ACTIVATING;
877 timer = now_d + B_TIMER_ACTIVATING;
884 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
888 case B_EVENT_IMPORTED:
890 case B_STATE_IMPORTING:
891 state = B_STATE_IDLE;
892 mISDNport->b_remote_id[i] = 0;
893 mISDNport->b_remote_ref[i] = 0;
895 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
896 if (p_m_remote_ref) {
897 message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
898 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
899 add_trace("type", NULL, "assign");
900 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
902 state = B_STATE_EXPORTING;
903 mISDNport->b_remote_id[i] = p_m_remote_id;
904 mISDNport->b_remote_ref[i] = p_m_remote_ref;
906 if (_bchannel_create(mISDNport, i)) {
907 _bchannel_activate(mISDNport, i, 1);
908 state = B_STATE_ACTIVATING;
909 timer = now_d + B_TIMER_ACTIVATING;
916 /* ignore, because not assigned */
921 case B_EVENT_TIMEOUT:
925 /* ignore due to deactivation confirm after unloading */
928 case B_STATE_ACTIVATING:
929 _bchannel_activate(mISDNport, i, 1);
930 timer = now_d + B_TIMER_ACTIVATING;
933 case B_STATE_DEACTIVATING:
934 _bchannel_activate(mISDNport, i, 0);
935 timer = now_d + B_TIMER_DEACTIVATING;
939 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
944 PERROR("Illegal event %d, please correct.\n", event);
947 mISDNport->b_state[i] = state;
948 mISDNport->b_timer[i] = timer;
955 * check for available channel and reserve+set it.
956 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
958 * returns -(cause value) or x = channel x or 0 = no channel
959 * NOTE: no activation is done here
961 int PmISDN::seize_bchannel(int channel, int exclusive)
965 /* the channel is what we have */
966 if (p_m_b_channel == channel)
969 /* if channel already in use, release it */
974 if (channel==CHANNEL_NO || channel==0)
977 /* is channel in range ? */
979 || (channel>p_m_mISDNport->b_num && channel<16)
980 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
981 return(-6); /* channel unacceptable */
983 /* request exclusive channel */
984 if (exclusive && channel>0) {
985 i = channel-1-(channel>16);
986 if (p_m_mISDNport->b_port[i])
987 return(-44); /* requested channel not available */
991 /* ask for channel */
993 i = channel-1-(channel>16);
994 if (p_m_mISDNport->b_port[i] == NULL)
998 /* search for channel */
1000 while(i < p_m_mISDNport->b_num) {
1001 if (!p_m_mISDNport->b_port[i]) {
1002 channel = i+1+(i>=15);
1007 return(-34); /* no free channel */
1010 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1012 /* link Port, set parameters */
1013 p_m_mISDNport->b_port[i] = this;
1015 p_m_b_channel = channel;
1016 p_m_b_exclusive = exclusive;
1017 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1019 /* reserve channel */
1020 if (!p_m_b_reserve) {
1022 p_m_mISDNport->b_reserved++;
1029 * drop reserved channel and unset it.
1030 * deactivation is also done
1032 void PmISDN::drop_bchannel(void)
1034 /* unreserve channel */
1036 p_m_mISDNport->b_reserved--;
1040 if (p_m_b_index < 0)
1045 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1047 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1048 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1049 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1050 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1053 p_m_b_exclusive = 0;
1056 /* process bchannel export/import message from join */
1057 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1059 class Endpoint *epoint;
1061 class PmISDN *isdnport;
1062 struct mISDNport *mISDNport;
1066 case BCHANNEL_REQUEST:
1067 /* find the port object for the join object ref */
1068 if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) {
1069 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1072 if (!epoint->ep_portlist) {
1073 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1076 if (epoint->ep_portlist->next) {
1077 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);
1079 if (!(port = find_port_id(epoint->ep_portlist->port_id))) {
1080 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1083 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) {
1084 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1086 isdnport = (class PmISDN *)port;
1089 if (isdnport->p_m_remote_id) {
1090 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1093 mISDNport = isdnport->p_m_mISDNport;
1094 i = isdnport->p_m_b_index;
1095 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1096 add_trace("type", NULL, "export request");
1098 isdnport->p_m_remote_ref = joinremote->j_serial;
1099 isdnport->p_m_remote_id = joinremote->j_remote_id;
1100 if (mISDNport && i>=0) {
1101 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1105 case BCHANNEL_RELEASE:
1106 case BCHANNEL_ASSIGN_ACK:
1107 case BCHANNEL_REMOVE_ACK:
1108 /* find mISDNport for stack ID */
1109 mISDNport = mISDNport_first;
1112 ii = mISDNport->b_num;
1114 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1120 mISDNport = mISDNport->next;
1123 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1127 if (type!=BCHANNEL_RELEASE) {
1129 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1130 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1132 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1135 isdnport = mISDNport->b_port[i];
1136 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1137 add_trace("type", NULL, "import request");
1140 isdnport->p_m_remote_ref = 0;
1141 isdnport->p_m_remote_id = 0;
1143 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1147 PERROR("received wrong bchannel message type %d from remote\n", type);
1155 audio transmission procedure:
1156 -----------------------------
1159 three sources of audio transmission:
1160 - crypto-data high priority
1161 - tones high priority (also high)
1162 - remote-data low priority
1165 a variable that temporarily shows the number of samples elapsed since last transmission process.
1166 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1169 a variable that is increased whenever data is transmitted.
1170 it is decreased while time elapses. it stores the number of samples that
1171 are currently loaded to dsp module.
1172 since clock in dsp module is the same clock for user space process, these
1176 there are two levels:
1177 ISDN_LOAD will give the load that have to be kept in dsp.
1178 ISDN_MAXLOAD will give the maximum load before dropping.
1180 * procedure for low priority data
1181 see txfromup() for procedure
1182 in short: remote data is ignored during high priority tones
1184 * procedure for high priority data
1185 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1186 if no more data is available, load becomes empty again.
1189 0 ISDN_LOAD ISDN_MAXLOAD
1190 +--------------------+----------------------+
1192 +--------------------+----------------------+
1194 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1195 0 ISDN_LOAD ISDN_MAXLOAD
1196 +--------------------+----------------------+
1197 |TTTTTTTTTTTTTTTTTTTT| |
1198 +--------------------+----------------------+
1200 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1201 0 ISDN_LOAD ISDN_MAXLOAD
1202 +--------------------+----------------------+
1203 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1204 +--------------------+----------------------+
1207 int PmISDN::handler(void)
1209 struct lcr_msg *message;
1213 if ((ret = Port::handler()))
1217 if (p_m_last_tv_sec) {
1218 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1219 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1221 /* set clock of first process ever in this instance */
1222 p_m_last_tv_sec = now_tv.tv_sec;
1223 p_m_last_tv_msec = now_tv.tv_usec/1000;
1225 /* process only if we have a minimum of samples, to make packets not too small */
1226 if (elapsed >= ISDN_TRANSMIT
1227 && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
1228 /* set clock of last process! */
1229 p_m_last_tv_sec = now_tv.tv_sec;
1230 p_m_last_tv_msec = now_tv.tv_usec/1000;
1233 if (elapsed < p_m_load)
1234 p_m_load -= elapsed;
1238 /* to send data, tone must be on */
1239 if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
1240 && (p_m_load < ISDN_LOAD) /* enough load? */
1241 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
1242 int tosend = ISDN_LOAD - p_m_load, length;
1243 unsigned char buf[MISDN_HEADER_LEN+tosend];
1244 struct mISDNhead *frm = (struct mISDNhead *)buf;
1245 unsigned char *p = buf+MISDN_HEADER_LEN;
1247 /* copy inband signalling (e.g. used by ss5) */
1248 if (p_m_inband_send_on && tosend) {
1249 tosend -= inband_send(p, tosend);
1252 /* copy crypto loops */
1253 while (p_m_crypt_msg_loops && tosend) {
1254 /* how much do we have to send */
1255 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1258 if (length > tosend)
1261 /* copy message (part) to buffer */
1262 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1265 p_m_crypt_msg_current += length;
1266 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
1268 p_m_crypt_msg_current = 0;
1269 p_m_crypt_msg_loops--;
1270 // puts("eine loop weniger");
1278 if (p_tone_name[0] && tosend) {
1279 tosend -= read_audio(p, tosend);
1283 if (ISDN_LOAD - p_m_load - tosend > 0) {
1284 frm->prim = PH_DATA_REQ;
1286 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1288 PERROR("Failed to send to socket %d (samples = %d)\n", p_m_mISDNport->b_socket[p_m_b_index], ISDN_LOAD-p_m_load-tosend);
1289 p_m_load += ISDN_LOAD - p_m_load - tosend;
1294 // NOTE: deletion is done by the child class
1296 /* handle timeouts */
1298 if (p_m_timer+p_m_timeout < now_d) {
1299 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1301 /* send timeout to endpoint */
1302 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1303 message->param.state = p_state;
1304 message_put(message);
1309 return(0); /* nothing done */
1314 * whenever we get audio data from bchannel, we process it here
1316 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1318 unsigned int cont = *((unsigned int *)data);
1319 unsigned char *data_temp;
1320 unsigned int length_temp;
1321 struct lcr_msg *message;
1325 if (hh->prim == PH_CONTROL_IND) {
1327 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1330 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1331 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1332 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1334 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1335 message->param.dtmf = cont & DTMF_TONE_MASK;
1336 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1337 message_put(message);
1342 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1343 add_trace("DSP-CRYPT", NULL, "error");
1345 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1346 message->param.crypt.type = CC_ERROR_IND;
1347 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1348 message_put(message);
1352 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1353 add_trace("DSP-CRYPT", NULL, "ok");
1355 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1356 message->param.crypt.type = CC_ACTBF_CONF;
1357 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1358 message_put(message);
1362 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1363 add_trace("unknown", NULL, "0x%x", cont);
1368 if (hh->prim == PH_CONTROL_IND) {
1371 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1372 add_trace("unknown", NULL, "0x%x", hh->id);
1377 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1379 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1380 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1383 /* see below (same condition) */
1384 if (p_state!=PORT_STATE_CONNECT
1385 && !p_m_mISDNport->tones)
1387 // printf(".");fflush(stdout);return;
1389 record(data, len, 1); // from up
1392 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1393 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1397 /* inband is processed */
1398 if (p_m_inband_receive_on)
1399 inband_receive(data, len);
1401 /* calls will not process any audio data unless
1402 * the call is connected OR tones feature is enabled.
1404 #ifndef DEBUG_COREBRIDGE
1405 if (p_state!=PORT_STATE_CONNECT
1406 && !p_m_mISDNport->tones)
1411 /* the bearer capability must be audio in order to send and receive
1412 * audio prior or after connect.
1414 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1418 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1420 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1426 record(data, len, 0); // from down
1428 /* randomize and listen to crypt message if enabled */
1429 if (p_m_crypt_listen) {
1430 /* the noisy randomizer */
1434 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1436 cryptman_listen_bch(data, len);
1441 /* send data to epoint */
1442 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) { /* only if we have an epoint object */
1445 while(length_temp) {
1446 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1447 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1448 memcpy(message->param.data.data, data_temp, message->param.data.len);
1449 message_put(message);
1450 if (length_temp <= sizeof(message->param.data.data))
1452 data_temp += sizeof(message->param.data.data);
1453 length_temp -= sizeof(message->param.data.data);
1462 void PmISDN::set_echotest(int echo)
1464 if (p_m_echo != echo) {
1466 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1468 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1469 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_echo?DSP_ECHO_ON:DSP_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1476 void PmISDN::set_tone(const char *dir, const char *tone)
1481 /* if no directory is given (by extension), we use interface.conf or options.conf */
1482 if (!dir || !dir[0]) {
1483 if (p_m_mISDNport->ifport->tones_dir[0])
1484 dir = p_m_mISDNport->ifport->tones_dir;
1485 else if (options.tones_dir[0])
1486 dir = options.tones_dir;
1491 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1497 /* check for dsp tones */
1498 if (!strcmp(dir, "american"))
1500 if (!strcmp(dir, "german"))
1502 if (!strcmp(dir, "oldgerman"))
1503 dsp = DSP_OLDGERMAN;
1505 /* check if we NOT really have to use a dsp-tone */
1506 if (dsp == DSP_NONE) {
1509 if (p_m_b_index > -1)
1510 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1511 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1512 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1515 Port::set_tone(dir, tone);
1519 /* now we USE dsp-tone, convert name */
1520 if (!strcmp(tone, "dialtone")) {
1522 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1523 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1524 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1526 } else if (!strcmp(tone, "dialpbx")) {
1528 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1529 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1530 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1532 } else if (!strcmp(tone, "ringing")) {
1534 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1535 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1536 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1538 } else if (!strcmp(tone, "ringpbx")) {
1540 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1541 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1542 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1544 } else if (!strcmp(tone, "busy")) {
1547 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1548 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1549 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1551 } else if (!strcmp(tone, "release")) {
1554 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1555 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1556 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1558 } else if (!strcmp(tone, "cause_10"))
1560 else if (!strcmp(tone, "cause_11"))
1562 else if (!strcmp(tone, "cause_22")) {
1564 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1565 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1566 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1568 } else if (!strncmp(tone, "cause_", 6))
1569 id = TONE_SPECIAL_INFO;
1573 /* if we have a tone that is not supported by dsp */
1574 if (id==TONE_OFF && tone[0])
1578 if (p_m_tone != id) {
1581 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1582 if (p_m_b_index > -1)
1583 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1584 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_tone?DSP_TONE_PATT_ON:DSP_TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1586 /* turn user-space tones off in cases of no tone OR dsp tone */
1587 Port::set_tone("",NULL);
1591 /* MESSAGE_mISDNSIGNAL */
1592 //extern struct lcr_msg *dddebug;
1593 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1595 int oldconf, newconf;
1596 switch(param->mISDNsignal.message) {
1597 case mISDNSIGNAL_VOLUME:
1598 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1599 p_m_tx_gain = param->mISDNsignal.tx_gain;
1600 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1601 if (p_m_b_index > -1)
1602 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1603 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1605 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1606 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1607 p_m_rx_gain = param->mISDNsignal.rx_gain;
1608 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1609 if (p_m_b_index > -1)
1610 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1611 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1613 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1616 case mISDNSIGNAL_CONF:
1617 oldconf = p_m_mute?0:p_m_conf;
1618 p_m_conf = param->mISDNsignal.conf;
1619 newconf = p_m_mute?0:p_m_conf;
1620 set_conf(oldconf, newconf);
1623 case mISDNSIGNAL_JOINDATA:
1624 if (p_m_joindata != param->mISDNsignal.joindata) {
1625 p_m_joindata = param->mISDNsignal.joindata;
1626 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1628 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1631 case mISDNSIGNAL_DELAY:
1632 if (p_m_delay != param->mISDNsignal.delay) {
1633 p_m_delay = param->mISDNsignal.delay;
1634 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1635 if (p_m_b_index > -1)
1636 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1637 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_delay?DSP_DELAY:DSP_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
1639 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1643 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1648 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1650 struct lcr_msg *message;
1652 switch(param->crypt.type) {
1653 case CC_ACTBF_REQ: /* activate blowfish */
1655 p_m_crypt_key_len = param->crypt.len;
1656 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1657 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1658 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1659 message->param.crypt.type = CC_ERROR_IND;
1660 message_put(message);
1663 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1665 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1666 if (p_m_b_index > -1)
1667 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1668 ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_crypt?DSP_BF_ENABLE_KEY:DSP_BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len);
1671 case CC_DACT_REQ: /* deactivate session encryption */
1676 case CR_LISTEN_REQ: /* start listening to messages */
1677 p_m_crypt_listen = 1;
1678 p_m_crypt_listen_state = 0;
1681 case CR_UNLISTEN_REQ: /* stop listening to messages */
1682 p_m_crypt_listen = 0;
1685 case CR_MESSAGE_REQ: /* send message */
1686 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1687 if (!p_m_crypt_msg_len) {
1688 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1691 p_m_crypt_msg_current = 0; /* reset */
1692 p_m_crypt_msg_loops = 6; /* enable */
1694 /* disable txmix, or we get corrupt data due to audio process */
1695 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1696 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1697 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1703 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1709 * endpoint sends messages to the port
1711 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1713 if (Port::message_epoint(epoint_id, message_id, param))
1716 switch(message_id) {
1717 case MESSAGE_DATA: /* tx-data from upper layer */
1718 txfromup(param->data.data, param->data.len);
1721 case MESSAGE_mISDNSIGNAL: /* user command */
1722 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1723 message_mISDNsignal(epoint_id, message_id, param);
1726 case MESSAGE_CRYPT: /* crypt control command */
1727 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1728 message_crypt(epoint_id, message_id, param);
1737 * main loop for processing messages from mISDN
1739 int mISDN_handler(void)
1742 struct mISDNport *mISDNport;
1743 class PmISDN *isdnport;
1745 unsigned char buffer[2048+MISDN_HEADER_LEN];
1746 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1750 /* process all ports */
1751 mISDNport = mISDNport_first;
1753 /* process all bchannels */
1755 while(i < mISDNport->b_num) {
1756 /* process timer events for bchannel handling */
1757 if (mISDNport->b_timer[i]) {
1758 if (mISDNport->b_timer[i] <= now_d)
1759 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
1761 /* handle port of bchannel */
1762 isdnport=mISDNport->b_port[i];
1764 /* call bridges in user space OR crypto OR recording */
1765 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record || isdnport->p_m_inband_receive_on) {
1766 /* rx IS required */
1767 if (isdnport->p_m_rxoff) {
1769 isdnport->p_m_rxoff = 0;
1770 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1771 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1772 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1776 /* rx NOT required */
1777 if (!isdnport->p_m_rxoff) {
1779 isdnport->p_m_rxoff = 1;
1780 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1781 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1782 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1787 if (isdnport->p_record) {
1788 /* txdata IS required */
1789 if (!isdnport->p_m_txdata) {
1791 isdnport->p_m_txdata = 1;
1792 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1793 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1794 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1798 /* txdata NOT required */
1799 if (isdnport->p_m_txdata) {
1801 isdnport->p_m_txdata = 0;
1802 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1803 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1804 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1810 /* handle message from bchannel */
1811 if (mISDNport->b_socket[i] > -1) {
1812 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
1813 if (ret >= (int)MISDN_HEADER_LEN) {
1816 /* we don't care about confirms, we use rx data to sync tx */
1820 /* we receive audio data, we respond to it AND we send tones */
1825 case PH_CONTROL_IND:
1826 if (mISDNport->b_port[i])
1827 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1829 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
1832 case PH_ACTIVATE_IND:
1833 case DL_ESTABLISH_IND:
1834 case PH_ACTIVATE_CNF:
1835 case DL_ESTABLISH_CNF:
1836 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
1837 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1840 case PH_DEACTIVATE_IND:
1841 case DL_RELEASE_IND:
1842 case PH_DEACTIVATE_CNF:
1843 case DL_RELEASE_CNF:
1844 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
1845 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1849 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
1852 if (ret < 0 && errno != EWOULDBLOCK)
1853 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
1860 /* handle queued up-messages (d-channel) */
1861 if (!mISDNport->gsm) {
1862 while ((mb = mdequeue(&mISDNport->upqueue))) {
1865 case MPH_ACTIVATE_IND:
1866 if (mISDNport->l1link != 1) {
1867 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1869 mISDNport->l1link = 1;
1873 case MPH_DEACTIVATE_IND:
1874 if (mISDNport->l1link != 0) {
1875 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1877 mISDNport->l1link = 0;
1881 case MPH_INFORMATION_IND:
1882 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1884 case L1_SIGNAL_LOS_ON:
1887 case L1_SIGNAL_LOS_OFF:
1890 case L1_SIGNAL_AIS_ON:
1893 case L1_SIGNAL_AIS_OFF:
1896 case L1_SIGNAL_RDI_ON:
1899 case L1_SIGNAL_RDI_OFF:
1902 case L1_SIGNAL_SLIP_TX:
1903 mISDNport->slip_tx++;
1905 case L1_SIGNAL_SLIP_RX:
1906 mISDNport->slip_rx++;
1911 case MT_L2ESTABLISH:
1912 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1913 add_trace("tei", NULL, "%d", l3m->pid);
1915 mISDNport->l2link = 1;
1917 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1918 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1919 if (mISDNport->l2establish) {
1920 mISDNport->l2establish = 0;
1921 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1928 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1929 if (!mISDNport->l2establish) {
1930 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1931 add_trace("tei", NULL, "%d", l3m->pid);
1933 /* down if not nt-ptmp */
1934 if (!mISDNport->ntmode || mISDNport->ptp)
1935 mISDNport->l2link = 0;
1937 if (!mISDNport->gsm && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1938 if (!mISDNport->l2establish && mISDNport->l2hold) {
1939 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1940 time(&mISDNport->l2establish);
1941 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1947 /* l3-data is sent to LCR */
1948 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1956 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
1958 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
1959 mISDNport->l1timeout = 0;
1962 /* layer 2 establish timer */
1963 if (mISDNport->l2establish) {
1964 if (now-mISDNport->l2establish > 5) {
1965 mISDNport->l2establish = 0;
1966 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1968 // PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1969 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1970 time(&mISDNport->l2establish);
1977 mISDNport = mISDNport->next;
1980 /* if we received at least one b-frame, we will return 1 */
1984 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1988 * l3m must be queued, except for MT_ASSIGN
1991 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
1994 /* special MT_ASSIGN handling:
1996 * if we request a PID from mlayer, we always do it while lcr is locked.
1997 * therefore we must check the MT_ASSIGN reply first before we lock.
1998 * this is because the MT_ASSIGN reply is received with the requesting
1999 * process, not by the mlayer thread!
2000 * this means, that the reply is sent during call of the request.
2001 * we must check if we get a reply and we know that we lcr is currently
2004 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2005 /* let's do some checking if someone changes stack behaviour */
2006 if (mt_assign_pid != 0)
2007 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2008 mt_assign_pid = pid;
2011 /* queue message, create, if required */
2013 l3m = alloc_l3_msg();
2015 FATAL("No memory for layer 3 message\n");
2017 mb = container_of(l3m, struct mbuffer, l3);
2020 mqueue_tail(&mISDNport->upqueue, mb);
2024 int mISDN_getportbyname(int sock, int cnt, char *portname)
2026 struct mISDN_devinfo devinfo;
2030 while (port < cnt) {
2032 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2035 if (!strcasecmp(devinfo.name, portname))
2046 * global function to add a new card (port)
2048 struct mISDNport *mISDNport_open(int port, char *portname, int ptp, int force_nt, int te_special, int l1hold, int l2hold, struct interface *interface, int gsm, unsigned int ss5)
2051 struct mISDNport *mISDNport, **mISDNportp;
2055 // struct mlayer3 *ml3;
2056 struct mISDN_devinfo devinfo;
2057 unsigned int protocol, prop;
2059 /* check port counts */
2060 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2062 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2067 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2071 port = mISDN_getportbyname(mISDNsocket, cnt, portname);
2074 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface for GSM?.\n", portname);
2076 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", portname);
2079 // note: 'port' has still the port number
2081 if (port>cnt || port<0) {
2082 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2086 /* get port attributes */
2087 pri = bri = pots = nt = te = 0;
2089 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2091 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2094 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2098 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2102 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2106 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2111 if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2117 if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2122 if (force_nt && !nt) {
2123 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2127 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2130 if (pots && !bri && !pri) {
2131 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2135 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2139 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2142 /* set NT by turning off TE */
2145 /* if TE an NT is supported (and not forced to NT), turn off NT */
2149 /* check for double use of port */
2151 mISDNport = mISDNport_first;
2153 if (mISDNport->portnum == port)
2155 mISDNport = mISDNport->next;
2158 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2163 /* check for continous channelmap with no bchannel on slot 16 */
2164 if (test_channelmap(0, devinfo.channelmap)) {
2165 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2169 while(i < (int)devinfo.nrbchan + 1) {
2171 if (test_channelmap(i, devinfo.channelmap)) {
2172 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2176 if (!test_channelmap(i, devinfo.channelmap)) {
2177 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2184 /* add mISDNport structure */
2185 mISDNportp = &mISDNport_first;
2187 mISDNportp = &((*mISDNportp)->next);
2188 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2190 /* gsm/ss5 link is always active */
2191 mISDNport->l1link = 1;
2192 mISDNport->l2link = 1;
2194 mISDNport->l1link = -1;
2195 mISDNport->l2link = -1;
2197 mISDNport->gsm = gsm;
2199 *mISDNportp = mISDNport;
2201 /* if pri, must set PTP */
2205 /* set ss5 params */
2207 /* try to keep interface enabled */
2227 /* allocate ressources of port */
2228 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2229 prop = (1 << MISDN_FLG_L2_CLEAN);
2230 if (ptp) // ptp forced
2231 prop |= (1 << MISDN_FLG_PTP);
2232 if (nt) // supports hold/retrieve on nt-mode
2233 prop |= (1 << MISDN_FLG_NET_HOLD);
2234 if (l1hold) // supports layer 1 hold
2235 prop |= (1 << MISDN_FLG_L1_HOLD);
2236 if (l2hold) // supports layer 2 hold
2237 prop |= (1 << MISDN_FLG_L2_HOLD);
2238 /* open layer 3 and init upqueue */
2240 unsigned long on = 1;
2241 struct sockaddr_mISDN addr;
2243 if (devinfo.nrbchan < 8) {
2244 PERROR_RUNTIME("GSM port %d must have at least 8 b-channels.\n", port);
2245 mISDNport_close(mISDNport);
2249 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_NT_S0)) < 0) {
2250 PERROR_RUNTIME("GSM port %d failed to open socket.\n", port);
2251 mISDNport_close(mISDNport);
2254 /* set nonblocking io */
2255 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2256 PERROR_RUNTIME("GSM port %d failed to set socket into nonblocking io.\n", port);
2257 mISDNport_close(mISDNport);
2260 /* bind socket to dchannel */
2261 memset(&addr, 0, sizeof(addr));
2262 addr.family = AF_ISDN;
2265 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2266 PERROR_RUNTIME("GSM port %d failed to bind socket. (errno %d)\n", port, errno);
2267 mISDNport_close(mISDNport);
2271 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2272 mqueue_init(&mISDNport->upqueue);
2273 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2274 if (!mISDNport->ml3) {
2275 mqueue_purge(&mISDNport->upqueue);
2276 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2284 "PORT (open failed)");
2286 mISDNport_close(mISDNport);
2291 SCPY(mISDNport->name, devinfo.name);
2292 mISDNport->b_num = devinfo.nrbchan;
2293 mISDNport->portnum = port;
2294 mISDNport->ntmode = nt;
2295 mISDNport->tespecial = te_special;
2296 mISDNport->pri = pri;
2297 mISDNport->ptp = ptp;
2298 mISDNport->l1hold = l1hold;
2299 mISDNport->l2hold = l2hold;
2300 mISDNport->ss5 = ss5;
2301 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2303 while(i < mISDNport->b_num) {
2304 mISDNport->b_state[i] = B_STATE_IDLE;
2305 mISDNport->b_socket[i] = -1;
2309 /* if ptp, pull up the link */
2310 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2311 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2312 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2313 add_trace("tei", NULL, "%d", 0);
2315 time(&mISDNport->l2establish);
2318 /* for nt-mode ptmp the link is always up */
2319 if (mISDNport->ntmode && !mISDNport->ptp)
2320 mISDNport->l2link = 1;
2322 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2324 start_trace(mISDNport->portnum,
2332 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2333 add_trace("channels", NULL, "%d", mISDNport->b_num);
2335 add_trace("ccitt#5", NULL, "enabled");
2343 * load static port instances, if required by mISDNport
2345 void mISDNport_static(struct mISDNport *mISDNport)
2350 while(i < mISDNport->b_num) {
2353 ss5_create_channel(mISDNport, i);
2361 * function to free ALL cards (ports)
2363 void mISDNport_close_all(void)
2365 /* free all ports */
2366 while(mISDNport_first)
2367 mISDNport_close(mISDNport_first);
2371 * free only one port
2373 void mISDNport_close(struct mISDNport *mISDNport)
2375 struct mISDNport **mISDNportp;
2377 class PmISDN *isdnport;
2380 /* remove all port instance that are linked to this mISDNport */
2384 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2385 isdnport = (class PmISDN *)port;
2386 if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2387 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2395 /* only if we are already part of interface */
2396 if (mISDNport->ifport) {
2397 start_trace(mISDNport->portnum,
2398 mISDNport->ifport->interface,
2408 /* free bchannels */
2410 while(i < mISDNport->b_num) {
2411 if (mISDNport->b_socket[i] > -1) {
2412 _bchannel_destroy(mISDNport, i);
2413 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2418 /* close layer 3, if open */
2419 if (!mISDNport->gsm && mISDNport->ml3) {
2420 close_layer3(mISDNport->ml3);
2423 /* close gsm socket, if open */
2424 if (mISDNport->gsm && mISDNport->lcr_sock > -1) {
2425 close(mISDNport->lcr_sock);
2429 if (!mISDNport->gsm)
2430 mqueue_purge(&mISDNport->upqueue);
2432 /* remove from list */
2433 mISDNportp = &mISDNport_first;
2434 while(*mISDNportp) {
2435 if (*mISDNportp == mISDNport) {
2436 *mISDNportp = (*mISDNportp)->next;
2440 mISDNportp = &((*mISDNportp)->next);
2444 FATAL("mISDNport not in list\n");
2446 FREE(mISDNport, sizeof(struct mISDNport));
2453 * enque data from upper buffer
2455 void PmISDN::txfromup(unsigned char *data, int length)
2457 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2458 struct mISDNhead *hh = (struct mISDNhead *)buf;
2461 if (p_m_b_index < 0)
2463 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2466 /* check if high priority tones exist
2467 * ignore data in this case
2469 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2472 /* preload procedure
2473 * if transmit buffer in DSP module is empty,
2474 * preload it to DSP_LOAD to prevent jitter gaps.
2476 if (p_m_load==0 && ISDN_LOAD>0) {
2477 hh->prim = PH_DATA_REQ;
2479 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2480 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2482 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
2483 p_m_load += ISDN_LOAD;
2486 /* drop if load would exceed ISDN_MAXLOAD
2487 * this keeps the delay not too high
2489 if (p_m_load+length > ISDN_MAXLOAD)
2492 /* make and send frame */
2493 hh->prim = PH_DATA_REQ;
2495 memcpy(buf+MISDN_HEADER_LEN, data, length);
2496 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2498 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
2502 int PmISDN::inband_send(unsigned char *buffer, int len)
2504 PERROR("this function must be derived to function!\n");
2508 void PmISDN::inband_send_on(void)
2510 PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2511 p_m_inband_send_on = 1;
2514 void PmISDN::inband_send_off(void)
2516 PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2517 p_m_inband_send_on = 0;
2520 void PmISDN::inband_receive(unsigned char *buffer, int len)
2523 // if (len >= SS5_DECODER_NPOINTS)
2524 // ss5_decode(buffer, SS5_DECODER_NPOINTS);
2525 PERROR("this function must be derived to function!\n");
2528 void PmISDN::inband_receive_on(void)
2530 /* this must work during constructor, see ss5.cpp */
2531 PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2532 p_m_inband_receive_on = 1;
2535 void PmISDN::inband_receive_off(void)
2537 PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2538 p_m_inband_receive_on = 0;
2541 void PmISDN::mute_on(void)
2545 PDEBUG(DEBUG_PORT, "turning mute on.\n");
2547 set_conf(p_m_conf, 0);
2550 void PmISDN::mute_off(void)
2554 PDEBUG(DEBUG_PORT, "turning mute off.\n");
2556 set_conf(0, p_m_conf);