+ isdnport->load_tx();
+
+ return 0;
+}
+
+void PmISDN::load_tx(void)
+{
+ int elapsed = 0;
+ int ret;
+ struct timeval current_time;
+
+ /* get elapsed */
+ gettimeofday(¤t_time, NULL);
+ if (p_m_last_tv_sec) {
+ elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
+ + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
+ }
+ /* set clock of last process! */
+ p_m_last_tv_sec = current_time.tv_sec;
+ p_m_last_tv_msec = current_time.tv_usec/1000;
+
+ /* process only if we have samples and we are active */
+ if (elapsed && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
+ /* update load */
+ if (elapsed < p_m_load)
+ p_m_load -= elapsed;
+ else
+ p_m_load = 0;
+
+ /* to send data, tone must be on */
+ if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
+ && (p_m_load < ISDN_LOAD) /* not too much load? */
+ && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
+ int tosend = ISDN_LOAD - p_m_load, length;
+ unsigned char buf[MISDN_HEADER_LEN+tosend];
+ struct mISDNhead *frm = (struct mISDNhead *)buf;
+ unsigned char *p = buf+MISDN_HEADER_LEN;
+
+ /* copy inband signalling (e.g. used by ss5) */
+ if (p_m_inband_send_on && tosend) {
+ tosend -= inband_send(p, tosend);
+ }
+
+ /* copy crypto loops */
+ while (p_m_crypt_msg_loops && tosend) {
+ /* how much do we have to send */
+ length = p_m_crypt_msg_len - p_m_crypt_msg_current;
+
+ /* clip tosend */
+ if (length > tosend)
+ length = tosend;
+
+ /* copy message (part) to buffer */
+ memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
+
+ /* new position */
+ p_m_crypt_msg_current += length;
+ if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
+ /* next loop */
+ p_m_crypt_msg_current = 0;
+ p_m_crypt_msg_loops--;
+ if (!p_m_crypt_msg_loops)
+ update_rxoff();
+// puts("eine loop weniger");
+ }
+
+ /* new length */
+ tosend -= length;
+ }
+
+ /* copy tones */
+ if (p_tone_name[0] && tosend) {
+ tosend -= read_audio(p, tosend);
+ }
+
+ /* send data */
+ if (ISDN_LOAD - p_m_load - tosend > 0) {
+ frm->prim = PH_DATA_REQ;
+ frm->id = 0;
+ 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);
+ if (ret <= 0)
+ 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);
+ p_m_load += ISDN_LOAD - p_m_load - tosend;
+ }
+ }
+ }
+
+ if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on || p_m_load) {
+ schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
+ }
+}
+
+/* handle timeouts */
+static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
+{
+ class PmISDN *isdnport = (class PmISDN *)instance;
+ struct lcr_msg *message;
+
+ 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);
+ /* send timeout to endpoint */
+ message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
+ message->param.state = isdnport->p_state;
+ message_put(message);
+
+ return 0;
+}
+
+
+/*
+ * whenever we get audio data from bchannel, we process it here
+ */
+void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
+{
+ unsigned int cont = *((unsigned int *)data);
+ struct lcr_msg *message;
+ unsigned char *p;
+ int l;
+
+ if (hh->prim == PH_CONTROL_IND) {
+ if (len < 4) {
+ PERROR("SHORT READ OF PH_CONTROL INDICATION\n");