extern eOresult_t eo_transmitter_outpacket_Prepare(EOtransmitter *p, uint16_t *numberofrops) { uint16_t remainingbytes; if((NULL == p) || (NULL == numberofrops)) { return(eores_NOK_nullpointer); } // clear the content of the ropframe to transmit which uses the same storage of the packet ... eo_ropframe_Clear(p->ropframereadytotx); // add to it the ropframe of regulars. keep it afterwards. dont clear it !!! eov_mutex_Take(p->mtx_regulars, eok_reltimeINFINITE); eo_ropframe_Append(p->ropframereadytotx, p->ropframeregulars, &remainingbytes); eov_mutex_Release(p->mtx_regulars); // add the ropframe of occasionals ... and then clear it eov_mutex_Take(p->mtx_occasionals, eok_reltimeINFINITE); eo_ropframe_Append(p->ropframereadytotx, p->ropframeoccasionals, &remainingbytes); eo_ropframe_Clear(p->ropframeoccasionals); eov_mutex_Release(p->mtx_occasionals); // add the ropframe of replies ... and then clear it eov_mutex_Take(p->mtx_replies, eok_reltimeINFINITE); eo_ropframe_Append(p->ropframereadytotx, p->ropframereplies, &remainingbytes); eo_ropframe_Clear(p->ropframereplies); eov_mutex_Release(p->mtx_replies); *numberofrops = eo_ropframe_ROP_NumberOf(p->ropframereadytotx); return(eores_OK); }
extern eOresult_t eo_receiver_GetReply(EOreceiver *p, EOropframe **ropframereply) { if((NULL == p) || (NULL == ropframereply)) { return(eores_NOK_nullpointer); } if(0 == eo_ropframe_ROP_NumberOf(p->ropframereply)) { *ropframereply = p->ropframereply; return(eores_NOK_generic); } *ropframereply = p->ropframereply; return(eores_OK); }
extern eOresult_t eo_receiver_Process(EOreceiver *p, EOpacket *packet, uint16_t *numberofrops, eObool_t *thereisareply, eOabstime_t *transmittedtime) { uint16_t rxremainingbytes = 0; uint16_t txremainingbytes = 0; uint8_t* payload; uint16_t size; uint16_t capacity; uint16_t nrops; uint16_t i; eOresult_t res; eOipv4addr_t remipv4addr; eOipv4port_t remipv4port; uint64_t rec_seqnum; uint64_t rec_ageoframe; uint16_t numofprocessedrops = 0; if((NULL == p) || (NULL == packet)) { return(eores_NOK_nullpointer); } // clear the ropframereply w/ eo_ropframe_Clear(). the clear operation also makes it safe to manipulate p->ropframereplay with *_quickversion eo_ropframe_Clear(p->ropframereply); // we get the ip address and port of the incoming packet. // the remaddr can be any. however, if the eo_receiver_Process() is called by the EOtransceiver, it will be only the one of the remotehost eo_packet_Addressing_Get(packet, &remipv4addr, &remipv4port); // then we assign them to the ones of the EOreceiver. by doing so we force the receive to accept packets from everyboby. //p->ipv4addr = remipv4addr; //p->ipv4port = remipv4port; // retrieve payload from the incoming packet and load the ropframe with it eo_packet_Payload_Get(packet, &payload, &size); eo_packet_Capacity_Get(packet, &capacity); eo_ropframe_Load(p->ropframeinput, payload, size, capacity); // verify if the ropframeinput is valid w/ eo_ropframe_IsValid() if(eobool_false == eo_ropframe_IsValid(p->ropframeinput)) { #if defined(USE_DEBUG_EORECEIVER) { // DEBUG p->debug.rxinvalidropframes ++; } #endif p->error_invalidframe.remipv4addr = remipv4addr; p->error_invalidframe.ropframe = p->ropframeinput; s_eo_receiver_on_error_invalidframe(p); if(NULL != thereisareply) { *thereisareply = eobool_false; } return(eores_NOK_generic); } // check sequence number rec_seqnum = eo_ropframe_seqnum_Get(p->ropframeinput); rec_ageoframe = eo_ropframe_age_Get(p->ropframeinput); if(p->rx_seqnum == eok_uint64dummy) { //this is the first received ropframe or ... the sender uses dummy seqnum p->rx_seqnum = rec_seqnum; p->tx_ageofframe = rec_ageoframe; } else { if(rec_seqnum != (p->rx_seqnum+1)) { #if defined(USE_DEBUG_EORECEIVER) { p->debug.errorsinsequencenumber ++; } #endif // must set values p->error_seqnumber.remipv4addr = remipv4addr; p->error_seqnumber.rec_seqnum = rec_seqnum; p->error_seqnumber.exp_seqnum = p->rx_seqnum+1; p->error_seqnumber.timeoftxofcurrent = rec_ageoframe; p->error_seqnumber.timeoftxofprevious = p->tx_ageofframe; s_eo_receiver_on_error_seqnumber(p); } p->rx_seqnum = rec_seqnum; p->tx_ageofframe = rec_ageoframe; } nrops = eo_ropframe_ROP_NumberOf_quickversion(p->ropframeinput); for(i=0; i<nrops; i++) { // - get the rop w/ eo_ropframe_ROP_Parse() // if we have a valid ropinput the following eo_ropframe_ROP_Parse() returns OK. // in all cases rxremainingbytes contains the number of bytes we still need to parse. in case of // unrecoverable error in the ropframe res is NOK and rxremainingbytes is 0. res = eo_ropframe_ROP_Parse(p->ropframeinput, p->ropinput, &rxremainingbytes); if(eores_OK == res) { // we have a valid ropinput numofprocessedrops++; // - use the agent w/ eo_agent_InpROPprocess() and retrieve the ropreply. eo_agent_InpROPprocess(p->agent, p->ropinput, remipv4addr, p->ropreply); // - if ropreply is ok w/ eo_rop_GetROPcode() then add it to ropframereply w/ eo_ropframe_ROP_Add() if(eo_ropcode_none != eo_rop_GetROPcode(p->ropreply)) { res = eo_ropframe_ROP_Add(p->ropframereply, p->ropreply, NULL, NULL, &txremainingbytes); #if defined(USE_DEBUG_EORECEIVER) { // DEBUG if(eores_OK != res) { p->debug.lostreplies ++; } } #endif } } // we stop the decoding if rxremainingbytes has reached zero if(0 == rxremainingbytes) { break; } } if(NULL != numberofrops) { *numberofrops = numofprocessedrops; } // if any rop inside ropframereply w/ eo_ropframe_ROP_NumberOf() then sets thereisareply if(NULL != thereisareply) { *thereisareply = (0 == eo_ropframe_ROP_NumberOf(p->ropframereply)) ? (eobool_false) : (eobool_true); // dont use the quickversion because it may be that ropframereply is dummy //*thereisareply = (0 == eo_ropframe_ROP_NumberOf_quickversion(p->ropframereply)) ? (eobool_false) : (eobool_true); } if(NULL != transmittedtime) { *transmittedtime = eo_ropframe_age_Get(p->ropframeinput); } return(eores_OK); }