1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 **
10 \*****************************************************************************/
15 #include <mISDN/mISDNcompat.h>
16 int __af_isdn = MISDN_AF_ISDN;
17 #include <mISDN/q931.h>
20 #ifdef __compiler_offsetof
21 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
23 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
27 #define container_of(ptr, type, member) ({ \
28 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
29 (type *)( (char *)__mptr - offsetof(type,member) );})
32 // timeouts if activating/deactivating response from mISDN got lost
33 #define B_TIMER_ACTIVATING 1 // seconds
34 #define B_TIMER_DEACTIVATING 1 // seconds
37 #if defined WITH_GSM_BS && defined WITH_GSM_MS
38 #define MISDNPORT_GSM (mISDNport->gsm_bs || mISDNport->gsm_ms)
41 #define MISDNPORT_GSM (mISDNport->gsm_bs)
44 #define MISDNPORT_GSM (mISDNport->gsm_ms)
48 #define MISDNPORT_GSM (0)
51 /* list of mISDN ports */
52 struct mISDNport *mISDNport_first;
54 /* noise randomizer */
55 unsigned char mISDN_rand[256];
56 int mISDN_rand_count = 0;
58 unsigned int mt_assign_pid = ~0;
61 static int upqueue_pipe[2];
62 static struct lcr_fd upqueue_fd;
63 int upqueue_avail = 0;
65 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i);
66 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i);
68 int mISDN_initialize(void)
72 /* try to open raw socket to check kernel */
73 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
74 if (mISDNsocket < 0) {
75 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN? Protocol family is %d.)\n", strerror(errno), PF_ISDN);
80 init_layer3(4); // buffer of 4
82 /* open debug, if enabled and not only stack debugging */
84 SPRINT(filename, "%s/debug.log", LOG_DIR);
85 debug_fp = fopen(filename, "a");
88 if (options.deb & DEBUG_STACK) {
89 SPRINT(filename, "%s/debug_mISDN.log", LOG_DIR);
90 mISDN_debug_init(0xfffffeff, filename, filename, filename);
92 mISDN_debug_init(0, NULL, NULL, NULL);
94 if (pipe(upqueue_pipe) < 0)
95 FATAL("Failed to open pipe\n");
96 memset(&upqueue_fd, 0, sizeof(upqueue_fd));
97 upqueue_fd.fd = upqueue_pipe[0];
98 register_fd(&upqueue_fd, LCR_FD_READ, mISDN_upqueue, NULL, 0);
103 void mISDN_deinitialize(void)
113 if (mISDNsocket > -1)
116 if (upqueue_fd.inuse) {
117 unregister_fd(&upqueue_fd);
118 close(upqueue_pipe[0]);
119 close(upqueue_pipe[1]);
124 int load_timer(struct lcr_timer *timer, void *instance, int index);
129 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings)
131 p_m_mISDNport = mISDNport;
132 p_m_portnum = mISDNport->portnum;
139 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
140 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
149 p_m_inband_send_on = 0;
150 p_m_inband_receive_on = 0;
151 p_m_dtmf = !mISDNport->ifport->nodtmf;
152 memset(&p_m_timeout, 0, sizeof(p_m_timeout));
153 add_timer(&p_m_timeout, mISDN_timeout, this, 0);
154 p_m_remote_ref = 0; /* channel shall be exported to given remote */
155 p_m_remote_id = 0; /* remote admin socket */
156 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
159 memset(&p_m_loadtimer, 0, sizeof(p_m_loadtimer));
160 add_timer(&p_m_loadtimer, load_timer, this, 0);
166 p_m_crypt_listen = 0;
167 p_m_crypt_msg_loops = 0;
168 p_m_crypt_msg_loops = 0;
169 p_m_crypt_msg_len = 0;
170 p_m_crypt_msg[0] = '\0';
171 p_m_crypt_msg_current = 0;
172 p_m_crypt_key_len = 0;
173 p_m_crypt_listen = 0;
174 p_m_crypt_listen_state = 0;
175 p_m_crypt_listen_len = 0;
176 p_m_crypt_listen_msg[0] = '\0';
177 p_m_crypt_listen_crc = 0;
178 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
179 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
180 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
184 /* if any channel requested by constructor */
185 if (channel == CHANNEL_ANY) {
186 /* reserve channel */
188 mISDNport->b_reserved++;
191 /* reserve channel */
192 if (channel > 0) // only if constructor was called with a channel resevation
193 seize_bchannel(channel, exclusive);
195 /* we increase the number of objects: */
197 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
198 //inband_receive_on();
207 struct lcr_msg *message;
209 del_timer(&p_m_timeout);
210 del_timer(&p_m_loadtimer);
212 /* remove bchannel relation */
216 while (p_epointlist) {
217 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
218 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
219 message->param.disconnectinfo.cause = 16;
220 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
221 message_put(message);
222 /* remove from list */
223 free_epointlist(p_epointlist);
226 /* we decrease the number of objects: */
227 p_m_mISDNport->use--;
228 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
235 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
237 /* init trace with given values */
238 start_trace(mISDNport?mISDNport->portnum:-1,
239 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
240 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
241 port?port->p_dialinginfo.id:NULL,
244 port?port->p_serial:0,
252 static struct isdn_message {
256 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
257 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
258 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
259 {"DL_RELEASE", L2_RELEASE_REQ},
260 {"UNKNOWN", L3_UNKNOWN_REQ},
261 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
262 {"MT_SETUP", L3_SETUP_REQ},
263 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
264 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
265 {"MT_ALERTING", L3_ALERTING_REQ},
266 {"MT_CONNECT", L3_CONNECT_REQ},
267 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
268 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
269 {"MT_RELEASE", L3_RELEASE_REQ},
270 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
271 {"MT_INFORMATION", L3_INFORMATION_REQ},
272 {"MT_PROGRESS", L3_PROGRESS_REQ},
273 {"MT_NOTIFY", L3_NOTIFY_REQ},
274 {"MT_SUSPEND", L3_SUSPEND_REQ},
275 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
276 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
277 {"MT_RESUME", L3_RESUME_REQ},
278 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
279 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
280 {"MT_HOLD", L3_HOLD_REQ},
281 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
282 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
283 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
284 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
285 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
286 {"MT_FACILITY", L3_FACILITY_REQ},
287 {"MT_STATUS", L3_STATUS_REQ},
288 {"MT_RESTART", L3_RESTART_REQ},
289 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
290 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
293 static const char *isdn_prim[4] = {
299 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
304 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
305 /* select message and primitive text */
307 while(isdn_message[i].name) {
308 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
309 if (isdn_message[i].value == (msg&0xffffff00)) {
310 SCPY(msgtext, isdn_message[i].name);
315 SCAT(msgtext, isdn_prim[msg&0x00000003]);
318 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
320 if (mISDNport->ntmode) {
321 if (direction == DIRECTION_OUT)
322 SCAT(msgtext, " N->U");
324 SCAT(msgtext, " N<-U");
326 if (direction == DIRECTION_OUT)
327 SCAT(msgtext, " U->N");
329 SCAT(msgtext, " U<-N");
334 /* init trace with given values */
335 start_trace(mISDNport?mISDNport->portnum:-1,
336 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
337 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
338 port?port->p_dialinginfo.id:NULL,
341 port?port->p_serial:0,
347 * send control information to the channel (dsp-module)
349 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
351 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
352 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
353 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
359 ctrl->prim = PH_CONTROL_REQ;
363 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
365 PERROR("Failed to send to socket %d\n", sock);
366 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
367 if (c1 == DSP_CONF_JOIN)
368 add_trace(trace_name, NULL, "0x%08x", trace_value);
370 add_trace(trace_name, NULL, "%d", trace_value);
374 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)
376 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
377 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
378 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
384 ctrl->prim = PH_CONTROL_REQ;
387 memcpy(d, c2, c2_len);
388 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
390 PERROR("Failed to send to socket %d\n", sock);
391 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
392 add_trace(trace_name, NULL, "%d", trace_value);
396 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i);
399 * subfunction for bchannel_event
402 static int _bchannel_create(struct mISDNport *mISDNport, int i)
405 struct sockaddr_mISDN addr;
407 if (mISDNport->b_sock[i].inuse) {
408 PERROR("Error: Socket already created for index %d\n", i);
413 //#warning testing without DSP
414 // mISDNport->b_sock[i].fd = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_HDLC:ISDN_P_B_RAW);
415 mISDNport->b_sock[i].fd = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_L2DSPHDLC:ISDN_P_B_L2DSP);
416 if (mISDNport->b_sock[i].fd < 0) {
417 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
421 /* register callback for read */
422 register_fd(&mISDNport->b_sock[i], LCR_FD_READ, b_sock_callback, mISDNport, i);
424 /* bind socket to bchannel */
425 addr.family = AF_ISDN;
426 addr.dev = mISDNport->portnum;
427 addr.channel = i+1+(i>=15);
428 ret = bind(mISDNport->b_sock[i].fd, (struct sockaddr *)&addr, sizeof(addr));
430 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);
431 close(mISDNport->b_sock[i].fd);
432 unregister_fd(&mISDNport->b_sock[i]);
436 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
437 add_trace("channel", NULL, "%d", i+1+(i>=15));
438 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
446 * subfunction for bchannel_event
447 * activate / deactivate request
449 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate, int timeout)
451 struct mISDNhead act;
454 if (!mISDNport->b_sock[i].inuse)
456 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
458 ret = sendto(mISDNport->b_sock[i].fd, &act, MISDN_HEADER_LEN, 0, NULL, 0);
460 PERROR("Failed to send to socket %d\n", mISDNport->b_sock[i].fd);
463 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
464 add_trace("channel", NULL, "%d", i+1+(i>=15));
466 add_trace("event", NULL, "timeout recovery");
472 * subfunction for bchannel_event
475 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
480 if (!mISDNport->b_sock[i].inuse)
482 handle = mISDNport->b_sock[i].fd;
483 port = mISDNport->b_port[i];
484 mode = mISDNport->b_mode[i];
486 PERROR("bchannel index i=%d not associated with a port object\n", i);
490 /* set dsp features */
491 if (port->p_m_txdata)
492 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
493 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
494 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
495 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
496 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
497 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
498 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
499 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
500 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
501 if (port->p_m_conf && !port->p_m_mute)
502 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
504 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
505 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
506 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
508 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
509 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
510 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
511 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
512 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
513 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
514 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);
518 void PmISDN::set_conf(int oldconf, int newconf)
520 if (oldconf != newconf) {
521 PDEBUG(DEBUG_BCHANNEL, "we change conference from conf=%d to conf=%d.\n", oldconf, newconf);
522 if (p_m_b_index > -1)
523 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
524 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, (newconf)?DSP_CONF_JOIN:DSP_CONF_SPLIT, newconf, "DSP-CONF", newconf);
526 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", newconf);
531 * subfunction for bchannel_event
534 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
536 if (!mISDNport->b_sock[i].inuse)
538 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
539 add_trace("channel", NULL, "%d", i+1+(i>=15));
540 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
542 close(mISDNport->b_sock[i].fd);
543 unregister_fd(&mISDNport->b_sock[i]);
551 A bchannel goes through the following states in this order:
554 No one is using the bchannel.
555 It is available and not linked to Port class, nor reserved.
558 The bchannel stack is created and an activation request is sent.
559 It MAY be linked to Port class, but already unlinked due to Port class removal.
562 The bchannel is active and cofigured to the Port class needs.
563 Also it is linked to a Port class, otherwhise it would be deactivated.
565 - B_STATE_DEACTIVATING
566 The bchannel is in deactivating state, due to deactivation request.
567 It may be linked to a Port class, that likes to reactivate it.
571 After deactivating bchannel, and if not used, the bchannel becomes idle again.
573 Also the bchannel may be exported, but only if the state is or becomes idle:
576 The bchannel assignment has been sent to the remove application.
579 The bchannel assignment is acknowledged by the remote application.
582 The bchannel is re-imported by mISDN port object.
586 After re-importing bchannel, and if not used, the bchannel becomes idle again.
589 A bchannel can have the following events:
592 A bchannel is required by a Port class.
595 The bchannel beomes active.
598 The bchannel is not required by Port class anymore
600 - B_EVENT_DEACTIVATED
601 The bchannel becomes inactive.
604 The bchannel is now used by remote application.
607 The bchannel is not used by remote application.
609 - B_EVENT_EXPORTREQUEST
610 The bchannel shall be exported to the remote application.
612 - B_EVENT_IMPORTREQUEST
613 The bchannel is released from the remote application.
615 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
617 if an export request is receive by remote application, p_m_remote_* is set.
618 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.)
619 - set on export request from remote application (if port is assigned)
620 - set on channel use, if requested by remote application (p_m_remote_*)
621 - cleared on drop request
623 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
624 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
625 the bchannel import/export is acknowledged with stack given.
627 if exporting, b_remote_*[index] is set to the remote socket id.
628 if importing has been acknowledged. b_remote_*[index] is cleared.
633 * process bchannel events
634 * - mISDNport is a pointer to the port's structure
635 * - i is the index of the bchannel
636 * - event is the B_EVENT_* value
637 * - port is the PmISDN class pointer
639 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
641 class PmISDN *b_port = mISDNport->b_port[i];
642 int state = mISDNport->b_state[i];
643 int timer = -1; // no change
644 unsigned int p_m_remote_ref = 0;
645 unsigned int p_m_remote_id = 0;
648 char *p_m_pipeline = NULL;
649 unsigned char *p_m_crypt_key = NULL;
650 int p_m_crypt_key_len = 0;
651 int p_m_crypt_key_type = 0;
652 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
655 p_m_remote_id = b_port->p_m_remote_id;
656 p_m_remote_ref = b_port->p_m_remote_ref;
657 p_m_tx_gain = b_port->p_m_tx_gain;
658 p_m_rx_gain = b_port->p_m_rx_gain;
659 p_m_pipeline = b_port->p_m_pipeline;
660 p_m_crypt_key = b_port->p_m_crypt_key;
661 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
662 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
667 /* port must be linked in order to allow activation */
669 FATAL("bchannel must be linked to a Port class\n");
672 if (p_m_remote_ref) {
673 /* export bchannel */
674 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);
675 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
676 add_trace("type", NULL, "assign");
677 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
679 state = B_STATE_EXPORTING;
680 mISDNport->b_remote_id[i] = p_m_remote_id;
681 mISDNport->b_remote_ref[i] = p_m_remote_ref;
683 /* create stack and send activation request */
684 if (_bchannel_create(mISDNport, i)) {
685 _bchannel_activate(mISDNport, i, 1, 0);
686 state = B_STATE_ACTIVATING;
687 timer = B_TIMER_ACTIVATING;
692 case B_STATE_ACTIVATING:
693 case B_STATE_EXPORTING:
694 /* do nothing, because it is already activating */
697 case B_STATE_DEACTIVATING:
698 case B_STATE_IMPORTING:
699 /* do nothing, because we must wait until we can reactivate */
703 /* problems that might ocurr:
704 * B_EVENT_USE is received when channel already in use.
705 * bchannel exported, but not freed by other port
707 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
711 case B_EVENT_EXPORTREQUEST:
712 /* special case where the bchannel is requested by remote */
713 if (!p_m_remote_ref) {
714 PERROR("export request without remote channel set, please correct.\n");
719 /* in case, the bchannel is exported right after seize_bchannel */
720 /* export bchannel */
721 /* p_m_remote_id is set, when this event happens. */
722 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);
723 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
724 add_trace("type", NULL, "assign");
725 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
727 state = B_STATE_EXPORTING;
728 mISDNport->b_remote_id[i] = p_m_remote_id;
729 mISDNport->b_remote_ref[i] = p_m_remote_ref;
732 case B_STATE_ACTIVATING:
733 case B_STATE_EXPORTING:
734 /* do nothing, because it is already activating */
737 case B_STATE_DEACTIVATING:
738 case B_STATE_IMPORTING:
739 /* do nothing, because we must wait until we can reactivate */
743 /* bchannel is active, so we deactivate */
744 _bchannel_activate(mISDNport, i, 0, 0);
745 state = B_STATE_DEACTIVATING;
746 timer = B_TIMER_DEACTIVATING;
750 /* problems that might ocurr:
751 * ... when channel already in use.
752 * bchannel exported, but not freed by other port
754 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
758 case B_EVENT_IMPORTREQUEST:
759 /* special case where the bchannel is released by remote */
760 if (p_m_remote_ref) {
761 PERROR("import request with remote channel set, please correct.\n");
767 /* bchannel is not exported */
770 case B_STATE_ACTIVATING:
771 case B_STATE_EXPORTING:
772 /* do nothing because we must wait until bchanenl is active before deactivating */
776 /* bchannel is exported, so we re-import */
777 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
778 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
779 add_trace("type", NULL, "remove");
780 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
782 state = B_STATE_IMPORTING;
785 case B_STATE_DEACTIVATING:
786 case B_STATE_IMPORTING:
787 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
791 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
795 case B_EVENT_ACTIVATED:
798 case B_STATE_ACTIVATING:
799 if (b_port && !p_m_remote_id) {
800 /* bchannel is active and used by Port class, so we configure bchannel */
801 _bchannel_configure(mISDNport, i);
802 state = B_STATE_ACTIVE;
803 b_port->p_m_load = 0;
805 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
806 _bchannel_activate(mISDNport, i, 0, 0);
807 state = B_STATE_DEACTIVATING;
808 timer = B_TIMER_DEACTIVATING;
813 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
817 case B_EVENT_EXPORTED:
819 case B_STATE_EXPORTING:
820 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) {
821 /* remote export done */
822 state = B_STATE_REMOTE;
824 /* bchannel is now exported, but we need bchannel back
825 * OR bchannel is not used anymore
826 * OR bchannel has been exported to an obsolete ref,
827 * so reimport, to later export to new remote */
828 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
829 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
830 add_trace("type", NULL, "remove");
831 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
833 state = B_STATE_IMPORTING;
838 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
844 FATAL("bchannel must be linked to a Port class\n");
847 /* bchannel is idle due to an error, so we do nothing */
850 case B_STATE_ACTIVATING:
851 case B_STATE_EXPORTING:
852 /* do nothing because we must wait until bchanenl is active before deactivating */
856 /* bchannel is active, so we deactivate */
857 _bchannel_activate(mISDNport, i, 0, 0);
858 state = B_STATE_DEACTIVATING;
859 timer = B_TIMER_DEACTIVATING;
863 /* bchannel is exported, so we re-import */
864 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
865 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
866 add_trace("type", NULL, "remove");
867 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
869 state = B_STATE_IMPORTING;
872 case B_STATE_DEACTIVATING:
873 case B_STATE_IMPORTING:
874 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
878 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
882 case B_EVENT_DEACTIVATED:
886 /* ignore due to deactivation confirm after unloading */
889 case B_STATE_DEACTIVATING:
890 _bchannel_destroy(mISDNport, i);
891 state = B_STATE_IDLE;
893 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
894 if (p_m_remote_ref) {
895 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);
896 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
897 add_trace("type", NULL, "assign");
898 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
900 state = B_STATE_EXPORTING;
901 mISDNport->b_remote_id[i] = p_m_remote_id;
902 mISDNport->b_remote_ref[i] = p_m_remote_ref;
904 if (_bchannel_create(mISDNport, i)) {
905 _bchannel_activate(mISDNport, i, 1, 0);
906 state = B_STATE_ACTIVATING;
907 timer = B_TIMER_ACTIVATING;
914 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
918 case B_EVENT_IMPORTED:
920 case B_STATE_IMPORTING:
921 state = B_STATE_IDLE;
922 mISDNport->b_remote_id[i] = 0;
923 mISDNport->b_remote_ref[i] = 0;
925 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
926 if (p_m_remote_ref) {
927 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);
928 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
929 add_trace("type", NULL, "assign");
930 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
932 state = B_STATE_EXPORTING;
933 mISDNport->b_remote_id[i] = p_m_remote_id;
934 mISDNport->b_remote_ref[i] = p_m_remote_ref;
936 if (_bchannel_create(mISDNport, i)) {
937 _bchannel_activate(mISDNport, i, 1, 0);
938 state = B_STATE_ACTIVATING;
939 timer = B_TIMER_ACTIVATING;
946 /* ignore, because not assigned */
951 case B_EVENT_TIMEOUT:
955 /* ignore due to deactivation confirm after unloading */
958 case B_STATE_ACTIVATING:
959 _bchannel_activate(mISDNport, i, 1, 1);
960 timer = B_TIMER_ACTIVATING;
963 case B_STATE_DEACTIVATING:
964 _bchannel_activate(mISDNport, i, 0, 1);
965 timer = B_TIMER_DEACTIVATING;
969 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
974 PERROR("Illegal event %d, please correct.\n", event);
977 mISDNport->b_state[i] = state;
979 unsched_timer(&mISDNport->b_timer[i]);
981 schedule_timer(&mISDNport->b_timer[i], timer, 0);
988 * check for available channel and reserve+set it.
989 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
991 * returns -(cause value) or x = channel x or 0 = no channel
992 * NOTE: no activation is done here
994 int PmISDN::seize_bchannel(int channel, int exclusive)
998 /* the channel is what we have */
999 if (p_m_b_channel == channel)
1002 /* if channel already in use, release it */
1007 if (channel==CHANNEL_NO || channel==0)
1010 /* is channel in range ? */
1012 || (channel>p_m_mISDNport->b_num && channel<16)
1013 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1014 return(-6); /* channel unacceptable */
1016 /* request exclusive channel */
1017 if (exclusive && channel>0) {
1018 i = channel-1-(channel>16);
1019 if (p_m_mISDNport->b_port[i])
1020 return(-44); /* requested channel not available */
1024 /* ask for channel */
1026 i = channel-1-(channel>16);
1027 if (p_m_mISDNport->b_port[i] == NULL)
1031 /* search for channel */
1033 while(i < p_m_mISDNport->b_num) {
1034 if (!p_m_mISDNport->b_port[i]) {
1035 channel = i+1+(i>=15);
1040 return(-34); /* no free channel */
1043 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1045 /* link Port, set parameters */
1046 p_m_mISDNport->b_port[i] = this;
1048 p_m_b_channel = channel;
1049 p_m_b_exclusive = exclusive;
1050 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1052 /* reserve channel */
1053 if (!p_m_b_reserve) {
1055 p_m_mISDNport->b_reserved++;
1062 * drop reserved channel and unset it.
1063 * deactivation is also done
1065 void PmISDN::drop_bchannel(void)
1067 /* unreserve channel */
1069 p_m_mISDNport->b_reserved--;
1073 if (p_m_b_index < 0)
1078 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1080 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1081 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1082 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1083 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1086 p_m_b_exclusive = 0;
1089 /* process bchannel export/import message from join */
1090 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1092 class Endpoint *epoint;
1094 class PmISDN *isdnport;
1095 struct mISDNport *mISDNport;
1099 case BCHANNEL_REQUEST:
1100 /* find the port object for the join object ref */
1101 if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) {
1102 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1105 if (!epoint->ep_portlist) {
1106 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1109 if (epoint->ep_portlist->next) {
1110 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);
1112 if (!(port = find_port_id(epoint->ep_portlist->port_id))) {
1113 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1116 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) {
1117 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1119 isdnport = (class PmISDN *)port;
1122 if (isdnport->p_m_remote_id) {
1123 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1126 mISDNport = isdnport->p_m_mISDNport;
1127 i = isdnport->p_m_b_index;
1128 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1129 add_trace("type", NULL, "export request");
1131 isdnport->p_m_remote_ref = joinremote->j_serial;
1132 isdnport->p_m_remote_id = joinremote->j_remote_id;
1133 if (mISDNport && i>=0) {
1134 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1138 case BCHANNEL_RELEASE:
1139 case BCHANNEL_ASSIGN_ACK:
1140 case BCHANNEL_REMOVE_ACK:
1141 /* find mISDNport for stack ID */
1142 mISDNport = mISDNport_first;
1145 ii = mISDNport->b_num;
1147 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1153 mISDNport = mISDNport->next;
1156 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1160 if (type!=BCHANNEL_RELEASE) {
1162 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1163 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1165 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1168 isdnport = mISDNport->b_port[i];
1169 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1170 add_trace("type", NULL, "import request");
1173 isdnport->p_m_remote_ref = 0;
1174 isdnport->p_m_remote_id = 0;
1176 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1180 PERROR("received wrong bchannel message type %d from remote\n", type);
1188 audio transmission procedure:
1189 -----------------------------
1192 three sources of audio transmission:
1193 - crypto-data high priority
1194 - tones high priority (also high)
1195 - remote-data low priority
1198 a variable that temporarily shows the number of samples elapsed since last transmission process.
1199 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1202 a variable that is increased whenever data is transmitted.
1203 it is decreased while time elapses. it stores the number of samples that
1204 are currently loaded to dsp module.
1205 since clock in dsp module is the same clock for user space process, these
1209 there are two levels:
1210 ISDN_LOAD will give the load that have to be kept in dsp.
1211 ISDN_MAXLOAD will give the maximum load before dropping.
1213 * procedure for low priority data
1214 see txfromup() for procedure
1215 in short: remote data is ignored during high priority tones
1217 * procedure for high priority data
1218 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1219 if no more data is available, load becomes empty again.
1222 0 ISDN_LOAD ISDN_MAXLOAD
1223 +--------------------+----------------------+
1225 +--------------------+----------------------+
1227 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1228 0 ISDN_LOAD ISDN_MAXLOAD
1229 +--------------------+----------------------+
1230 |TTTTTTTTTTTTTTTTTTTT| |
1231 +--------------------+----------------------+
1233 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1234 0 ISDN_LOAD ISDN_MAXLOAD
1235 +--------------------+----------------------+
1236 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1237 +--------------------+----------------------+
1240 void PmISDN::update_load(void)
1242 /* don't trigger load event if: */
1243 if (!p_tone_name[0] && !p_m_crypt_msg_loops && !p_m_inband_send_on)
1246 /* don't trigger load event if event already active */
1247 if (p_m_loadtimer.active)
1250 schedule_timer(&p_m_loadtimer, 0, 0); /* no delay the first time */
1253 int load_timer(struct lcr_timer *timer, void *instance, int index)
1255 class PmISDN *isdnport = (class PmISDN *)instance;
1257 isdnport->load_tx();
1262 void PmISDN::load_tx(void)
1266 struct timeval current_time;
1269 gettimeofday(¤t_time, NULL);
1270 if (p_m_last_tv_sec) {
1271 elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
1272 + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
1274 /* set clock of last process! */
1275 p_m_last_tv_sec = current_time.tv_sec;
1276 p_m_last_tv_msec = current_time.tv_usec/1000;
1278 /* process only if we have samples and we are active */
1279 if (elapsed && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
1281 if (elapsed < p_m_load)
1282 p_m_load -= elapsed;
1286 /* to send data, tone must be on */
1287 if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
1288 && (p_m_load < ISDN_LOAD) /* not too much load? */
1289 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
1290 int tosend = ISDN_LOAD - p_m_load, length;
1291 unsigned char buf[MISDN_HEADER_LEN+tosend];
1292 struct mISDNhead *frm = (struct mISDNhead *)buf;
1293 unsigned char *p = buf+MISDN_HEADER_LEN;
1295 /* copy inband signalling (e.g. used by ss5) */
1296 if (p_m_inband_send_on && tosend) {
1297 tosend -= inband_send(p, tosend);
1300 /* copy crypto loops */
1301 while (p_m_crypt_msg_loops && tosend) {
1302 /* how much do we have to send */
1303 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1306 if (length > tosend)
1309 /* copy message (part) to buffer */
1310 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1313 p_m_crypt_msg_current += length;
1314 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
1316 p_m_crypt_msg_current = 0;
1317 p_m_crypt_msg_loops--;
1318 if (!p_m_crypt_msg_loops)
1320 // puts("eine loop weniger");
1328 if (p_tone_name[0] && tosend) {
1329 tosend -= read_audio(p, tosend);
1333 if (ISDN_LOAD - p_m_load - tosend > 0) {
1334 frm->prim = PH_DATA_REQ;
1336 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1338 PERROR("Failed to send to socket %d (samples = %d)\n", p_m_mISDNport->b_sock[p_m_b_index].fd, ISDN_LOAD-p_m_load-tosend);
1339 p_m_load += ISDN_LOAD - p_m_load - tosend;
1344 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on || p_m_load) {
1345 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
1349 /* handle timeouts */
1350 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
1352 class PmISDN *isdnport = (class PmISDN *)instance;
1353 struct lcr_msg *message;
1355 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", isdnport->p_name, isdnport->p_m_timeout.timeout.tv_sec, isdnport->p_state);
1356 /* send timeout to endpoint */
1357 message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1358 message->param.state = isdnport->p_state;
1359 message_put(message);
1366 * whenever we get audio data from bchannel, we process it here
1368 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1370 unsigned int cont = *((unsigned int *)data);
1371 unsigned char *data_temp;
1372 unsigned int length_temp;
1373 struct lcr_msg *message;
1377 if (hh->prim == PH_CONTROL_IND) {
1379 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1382 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1383 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1384 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1386 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1387 message->param.dtmf = cont & DTMF_TONE_MASK;
1388 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1389 message_put(message);
1394 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1395 add_trace("DSP-CRYPT", NULL, "error");
1397 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1398 message->param.crypt.type = CC_ERROR_IND;
1399 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1400 message_put(message);
1404 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1405 add_trace("DSP-CRYPT", NULL, "ok");
1407 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1408 message->param.crypt.type = CC_ACTBF_CONF;
1409 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1410 message_put(message);
1414 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1415 add_trace("unknown", NULL, "0x%x", cont);
1420 if (hh->prim == PH_CONTROL_IND) {
1423 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1424 add_trace("unknown", NULL, "0x%x", hh->id);
1429 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1431 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1432 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1435 /* see below (same condition) */
1436 if (p_state!=PORT_STATE_CONNECT
1437 && !p_m_mISDNport->tones)
1439 // printf(".");fflush(stdout);return;
1441 record(data, len, 1); // from up
1444 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1445 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1449 /* inband is processed */
1450 if (p_m_inband_receive_on)
1451 inband_receive(data, len);
1453 /* calls will not process any audio data unless
1454 * the call is connected OR tones feature is enabled.
1456 #ifndef DEBUG_COREBRIDGE
1457 if (p_state!=PORT_STATE_CONNECT
1458 && !p_m_mISDNport->tones)
1463 /* the bearer capability must be audio in order to send and receive
1464 * audio prior or after connect.
1466 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1470 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1472 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1478 record(data, len, 0); // from down
1480 /* randomize and listen to crypt message if enabled */
1481 if (p_m_crypt_listen) {
1482 /* the noisy randomizer */
1486 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1488 cryptman_listen_bch(data, len);
1493 /* send data to epoint */
1494 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) { /* only if we have an epoint object */
1497 while(length_temp) {
1498 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1499 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1500 memcpy(message->param.data.data, data_temp, message->param.data.len);
1501 message_put(message);
1502 if (length_temp <= sizeof(message->param.data.data))
1504 data_temp += sizeof(message->param.data.data);
1505 length_temp -= sizeof(message->param.data.data);
1514 void PmISDN::set_echotest(int echo)
1516 if (p_m_echo != echo) {
1518 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1520 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1521 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_echo?DSP_ECHO_ON:DSP_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1528 void PmISDN::set_tone(const char *dir, const char *tone)
1533 /* if no directory is given (by extension), we use interface.conf or options.conf */
1534 if (!dir || !dir[0]) {
1535 if (p_m_mISDNport->ifport->tones_dir[0])
1536 dir = p_m_mISDNport->ifport->tones_dir;
1537 else if (options.tones_dir[0])
1538 dir = options.tones_dir;
1543 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1549 /* check for dsp tones */
1550 if (!strcmp(dir, "american"))
1552 if (!strcmp(dir, "german"))
1554 if (!strcmp(dir, "oldgerman"))
1555 dsp = DSP_OLDGERMAN;
1557 /* check if we NOT really have to use a dsp-tone */
1558 if (dsp == DSP_NONE) {
1561 if (p_m_b_index > -1)
1562 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) {
1563 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1564 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1567 Port::set_tone(dir, tone);
1571 /* now we USE dsp-tone, convert name */
1572 if (!strcmp(tone, "dialtone")) {
1574 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1575 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1576 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1578 } else if (!strcmp(tone, "dialpbx")) {
1580 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1581 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1582 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1584 } else if (!strcmp(tone, "ringing")) {
1586 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1587 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1588 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1590 } else if (!strcmp(tone, "ringpbx")) {
1592 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1593 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1594 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1596 } else if (!strcmp(tone, "busy")) {
1599 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1600 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1601 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1603 } else if (!strcmp(tone, "release")) {
1606 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1607 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1608 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1610 } else if (!strcmp(tone, "cause_10"))
1612 else if (!strcmp(tone, "cause_11"))
1614 else if (!strcmp(tone, "cause_22")) {
1616 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1617 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1618 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1620 } else if (!strncmp(tone, "cause_", 6))
1621 id = TONE_SPECIAL_INFO;
1625 /* if we have a tone that is not supported by dsp */
1626 if (id==TONE_OFF && tone[0])
1630 if (p_m_tone != id) {
1633 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1634 if (p_m_b_index > -1)
1635 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)
1636 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_tone?DSP_TONE_PATT_ON:DSP_TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1638 /* turn user-space tones off in cases of no tone OR dsp tone */
1639 Port::set_tone("",NULL);
1643 /* MESSAGE_mISDNSIGNAL */
1644 //extern struct lcr_msg *dddebug;
1645 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1647 int oldconf, newconf;
1648 switch(param->mISDNsignal.message) {
1649 case mISDNSIGNAL_VOLUME:
1650 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1651 p_m_tx_gain = param->mISDNsignal.tx_gain;
1652 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1653 if (p_m_b_index > -1)
1654 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)
1655 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1657 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1658 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1659 p_m_rx_gain = param->mISDNsignal.rx_gain;
1660 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1661 if (p_m_b_index > -1)
1662 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1663 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1665 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1668 case mISDNSIGNAL_CONF:
1669 oldconf = p_m_mute?0:p_m_conf;
1670 p_m_conf = param->mISDNsignal.conf;
1671 newconf = p_m_mute?0:p_m_conf;
1672 set_conf(oldconf, newconf);
1675 case mISDNSIGNAL_JOINDATA:
1676 if (p_m_joindata != param->mISDNsignal.joindata) {
1677 p_m_joindata = param->mISDNsignal.joindata;
1678 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1681 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1684 case mISDNSIGNAL_DELAY:
1685 if (p_m_delay != param->mISDNsignal.delay) {
1686 p_m_delay = param->mISDNsignal.delay;
1687 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1688 if (p_m_b_index > -1)
1689 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)
1690 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_delay?DSP_DELAY:DSP_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
1692 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1696 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1701 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1703 struct lcr_msg *message;
1705 switch(param->crypt.type) {
1706 case CC_ACTBF_REQ: /* activate blowfish */
1708 p_m_crypt_key_len = param->crypt.len;
1709 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1710 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1711 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1712 message->param.crypt.type = CC_ERROR_IND;
1713 message_put(message);
1716 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1718 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1719 if (p_m_b_index > -1)
1720 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)
1721 ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, 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);
1724 case CC_DACT_REQ: /* deactivate session encryption */
1729 case CR_LISTEN_REQ: /* start listening to messages */
1730 p_m_crypt_listen = 1;
1732 p_m_crypt_listen_state = 0;
1735 case CR_UNLISTEN_REQ: /* stop listening to messages */
1736 p_m_crypt_listen = 0;
1740 case CR_MESSAGE_REQ: /* send message */
1741 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1742 if (!p_m_crypt_msg_len) {
1743 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1746 p_m_crypt_msg_current = 0; /* reset */
1747 p_m_crypt_msg_loops = 6; /* enable */
1751 /* disable txmix, or we get corrupt data due to audio process */
1752 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1753 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1754 ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1760 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1766 * endpoint sends messages to the port
1768 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1770 if (Port::message_epoint(epoint_id, message_id, param))
1773 switch(message_id) {
1774 case MESSAGE_DATA: /* tx-data from upper layer */
1775 txfromup(param->data.data, param->data.len);
1778 case MESSAGE_mISDNSIGNAL: /* user command */
1779 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1780 message_mISDNsignal(epoint_id, message_id, param);
1783 case MESSAGE_CRYPT: /* crypt control command */
1784 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1785 message_crypt(epoint_id, message_id, param);
1792 void PmISDN::update_rxoff(void)
1794 /* call bridges in user space OR crypto OR recording */
1795 if (p_m_joindata || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
1796 /* rx IS required */
1800 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1801 if (p_m_b_index > -1)
1802 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1803 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1806 /* rx NOT required */
1810 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1811 if (p_m_b_index > -1)
1812 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1813 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1818 /* txdata IS required */
1822 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1823 if (p_m_b_index > -1)
1824 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1825 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1828 /* txdata NOT required */
1832 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1833 if (p_m_b_index > -1)
1834 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1835 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1840 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1842 struct mISDNport *mISDNport;
1848 /* unset global semaphore */
1850 // with a very small incident, upqueue_avail may be set by mISDN thread and
1851 // another byte may be sent to the pipe, which causes a call to this function
1852 // again with nothing in the upqueue. this is no problem.
1853 ret = read(fd->fd, &byte, 1);
1855 /* process all ports */
1856 mISDNport = mISDNport_first;
1858 /* handle queued up-messages (d-channel) */
1859 if (!MISDNPORT_GSM) {
1860 while ((mb = mdequeue(&mISDNport->upqueue))) {
1863 case MPH_ACTIVATE_IND:
1864 if (mISDNport->l1link != 1) {
1865 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1867 mISDNport->l1link = 1;
1871 case MPH_DEACTIVATE_IND:
1872 if (mISDNport->l1link != 0) {
1873 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1875 mISDNport->l1link = 0;
1879 case MPH_INFORMATION_IND:
1880 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1882 case L1_SIGNAL_LOS_ON:
1885 case L1_SIGNAL_LOS_OFF:
1888 case L1_SIGNAL_AIS_ON:
1891 case L1_SIGNAL_AIS_OFF:
1894 case L1_SIGNAL_RDI_ON:
1897 case L1_SIGNAL_RDI_OFF:
1900 case L1_SIGNAL_SLIP_TX:
1901 mISDNport->slip_tx++;
1903 case L1_SIGNAL_SLIP_RX:
1904 mISDNport->slip_rx++;
1909 case MT_L2ESTABLISH:
1910 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1911 add_trace("tei", NULL, "%d", l3m->pid);
1913 mISDNport->l2link = 1;
1915 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1916 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1917 if (mISDNport->l2establish.active) {
1918 unsched_timer(&mISDNport->l2establish);
1919 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1926 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1927 if (!mISDNport->l2establish.active) {
1928 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1929 add_trace("tei", NULL, "%d", l3m->pid);
1931 /* down if not nt-ptmp */
1932 if (!mISDNport->ntmode || mISDNport->ptp)
1933 mISDNport->l2link = 0;
1935 if (!MISDNPORT_GSM && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1936 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1937 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1938 schedule_timer(&mISDNport->l2establish, 5, 0);
1939 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1945 /* l3-data is sent to LCR */
1946 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1952 mISDNport = mISDNport->next;
1957 /* l2 establish timer fires */
1958 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1960 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1962 if (!MISDNPORT_GSM && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1963 // PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1964 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1965 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1971 /* handle frames from bchannel */
1972 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1974 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1975 unsigned char buffer[2048+MISDN_HEADER_LEN];
1976 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1979 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1981 PERROR("read error frame, errno %d\n", errno);
1984 if (ret < (int)MISDN_HEADER_LEN) {
1985 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1989 /* we don't care about confirms, we use rx data to sync tx */
1993 /* we receive audio data, we respond to it AND we send tones */
1998 case PH_CONTROL_IND:
1999 if (mISDNport->b_port[i])
2000 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2002 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
2005 case PH_ACTIVATE_IND:
2006 case DL_ESTABLISH_IND:
2007 case PH_ACTIVATE_CNF:
2008 case DL_ESTABLISH_CNF:
2009 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
2010 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2013 case PH_DEACTIVATE_IND:
2014 case DL_RELEASE_IND:
2015 case PH_DEACTIVATE_CNF:
2016 case DL_RELEASE_CNF:
2017 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
2018 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2022 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2028 /* process timer events for bchannel handling */
2029 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2031 struct mISDNport *mISDNport = (struct mISDNport *)instance;
2034 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2040 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2044 * l3m must be queued, except for MT_ASSIGN
2047 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2050 /* special MT_ASSIGN handling:
2052 * if we request a PID from mlayer, we always do it while lcr is locked.
2053 * therefore we must check the MT_ASSIGN reply first before we lock.
2054 * this is because the MT_ASSIGN reply is received with the requesting
2055 * process, not by the mlayer thread!
2056 * this means, that the reply is sent during call of the request.
2057 * we must check if we get a reply and we know that we lcr is currently
2060 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2061 /* let's do some checking if someone changes stack behaviour */
2062 if (mt_assign_pid != 0)
2063 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2064 mt_assign_pid = pid;
2067 /* queue message, create, if required */
2069 l3m = alloc_l3_msg();
2071 FATAL("No memory for layer 3 message\n");
2073 mb = container_of(l3m, struct mbuffer, l3);
2076 mqueue_tail(&mISDNport->upqueue, mb);
2077 if (!upqueue_avail) {
2078 // multiple threads may cause multiple calls of this section, but this
2079 // results only in multiple processing of the upqueue read.
2080 // this is no problem.
2084 ret = write(upqueue_pipe[1], &byte, 1);
2089 int mISDN_getportbyname(int sock, int cnt, char *portname)
2091 struct mISDN_devinfo devinfo;
2095 while (port < cnt) {
2097 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2100 if (!strcasecmp(devinfo.name, portname))
2111 * global function to add a new card (port)
2113 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2116 struct mISDNport *mISDNport, **mISDNportp;
2117 int port = ifport->portnum;
2118 int ptp = ifport->ptp;
2119 int force_nt = ifport->nt;
2120 int l1hold = ifport->l1hold;
2121 int l2hold = ifport->l2hold;
2123 int ss5 = ifport->ss5;
2127 // struct mlayer3 *ml3;
2128 struct mISDN_devinfo devinfo;
2129 unsigned int protocol, prop;
2131 #if defined WITH_GSM_BS && defined WITH_GSM_MS
2132 gsm = ifport->gsm_ms | ifport->gsm_bs;
2135 gsm = ifport->gsm_bs;
2138 gsm = ifport->gsm_ms;
2142 /* check port counts */
2143 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2145 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2150 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2154 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2157 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface for GSM?.\n", ifport->portname);
2159 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2162 // note: 'port' has still the port number
2164 if (port>cnt || port<0) {
2165 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2169 /* get port attributes */
2170 pri = bri = pots = nt = te = 0;
2172 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2174 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2177 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2181 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2185 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2189 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2194 if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2200 if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2205 if (force_nt && !nt) {
2206 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2210 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2213 if (pots && !bri && !pri) {
2214 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2218 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2222 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2225 /* set NT by turning off TE */
2228 /* if TE an NT is supported (and not forced to NT), turn off NT */
2232 /* check for double use of port */
2234 mISDNport = mISDNport_first;
2236 if (mISDNport->portnum == port)
2238 mISDNport = mISDNport->next;
2241 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2246 /* check for continous channelmap with no bchannel on slot 16 */
2247 if (test_channelmap(0, devinfo.channelmap)) {
2248 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2252 while(i < (int)devinfo.nrbchan + 1) {
2254 if (test_channelmap(i, devinfo.channelmap)) {
2255 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2259 if (!test_channelmap(i, devinfo.channelmap)) {
2260 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2267 /* add mISDNport structure */
2268 mISDNportp = &mISDNport_first;
2270 mISDNportp = &((*mISDNportp)->next);
2271 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2272 add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2274 /* gsm/ss5 link is always active */
2275 mISDNport->l1link = 1;
2276 mISDNport->l2link = 1;
2278 mISDNport->l1link = -1;
2279 mISDNport->l2link = -1;
2282 mISDNport->gsm_bs = ifport->gsm_bs;
2285 mISDNport->gsm_ms = ifport->gsm_ms;
2288 *mISDNportp = mISDNport;
2290 /* if pri, must set PTP */
2294 /* set ss5 params */
2296 /* try to keep interface enabled */
2316 /* allocate ressources of port */
2317 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2318 prop = (1 << MISDN_FLG_L2_CLEAN);
2319 if (ptp) // ptp forced
2320 prop |= (1 << MISDN_FLG_PTP);
2321 if (nt) // supports hold/retrieve on nt-mode
2322 prop |= (1 << MISDN_FLG_NET_HOLD);
2323 if (l1hold) // supports layer 1 hold
2324 prop |= (1 << MISDN_FLG_L1_HOLD);
2325 if (l2hold) // supports layer 2 hold
2326 prop |= (1 << MISDN_FLG_L2_HOLD);
2327 /* open layer 3 and init upqueue */
2329 #if defined WITH_GSM_BS || defined WITH_GSM_MS
2330 unsigned long on = 1;
2331 struct sockaddr_mISDN addr;
2333 if (devinfo.nrbchan < 8) {
2334 PERROR_RUNTIME("GSM port %d must have at least 8 b-channels.\n", port);
2335 mISDNport_close(mISDNport);
2339 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_NT_S0)) < 0) {
2340 PERROR_RUNTIME("GSM port %d failed to open socket.\n", port);
2341 mISDNport_close(mISDNport);
2344 /* set nonblocking io */
2345 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2346 PERROR_RUNTIME("GSM port %d failed to set socket into nonblocking io.\n", port);
2347 mISDNport_close(mISDNport);
2350 /* bind socket to dchannel */
2351 memset(&addr, 0, sizeof(addr));
2352 addr.family = AF_ISDN;
2355 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2356 PERROR_RUNTIME("GSM port %d failed to bind socket. (errno %d)\n", port, errno);
2357 mISDNport_close(mISDNport);
2362 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2363 mqueue_init(&mISDNport->upqueue);
2364 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2365 if (!mISDNport->ml3) {
2366 mqueue_purge(&mISDNport->upqueue);
2367 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2375 "PORT (open failed)");
2377 mISDNport_close(mISDNport);
2382 SCPY(mISDNport->name, devinfo.name);
2383 mISDNport->b_num = devinfo.nrbchan;
2384 mISDNport->portnum = port;
2385 mISDNport->ntmode = nt;
2386 mISDNport->tespecial = ifport->tespecial;
2387 mISDNport->pri = pri;
2388 mISDNport->ptp = ptp;
2389 mISDNport->l1hold = l1hold;
2390 mISDNport->l2hold = l2hold;
2391 mISDNport->ss5 = ss5;
2392 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2394 while(i < mISDNport->b_num) {
2395 mISDNport->b_state[i] = B_STATE_IDLE;
2396 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2400 /* if ptp, pull up the link */
2401 if (!MISDNPORT_GSM && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2402 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2403 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2404 add_trace("tei", NULL, "%d", 0);
2406 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2409 /* for nt-mode ptmp the link is always up */
2410 if (mISDNport->ntmode && !mISDNport->ptp)
2411 mISDNport->l2link = 1;
2413 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2415 start_trace(mISDNport->portnum,
2423 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2424 add_trace("channels", NULL, "%d", mISDNport->b_num);
2426 add_trace("ccitt#5", NULL, "enabled");
2434 * load static port instances, if required by mISDNport
2436 void mISDNport_static(struct mISDNport *mISDNport)
2441 while(i < mISDNport->b_num) {
2444 ss5_create_channel(mISDNport, i);
2452 * function to free ALL cards (ports)
2454 void mISDNport_close_all(void)
2456 /* free all ports */
2457 while(mISDNport_first)
2458 mISDNport_close(mISDNport_first);
2462 * free only one port
2464 void mISDNport_close(struct mISDNport *mISDNport)
2466 struct mISDNport **mISDNportp;
2468 class PmISDN *isdnport;
2471 /* remove all port instance that are linked to this mISDNport */
2475 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2476 isdnport = (class PmISDN *)port;
2477 if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2478 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2486 /* only if we are already part of interface */
2487 if (mISDNport->ifport) {
2488 start_trace(mISDNport->portnum,
2489 mISDNport->ifport->interface,
2499 /* free bchannels */
2501 while(i < mISDNport->b_num) {
2502 if (mISDNport->b_sock[i].inuse) {
2503 _bchannel_destroy(mISDNport, i);
2504 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2506 if (mISDNport->b_timer[i].inuse) {
2507 del_timer(&mISDNport->b_timer[i]);
2511 del_timer(&mISDNport->l2establish);
2513 /* close layer 3, if open */
2514 if (!MISDNPORT_GSM && mISDNport->ml3) {
2515 close_layer3(mISDNport->ml3);
2518 #if defined WITH_GSM_BS || defined WITH_GSM_MS
2519 /* close gsm socket, if open */
2520 if (MISDNPORT_GSM && mISDNport->lcr_sock > -1) {
2521 close(mISDNport->lcr_sock);
2527 mqueue_purge(&mISDNport->upqueue);
2529 /* remove from list */
2530 mISDNportp = &mISDNport_first;
2531 while(*mISDNportp) {
2532 if (*mISDNportp == mISDNport) {
2533 *mISDNportp = (*mISDNportp)->next;
2537 mISDNportp = &((*mISDNportp)->next);
2541 FATAL("mISDNport not in list\n");
2543 FREE(mISDNport, sizeof(struct mISDNport));
2550 * enque data from upper buffer
2552 void PmISDN::txfromup(unsigned char *data, int length)
2554 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2555 struct mISDNhead *hh = (struct mISDNhead *)buf;
2558 if (p_m_b_index < 0)
2560 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2563 /* check if high priority tones exist
2564 * ignore data in this case
2566 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2569 /* preload procedure
2570 * if transmit buffer in DSP module is empty,
2571 * preload it to DSP_LOAD to prevent jitter gaps.
2573 if (p_m_load == 0 && ISDN_LOAD > 0) {
2574 hh->prim = PH_DATA_REQ;
2576 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2577 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2579 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2580 p_m_load += ISDN_LOAD;
2581 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
2584 /* drop if load would exceed ISDN_MAXLOAD
2585 * this keeps the delay not too high
2587 if (p_m_load+length > ISDN_MAXLOAD)
2590 /* make and send frame */
2591 hh->prim = PH_DATA_REQ;
2593 memcpy(buf+MISDN_HEADER_LEN, data, length);
2594 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2596 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2600 int PmISDN::inband_send(unsigned char *buffer, int len)
2602 PERROR("this function must be derived to function!\n");
2606 void PmISDN::inband_send_on(void)
2608 PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2609 p_m_inband_send_on = 1;
2610 /* trigger inband transmit */
2614 void PmISDN::inband_send_off(void)
2616 PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2617 p_m_inband_send_on = 0;
2620 void PmISDN::inband_receive(unsigned char *buffer, int len)
2623 // if (len >= SS5_DECODER_NPOINTS)
2624 // ss5_decode(buffer, SS5_DECODER_NPOINTS);
2625 PERROR("this function must be derived to function!\n");
2628 void PmISDN::inband_receive_on(void)
2630 /* this must work during constructor, see ss5.cpp */
2631 PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2632 p_m_inband_receive_on = 1;
2636 void PmISDN::inband_receive_off(void)
2638 PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2639 p_m_inband_receive_on = 0;
2643 void PmISDN::mute_on(void)
2647 PDEBUG(DEBUG_PORT, "turning mute on.\n");
2649 set_conf(p_m_conf, 0);
2652 void PmISDN::mute_off(void)
2656 PDEBUG(DEBUG_PORT, "turning mute off.\n");
2658 set_conf(0, p_m_conf);