- while(mISDNport)
- {
- /* process all bchannels */
- i = 0;
- while(i < mISDNport->b_num)
- {
- /* process timer events for bchannel handling */
- if (mISDNport->b_timer[i])
- {
- if (mISDNport->b_timer[i] <= now_d)
- bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
- }
- /* handle port of bchannel */
- isdnport=mISDNport->b_port[i];
- if (isdnport)
- {
- /* call bridges in user space OR crypto OR recording */
- if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
- {
- /* rx IS required */
- if (isdnport->p_m_rxoff)
- {
- /* turn on RX */
- isdnport->p_m_rxoff = 0;
- PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
- if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
- ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
- return(1);
- }
- } else
- {
- /* rx NOT required */
- if (!isdnport->p_m_rxoff)
- {
- /* turn off RX */
- isdnport->p_m_rxoff = 1;
- PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
- if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
- ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
- return(1);
- }
- }
- /* recording */
- if (isdnport->p_record)
- {
- /* txdata IS required */
- if (!isdnport->p_m_txdata)
- {
- /* turn on RX */
- isdnport->p_m_txdata = 1;
- PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
- if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
- ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
- return(1);
- }
- } else
- {
- /* txdata NOT required */
- if (isdnport->p_m_txdata)
- {
- /* turn off RX */
- isdnport->p_m_txdata = 0;
- PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
- if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
- ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
- return(1);
- }
- }
- }
-
- /* handle message from bchannel */
- if (mISDNport->b_socket[i] > -1)
- {
- ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
- if (ret >= (int)MISDN_HEADER_LEN)
- {
- work = 1;
- switch(hh->prim)
- {
- /* we don't care about confirms, we use rx data to sync tx */
- case PH_DATA_CNF:
- break;
-
- /* we receive audio data, we respond to it AND we send tones */
- case PH_DATA_IND:
- case DL_DATA_IND:
- case PH_DATA_REQ:
- case DL_DATA_REQ:
- case PH_CONTROL_IND:
- if (mISDNport->b_port[i])
- mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
- else
- PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
- break;
-
- case PH_ACTIVATE_IND:
- case DL_ESTABLISH_IND:
- case PH_ACTIVATE_CNF:
- case DL_ESTABLISH_CNF:
- PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
- bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
- break;
-
- case PH_DEACTIVATE_IND:
- case DL_RELEASE_IND:
- case PH_DEACTIVATE_CNF:
- case DL_RELEASE_CNF:
- PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
- bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
- break;
-
- default:
- PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
- }
- } else
- {
- if (ret < 0 && errno != EWOULDBLOCK)
- PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
- }
- }
-
- i++;
- }
-