/** Transmit buffer over socket (non blocking). * @param[in] idx = index in tx buffer array * @return socket send result */ int ecx_outframe_red(ecx_portt *port, int idx) { HPESTATUS status; ec_comt *datagramP; ec_etherheadert *ehp; int rval; ehp = (ec_etherheadert *)&(port->txbuf[idx]); /* rewrite MAC source address 1 to primary */ ehp->sa1 = oshw_htons(priMAC[1]); /* transmit over primary socket*/ rval = ecx_outframe(port, idx, 0); if (port->redstate != ECT_RED_NONE) { ehp = (ec_etherheadert *)&(port->txbuf2); /* use dummy frame for secondary socket transmit (BRD) */ datagramP = (ec_comt*)&(port->txbuf2)[ETH_HEADERSIZE]; /* write index to frame */ datagramP->index = idx; /* rewrite MAC source address 1 to secondary */ ehp->sa1 = oshw_htons(secMAC[1]); /* transmit over secondary socket */ //send(sockhandle2, &ec_txbuf2, ec_txbuflength2 , 0); // OBS! redundant not ACTIVE for BFIN, just added to compile //ASSERT (0); hpeAttachTransmitBufferSet(port->redport->handle, port->tx_buffers[idx]); status = hpeStartTransmitter(port->redport->handle); port->redport->rxbufstat[idx] = EC_BUF_TX; } return rval; }
/** Transmit buffer over socket (non blocking). * @param[in] port = port context struct * @param[in] idx = index in tx buffer array * @return socket send result */ int ecx_outframe_red(ecx_portt *port, int idx) { ec_comt *datagramP; ec_etherheadert *ehp; int rval; ehp = (ec_etherheadert *)&(port->txbuf[idx]); /* rewrite MAC source address 1 to primary */ ehp->sa1 = oshw_htons(priMAC[1]); /* transmit over primary socket*/ rval = ecx_outframe(port, idx, 0); if (port->redstate != ECT_RED_NONE) { mtx_lock (port->tx_mutex); ehp = (ec_etherheadert *)&(port->txbuf2); /* use dummy frame for secondary socket transmit (BRD) */ datagramP = (ec_comt*)&(port->txbuf2[ETH_HEADERSIZE]); /* write index to frame */ datagramP->index = idx; /* rewrite MAC source address 1 to secondary */ ehp->sa1 = oshw_htons(secMAC[1]); /* transmit over secondary socket */ //send(sockhandle2, &ec_txbuf2, ec_txbuflength2 , 0); // OBS! redundant not ACTIVE for BFIN, just added to compile ASSERT (0); bfin_EMAC_send(&(port->txbuf2), port->txbuflength2); mtx_unlock (port->tx_mutex); port->redport->rxbufstat[idx] = EC_BUF_TX; } return rval; }
/** Transmit buffer over socket (non blocking). * @param[in] port = port context struct * @param[in] idx = index in tx buffer array * @return socket send result */ int ecx_outframe_red(ecx_portt *port, int idx) { ec_comt *datagramP; ec_etherheadert *ehp; int rval; ehp = (ec_etherheadert *)&(port->txbuf[idx]); /* rewrite MAC source address 1 to primary */ ehp->sa1 = htons(priMAC[1]); /* transmit over primary socket*/ rval = ecx_outframe(port, idx, 0); if (port->redstate != ECT_RED_NONE) { //pthread_mutex_lock( &(port->tx_mutex) ); rt_mutex_acquire(&port->tx_mutex, TM_INFINITE); ehp = (ec_etherheadert *)&(port->txbuf2); /* use dummy frame for secondary socket transmit (BRD) */ datagramP = (ec_comt*)&(port->txbuf2[ETH_HEADERSIZE]); /* write index to frame */ datagramP->index = idx; /* rewrite MAC source address 1 to secondary */ ehp->sa1 = htons(secMAC[1]); /* transmit over secondary socket */ SEND(port->redport->sockhandle, &(port->txbuf2), port->txbuflength2 , 0); //pthread_mutex_unlock( &(port->tx_mutex) ); rt_mutex_release(&port->tx_mutex); port->redport->rxbufstat[idx] = EC_BUF_TX; } return rval; }
int ec_outframe(int idx, int stacknumber) { return ecx_outframe(&ecx_port, idx, stacknumber); }
/** Blocking redundant receive frame function. If redundant mode is not active then * it skips the secondary stack and redundancy functions. In redundant mode it waits * for both (primary and secondary) frames to come in. The result goes in an decision * tree that decides, depending on the route of the packet and its possible missing arrival, * how to reroute the original packet to get the data in an other try. * * @param[in] port = port context struct * @param[in] idx = requested index of frame * @param[in] timer = absolute timeout time * @return Workcounter if a frame is found with corresponding index, otherwise * EC_NOFRAME. */ static int ecx_waitinframe_red(ecx_portt *port, int idx, osal_timert timer) { int wkc = EC_NOFRAME; int wkc2 = EC_NOFRAME; int primrx, secrx; /* if not in redundant mode then always assume secondary is OK */ if (port->redstate == ECT_RED_NONE) { wkc2 = 0; } do { /* only read frame if not already in */ if (wkc <= EC_NOFRAME) { wkc = ecx_inframe(port, idx, 0); } /* only try secondary if in redundant mode */ if (port->redstate != ECT_RED_NONE) { /* only read frame if not already in */ if (wkc2 <= EC_NOFRAME) wkc2 = ecx_inframe(port, idx, 1); } /* wait for both frames to arrive or timeout */ } while (((wkc <= EC_NOFRAME) || (wkc2 <= EC_NOFRAME)) && (osal_timer_is_expired(&timer) == FALSE)); /* only do redundant functions when in redundant mode */ if (port->redstate != ECT_RED_NONE) { /* primrx if the reveived MAC source on primary socket */ primrx = 0; if (wkc > EC_NOFRAME) { primrx = port->rxsa[idx]; } /* secrx if the reveived MAC source on psecondary socket */ secrx = 0; if (wkc2 > EC_NOFRAME) { secrx = port->redport->rxsa[idx]; } /* primary socket got secondary frame and secondary socket got primary frame */ /* normal situation in redundant mode */ if ( ((primrx == RX_SEC) && (secrx == RX_PRIM)) ) { /* copy secondary buffer to primary */ memcpy(&(port->rxbuf[idx]), &(port->redport->rxbuf[idx]), port->txbuflength[idx] - ETH_HEADERSIZE); wkc = wkc2; } /* primary socket got nothing or primary frame, and secondary socket got secondary frame */ /* we need to resend TX packet */ if ( ((primrx == 0) && (secrx == RX_SEC)) || ((primrx == RX_PRIM) && (secrx == RX_SEC)) ) { osal_timert read_timer; /* If both primary and secondary have partial connection retransmit the primary received * frame over the secondary socket. The result from the secondary received frame is a combined * frame that traversed all slaves in standard order. */ if ( (primrx == RX_PRIM) && (secrx == RX_SEC) ) { /* copy primary rx to tx buffer */ memcpy(&(port->txbuf[idx][ETH_HEADERSIZE]), &(port->rxbuf[idx]), port->txbuflength[idx] - ETH_HEADERSIZE); } osal_timer_start(&read_timer, EC_TIMEOUTRET); /* resend secondary tx */ ecx_outframe(port, idx, 1); do { /* retrieve frame */ wkc2 = ecx_inframe(port, idx, 1); } while ((wkc2 <= EC_NOFRAME) && (osal_timer_is_expired(&read_timer) == FALSE)); if (wkc2 > EC_NOFRAME) { /* copy secondary result to primary rx buffer */ memcpy(&(port->rxbuf[idx]), &(port->redport->rxbuf[idx]), port->txbuflength[idx] - ETH_HEADERSIZE); wkc = wkc2; } } } /* return WKC or EC_NOFRAME */ return wkc; }