static void enterAlohaHandleData(Node* node, AlohaData* dataPtr, Message *msg) { //UserCodeStartHandleData AlohaHeader *hdr = (AlohaHeader *) msg->packet; BOOL isACK = hdr->ACK; BOOL expectingACK = (dataPtr->mode == ALOHA_EXPECTING_ACK); //UserCodeEndHandleData if (!isACK && !expectingACK) { if (isACK ) { ERROR_ReportError("Multiple true guards found in transitions from same state."); } dataPtr->state = ALOHA_RECEIVEPACKET; enterAlohaReceivePacket(node, dataPtr, msg); return; } else if (isACK) { if (!isACK && !expectingACK ) { ERROR_ReportError("Multiple true guards found in transitions from same state."); } dataPtr->state = ALOHA_RECEIVEACK; enterAlohaReceiveACK(node, dataPtr, msg); MESSAGE_Free(node, msg); return; } else { dataPtr->state = ALOHA_IDLE_STATE; enterAlohaIdleState(node, dataPtr, msg); MESSAGE_Free(node, msg); return; } }
void NodeData::make_reTransMsg(Node* node, CcnMsg* ccnMsg) { Message* timeoutMsg; AppTimer* info; timeoutMsg = MESSAGE_Alloc( node, APP_LAYER, APP_CCN_HOST, MSG_APP_TimerExpired); MESSAGE_InfoAlloc(node, timeoutMsg, sizeof(AppTimer)); info = (AppTimer *) MESSAGE_ReturnInfo(timeoutMsg); info->connectionId = (uint64_t)ccnMsg->msg_full_name; info->sourcePort = APP_CCN_LISTEN_PORT; info->type = APP_TIMER_RE_SEND_PKT; map<uint64_t, Message*>::iterator it_msg; CcnMsgBufferMap_t::iterator it_ccnMsg; it_msg = this->cancel_reTransMsg_map.find(ccnMsg->msg_full_name); it_ccnMsg = this->reTrans_ccnMsgBuffer.find(ccnMsg->msg_full_name); if(it_msg != this->cancel_reTransMsg_map.end()) { printf("[node:%d]msg_full_name: %lu\n", node->nodeId, ccnMsg->msg_full_name); printf("[node%d][msg%lu] %d %d\n",node->nodeId, ccnMsg->msg_full_name, ccnMsg->msg_name, ccnMsg->msg_chunk_num); ERROR_ReportError("Unexpected data in cacnel_reTransMsg_map\n"); } if(it_ccnMsg != this->reTrans_ccnMsgBuffer.end()) { printf("[node:%d]msg_full_name: %lu\n", node->nodeId, ccnMsg->msg_full_name); ERROR_ReportError("Unexpected data in reTrans_ccnMsgBuffer\n"); } this->cancel_reTransMsg_map.insert(pair<uint64_t, Message*>(ccnMsg->msg_full_name, timeoutMsg)); this->reTrans_ccnMsgBuffer.insert(pair<uint64_t, CcnMsg*>(ccnMsg->msg_full_name, this->NewCcnMsg(ccnMsg))); MESSAGE_Send(node, timeoutMsg, 2 * SECOND); }
void NodeData::release_windowSize(Node* node, CcnMsg* ccnMsg) { Cur_WindowSize_t::iterator it; it = this->cur_windowSize.find(ccnMsg->msg_name); if(it != this->cur_windowSize.end()) { if(it->second < 0) { ERROR_ReportError("error: window size is Zero\n"); } it->second--; } else { printf("[node%d][msg%lu] release window size error\n", node->nodeId, ccnMsg->msg_full_name); ERROR_ReportError("error: no window size\n"); } }
void NodeData::fibMapInput(Node* node, const char* filename) { ifstream ifs; ifs.open(filename); if(!ifs) { ERROR_ReportError("error: cannot open file\n"); } int sourceNodeId, destNodeId, nextNodeId; string str; while(getline(ifs, str)) { sscanf(str.data(), "%d:%d %d\n", &sourceNodeId, &destNodeId, &nextNodeId); if(sourceNodeId != node->nodeId) { continue; } this->fibMap.insert(pair<int, int>(destNodeId, nextNodeId)); } ifs.close(); //fujiwara fibの書き方とか確かめるためのデバッガ printf("sorceNodeID "); cout<< sourceNodeId <<endl; FibMap_t::iterator itr; for(itr=fibMap.begin();itr!=fibMap.end();itr++) { printf("キー "); cout<< itr->first << endl; printf("値 "); cout<< itr->second << endl; } }
bool NodeData::pitModSend(Node* node, CcnMsg* ccnMsg) { PitModMap_t::iterator it; it = this->pitModMap.find(ccnMsg->msg_full_name); this->recvModMapRemove(node, ccnMsg); // 最初のfakeDataを受け取ったら転送 if(isNotSent_fakeData(node, ccnMsg)) { if(it == this->pitModMap.end()) { ERROR_ReportError("error: next node info is not found in in PIT\n"); } //if(this->node_role == RELAY_NODE) //printf("[node%d]->[node%d][msg%lu] forward fakeData %d %d\n",node->nodeId, it->second, ccnMsg->msg_full_name, ccnMsg->msg_name, ccnMsg->msg_chunk_num); this->tcpOpenConnection(node, NewCcnMsg(ccnMsg), fakeData, it->second); } // すべてのfakeDataを受け取ったらpitModMapを削除 if(isRecvAll_fakeData(node, ccnMsg)) { it = this->pitModMap.find(ccnMsg->msg_full_name); this->pitModMap.erase(it); //if(this->node_role == RELAY_NODE) //printf("[node%d][msg%lu] deletemsg %d %d\n",node->nodeId, ccnMsg->msg_full_name, ccnMsg->msg_name, ccnMsg->msg_chunk_num); this->csDelete(ccnMsg->msg_full_name); this->lruDelete(ccnMsg->msg_full_name); } return true; }
// software. This source code and certain of the algorithms contained // within it are confidential trade secrets of Scalable Network // Technologies, Inc. and may not be used as the basis for any other // software, hardware, product or service. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include "api.h" #include "antenna.h" #include "antenna_switched.h" #include "antenna_steerable.h" #include "cellular.h" #include "phy_cellular.h" #ifdef UMTS_LIB #include "cellular_umts.h" #include "phy_umts.h" #endif #ifdef MUOS_LIB #include "cellular_muos.h" #include "phy_muos.h" #endif #define DEBUG 0 // /** // FUNCTION :: PhyCellularInit // LAYER :: PHY // PURPOSE :: Initialize the Cellular PHY // PARAMETERS :: // + node : Node* : Pointer to node. // + phyIndex : const int : Index of the PHY // + nodeInput : const NodeInput* : Pointer to the node input // RETURN :: void : NULL // **/ void PhyCellularInit(Node *node, const int phyIndex, const NodeInput *nodeInput) { Address interfaceAddress; char buf[MAX_STRING_LENGTH]; BOOL retVal; PhyCellularData *phyCellular = (PhyCellularData*) MEM_malloc(sizeof(PhyCellularData)); phyCellular->thisPhy = node->phyData[phyIndex]; node->phyData[phyIndex]->phyVar = ( void* )phyCellular; // generate initial seed RANDOM_SetSeed(phyCellular->randSeed, node->globalSeed, node->nodeId, PHY_CELLULAR, phyIndex); if (DEBUG) { printf("node %d: Cellular Phy Init\n", node->nodeId); } NetworkGetInterfaceInfo(node, phyCellular->thisPhy->macInterfaceIndex, &interfaceAddress); IO_ReadString( node, node->nodeId, phyCellular->thisPhy->macInterfaceIndex, nodeInput, "CELLULAR-PHY-MODEL", &retVal, buf); if (retVal == FALSE) { ERROR_ReportError("CELLULAR-PHY-MODEL parameter" " was not found for node"); } if (strcmp(buf, "PHY-ABSTRACT-CELLULAR") == 0) { if (DEBUG) { printf("node %d: Calling Abstract Cellular Phy Init\n", node->nodeId); } phyCellular->cellularPhyProtocolType = Cellular_ABSTRACT_Phy; } else if (strcmp(buf, "PHY-GSM") == 0) { if (DEBUG) { printf("node %d: GSM Cellular Phy init\n",node->nodeId); } phyCellular->cellularPhyProtocolType = Cellular_GSM_Phy; } else if (strcmp(buf, "PHY-GPRS") == 0) { if (DEBUG) { printf("node %d: GPRS Cellular Phy init\n",node->nodeId); } phyCellular->cellularPhyProtocolType = Cellular_GPRS_Phy; } else if (strcmp(buf, "PHY-UMTS") == 0) { #if defined(UMTS_LIB) phyCellular->cellularPhyProtocolType = Cellular_UMTS_Phy; PhyUmtsInit(node, phyIndex, nodeInput); #else ERROR_ReportMissingLibrary("PHY-UMTS", "UMTS"); #endif } else if (strcmp(buf, "PHY-MUOS") == 0) { #if defined(MUOS_LIB) phyCellular->cellularPhyProtocolType = Cellular_MUOS_Phy; PhyMuosInit(node, phyIndex, nodeInput); #else ERROR_ReportMissingLibrary("PHY-MUOS", "MUOS"); #endif } else if (strcmp(buf, "PHY-CDMA2000") == 0) { if (DEBUG) { printf("node %d: CDMA2000 Cellular PHY init\n",node->nodeId); } phyCellular->cellularPhyProtocolType = Cellular_CDMA2000_Phy; } else if (strcmp(buf, "PHY-WIMAX") == 0) { if (DEBUG) { printf("node %d: WIMAX Cellular PHY init\n",node->nodeId); } phyCellular->cellularPhyProtocolType = Cellular_WIMAX_Phy; } else { ERROR_ReportError( "CELLULAR-PHY-MODEL parameter must be ABSTRACT-CELLULAR-PHY," " PHY-GSM, PHY-GPRS, PHY-UMTS, PHY-CDMA2000" " or PHY-WIMAX"); } IO_ReadString( node->nodeId, ANY_DEST, nodeInput, "CELLULAR-STATISTICS", &retVal, buf); if ((retVal == FALSE) || (strcmp(buf, "YES") == 0)) { phyCellular->collectStatistics = TRUE; } else if (retVal && strcmp(buf, "NO") == 0) { phyCellular->collectStatistics = FALSE; } else { ERROR_ReportWarning( "Value of CELLULAR-STATISTICS should be YES or NO! " "Default value YES is used."); phyCellular->collectStatistics = TRUE; } } // /** // FUNCTION :: PhyCellularFinalize // LAYER :: PHY // PURPOSE :: Finalize the Cellular PHY, print out statistics // PARAMETERS :: // + node : Node* : Pointer to node. // + phyIndex : const int : Index of the PHY // RETURN :: void : NULL // **/ void PhyCellularFinalize(Node *node, const int phyIndex) { if (DEBUG) { printf("node %d: Cellular Phy Finalize\n",node->nodeId); } PhyCellularData *phyCellular = (PhyCellularData*)node->phyData[phyIndex]->phyVar; switch(phyCellular->cellularPhyProtocolType) { case Cellular_ABSTRACT_Phy: { break; } case Cellular_GSM_Phy: { break; } case Cellular_GPRS_Phy: { break; } case Cellular_UMTS_Phy: { #ifdef UMTS_LIB PhyUmtsFinalize(node, phyIndex); break; #else ERROR_ReportMissingLibrary("PHY-UMTS", "UMTS"); #endif } case Cellular_MUOS_Phy: { #ifdef MUOS_LIB PhyMuosFinalize(node, phyIndex); break; #else ERROR_ReportMissingLibrary("PHY-MUOS", "MUOS"); #endif } case Cellular_CDMA2000_Phy: { break; } case Cellular_WIMAX_Phy: { break; } default: { ERROR_ReportError( "CELLULAR-PHY-PROTOCOL parameter must be" " ABSTRACT-CELLULAR-PHY," " GSM-PHY, GPRS-PHY, UMTS-PHY, CDMA2000-PHY" " or WIMAX-PHY"); } } MEM_free(phyCellular); node->phyData[phyIndex]->phyVar = NULL; } // /** // FUNCTION :: PhyCellularStartTransmittingSignal // LAYER :: PHY // PURPOSE :: Start transmitting a frame // PARAMETERS :: // + node : Node* : Pointer to node. // + phyIndex : int : Index of the PHY // + packet : Message* : Frame to be transmitted // + clocktype : duration : Duration of the transmission // + useMacLayerSpecifiedDelay : Use MAC specified delay or calculate it // + initDelayUntilAirborne : clocktype : The MAC specified delay // RETURN :: void : NULL // **/ void PhyCellularStartTransmittingSignal( Node* node, int phyIndex, Message* packet, clocktype duration, BOOL useMacLayerSpecifiedDelay, clocktype initDelayUntilAirborne) { if (DEBUG) { printf("node %d: Cellular Phy start TXing\n",node->nodeId); } PhyCellularData *phyCellular = (PhyCellularData*)node->phyData[phyIndex]->phyVar; switch(phyCellular->cellularPhyProtocolType) { case Cellular_ABSTRACT_Phy: { break; } case Cellular_GSM_Phy: { break; } case Cellular_GPRS_Phy: { break; } case Cellular_UMTS_Phy: { #ifdef UMTS_LIB PhyUmtsStartTransmittingSignal( node, phyIndex, packet, duration, useMacLayerSpecifiedDelay, initDelayUntilAirborne); break; #else ERROR_ReportMissingLibrary("PHY-UMTS", "UMTS"); #endif } case Cellular_MUOS_Phy: { #ifdef MUOS_LIB PhyMuosStartTransmittingSignal( node, phyIndex, packet, duration, useMacLayerSpecifiedDelay, initDelayUntilAirborne); break; #else ERROR_ReportMissingLibrary("PHY-MUOS", "MUOS"); #endif } case Cellular_CDMA2000_Phy: { break; } case Cellular_WIMAX_Phy: { break; } default: { ERROR_ReportError( "CELLULAR-PHY-PROTOCOL parameter must be" " ABSTRACT-CELLULAR-PHY," " GSM-PHY, GPRS-PHY, UMTS-PHY, CDMA2000-PHY" " or WIMAX-PHY"); } } } // /** // FUNCTION :: PhyCellularTransmissionEnd // LAYER :: PHY // PURPOSE :: End of the transmission // PARAMETERS :: // + node : Node* : Pointer to node. // + phyIndex : int : Index of the PHY // RETURN :: void : NULL // **/ void PhyCellularTransmissionEnd( Node* node, int phyIndex) { if (DEBUG) { printf("node %d: Cellular Phy Transmission End\n",node->nodeId); } PhyCellularData *phyCellular = (PhyCellularData*)node->phyData[phyIndex]->phyVar; switch(phyCellular->cellularPhyProtocolType) { case Cellular_ABSTRACT_Phy: { break; } case Cellular_GSM_Phy: { break; } case Cellular_GPRS_Phy: { break; } case Cellular_UMTS_Phy: { #ifdef UMTS_LIB PhyUmtsTransmissionEnd(node, phyIndex); break; #else ERROR_ReportMissingLibrary("PHY-UMTS", "UMTS"); #endif } case Cellular_MUOS_Phy: { #ifdef MUOS_LIB PhyMuosTransmissionEnd(node, phyIndex); break; #else ERROR_ReportMissingLibrary("PHY-MUOS", "MUOS"); #endif } case Cellular_CDMA2000_Phy: { break; } case Cellular_WIMAX_Phy: { break; } default: { ERROR_ReportError( "CELLULAR-PHY-PROTOCOL parameter must be" " ABSTRACT-CELLULAR-PHY," " GSM-PHY, GPRS-PHY, UMTS-PHY, CDMA2000-PHY" " or WIMAX-PHY"); } } } // /** // FUNCTION :: PhyCellularSignalArrivalFromChannel // LAYER :: PHY // PURPOSE :: Handle signal arrival from the chanel // PARAMETERS :: // + node : Node* : Pointer to node. // + phyIndex : int : Index of the PHY // + channelIndex : int : Index of the channel receiving signal from // + propRxInfo : PropRxInfo* : Propagation information // RETURN :: void : NULL // **/ void PhyCellularSignalArrivalFromChannel( Node* node, int phyIndex, int channelIndex, PropRxInfo* propRxInfo) { if (DEBUG) { printf("node %d: Cellular Phy Signal Arrival From Channel\n", node->nodeId); } PhyCellularData *phyCellular = (PhyCellularData*)node->phyData[phyIndex]->phyVar; switch(phyCellular->cellularPhyProtocolType) { case Cellular_ABSTRACT_Phy: { break; } case Cellular_GSM_Phy: { break; } case Cellular_GPRS_Phy: { break; } case Cellular_UMTS_Phy: { #ifdef UMTS_LIB PhyUmtsSignalArrivalFromChannel( node, phyIndex, channelIndex, propRxInfo); break; #else ERROR_ReportMissingLibrary("PHY-UMTS", "UMTS"); #endif } case Cellular_MUOS_Phy: { #ifdef MUOS_LIB PhyMuosSignalArrivalFromChannel( node, phyIndex, channelIndex, propRxInfo); break; #else ERROR_ReportMissingLibrary("PHY-MUOS", "MUOS"); #endif } case Cellular_CDMA2000_Phy: { break; } case Cellular_WIMAX_Phy: { break; } default: { ERROR_ReportError( "CELLULAR-PHY-PROTOCOL parameter must be" " ABSTRACT-CELLULAR-PHY," " GSM-PHY, GPRS-PHY, UMTS-PHY, CDMA2000-PHY" " or WIMAX-PHY"); } } } // /** // FUNCTION :: PhyCellularSignalEndFromChannel // LAYER :: PHY // PURPOSE :: Handle signal end from a chanel // PARAMETERS :: // + node : Node* : Pointer to node. // + phyIndex : int : Index of the PHY // + channelIndex : int : Index of the channel receiving signal from // + propRxInfo : PropRxInfo* : Propagation information // RETURN :: void : NULL // **/ void PhyCellularSignalEndFromChannel( Node* node, int phyIndex, int channelIndex, PropRxInfo* propRxInfo) { if (DEBUG) { printf("node %d: Cellular Phy Signal End From Channel\n", node->nodeId); } PhyCellularData *phyCellular = (PhyCellularData*)node->phyData[phyIndex]->phyVar; switch(phyCellular->cellularPhyProtocolType) { case Cellular_ABSTRACT_Phy: { break; } case Cellular_GSM_Phy: { break; } case Cellular_GPRS_Phy: { break; } case Cellular_UMTS_Phy: { #ifdef UMTS_LIB PhyUmtsSignalEndFromChannel( node, phyIndex, channelIndex, propRxInfo); break; #else ERROR_ReportMissingLibrary("PHY-UMTS", "UMTS"); #endif } case Cellular_MUOS_Phy: { #ifdef MUOS_LIB PhyMuosSignalEndFromChannel( node, phyIndex, channelIndex, propRxInfo); break; #else ERROR_ReportMissingLibrary("PHY-MUOS", "MUOS"); #endif } case Cellular_CDMA2000_Phy: { break; } case Cellular_WIMAX_Phy: { break; } default: { ERROR_ReportError( "CELLULAR-PHY-PROTOCOL parameter must be" " ABSTRACT-CELLULAR-PHY," " GSM-PHY, GPRS-PHY, UMTS-PHY, CDMA2000-PHY" " or WIMAX-PHY"); } } } PhyStatusType PhyCellularGetStatus( Node* node, int phyNum) { return (PhyStatusType)1; } void PhyCellularSetTransmitPower( Node* node, PhyData* thisPhy, double newTxPower_mW) { } void PhyCellularGetTransmitPower( Node* node, PhyData* thisPhy, double* txPower_mW) { } clocktype PhyCellularGetTransmissionDuration( Node* node, int size, int dataRate) { return (clocktype)1; } int PhyCellularGetDataRate( Node* node, PhyData* thisPhy) { return 1; } float PhyCellularGetRxLevel( Node* node, int phyIndex) { return 1.0; } double PhyCellularGetRxQuality( Node* node, int phyIndex) { return 1.0; } // /** // FUNCTION :: PhyCellularInterferenceArrivalFromChannel // LAYER :: PHY // PURPOSE :: Handle signal arrival from the chanel // PARAMETERS :: // + node : Node* : Pointer to node. // + phyIndex : int : Index of the PHY // + channelIndex : int : Index of the channel receiving signal from // + propRxInfo : PropRxInfo* : Propagation information // + sigPower_mW : double : The inband interference signal power // RETURN :: void : NULL // **/ void PhyCellularInterferenceArrivalFromChannel( Node* node, int phyIndex, int channelIndex, PropRxInfo* propRxInfo, double sigPower_mW) { PhyCellularData *phyCellular = (PhyCellularData*)node->phyData[phyIndex]->phyVar; switch(phyCellular->cellularPhyProtocolType) { case Cellular_ABSTRACT_Phy: { break; } case Cellular_GSM_Phy: { break; } case Cellular_GPRS_Phy: { break; } case Cellular_UMTS_Phy: { #ifdef UMTS_LIB PhyUmtsInterferenceArrivalFromChannel( node, phyIndex, channelIndex, propRxInfo, sigPower_mW); break; #else ERROR_ReportMissingLibrary("PHY-UMTS", "UMTS"); #endif } case Cellular_CDMA2000_Phy: { break; } case Cellular_WIMAX_Phy: { break; } default: { ERROR_ReportError( "CELLULAR-PHY-PROTOCOL parameter must be" " ABSTRACT-CELLULAR-PHY," " GSM-PHY, GPRS-PHY, UMTS-PHY, CDMA2000-PHY" " or WIMAX-PHY"); } } }
int NodeData::fibFind(Node* node, CcnMsg* ccnMsg) { FibMap_t::iterator it; it = this->fibMap.find(ccnMsg->source_node_id); if(it == this->fibMap.end()) { ERROR_ReportError("error: next node was not found in FIB table\n"); } return it->second; }
void NodeData::fibSend_PROPOSAL(Node* node, CcnMsg* ccnMsg) { FibMap_t::iterator it; it = this->fibMap.find(ccnMsg->source_node_id); if(it == this->fibMap.end()) { ERROR_ReportError("error: next node was not found in FIB table\n"); } this->tcpOpenConnection(node, ccnMsg, Interest, it->second); }
void NodeData::csDelete(uint64_t msg_full_name) { CsMap_t::iterator it = this->csMap.find(msg_full_name); if(it != this->csMap.end()) { this->csMap.erase(it); } else { printf("msg_full_name = %lu\n", msg_full_name); ERROR_ReportError("not found\n"); } }
void ZigbeeAppInitTrace(Node* node, const NodeInput* nodeInput) { char buf[MAX_STRING_LENGTH]; BOOL retVal; BOOL traceAll = TRACE_IsTraceAll(node); BOOL trace = FALSE; BOOL writeMap = TRUE; IO_ReadString(node->nodeId, ANY_ADDRESS, nodeInput, "TRACE-ZIGBEEAPP", &retVal, buf); if (retVal) { if (strcmp(buf, "YES") == 0) { trace = TRUE; } else if (strcmp(buf, "NO") == 0) { trace = FALSE; } else { ERROR_ReportError( "TRACE-ZIGBEEAPP should be either \"YES\" or \"NO\".\n"); } } else { if (traceAll || node->traceData->layer[TRACE_APPLICATION_LAYER]) { trace = TRUE; } } if (trace) { TRACE_EnableTraceXML(node, TRACE_ZIGBEEAPP, "ZIGBEEAPP", ZigbeeAppPrintTraceXML, writeMap); } else { TRACE_DisableTraceXML(node, TRACE_ZIGBEEAPP, "ZIGBEEAPP", writeMap); } writeMap = FALSE; }
uint8_t NodeData::return_windowSize(CcnMsg* ccnMsg) { Cur_WindowSize_t::iterator it; it = this->cur_windowSize.find(ccnMsg->msg_name); if(it != this->cur_windowSize.end()) { return it->second; } else { ERROR_ReportError("no chunk information\n"); } }
void STAT_AggregatedStatistic::SetIteratorPath(std::string& path) { if (m_Statistics.size() > 0) { ERROR_ReportError( "Aggregated statistics path may not be used with AddStatistic"); } m_IteratorPath = path; }
void NodeData::lruRefresh(uint64_t msg_full_name) { CsLru_t::iterator it; for(it = this->csLru.begin(); it != this->csLru.end(); it++) { if(*it == msg_full_name) { this->csLru.erase(it); this->csLru.insert(this->csLru.begin(), msg_full_name); return; } } ERROR_ReportError("LRU refresh error\n"); }
void NodeData::send_reTransMsg(Node* node, uint64_t msg_full_name) { map<uint64_t, Message*>::iterator it_msg; CcnMsgBufferMap_t::iterator it_ccnMsg; it_msg = this->cancel_reTransMsg_map.find(msg_full_name); it_ccnMsg = this->reTrans_ccnMsgBuffer.find(msg_full_name); if(it_msg == this->cancel_reTransMsg_map.end()) { printf("[node:%d]msg_full_name: %lu\n", node->nodeId, msg_full_name); ERROR_ReportError("Not found resend msg "); } if(it_ccnMsg == this->reTrans_ccnMsgBuffer.end()) { printf("[node:%d]msg_full_name: %lu\n", node->nodeId, msg_full_name); ERROR_ReportError("Not found cancel ccnMsg"); } CcnMsg* ccnMsg; ccnMsg = it_ccnMsg->second; ccnMsg->resent_times++; CcnMsg* copy_ccnMsg; copy_ccnMsg = this->NewCcnMsg(ccnMsg); if(ccnMsg->resent_times > 3) { if(ccnMsg->content_type == VideoData) { printf("[node%d][chunk_num%d] re-send limit over\n", node->nodeId, ccnMsg->msg_chunk_num); this->statData->packet_lostTimes++; // this is not lost but unacquired } MESSAGE_CancelSelfMsg(node, it_msg->second); return; } this->cancel_reTransMsg_map.erase(it_msg); this->reTrans_ccnMsgBuffer.erase(it_ccnMsg); this->make_reTransMsg(node, copy_ccnMsg); this->fibSend(node, ccnMsg); }
void AlohaProcessEvent(Node* node, int interfaceIndex, Message* msg) { AlohaData* dataPtr; int event; dataPtr = (AlohaData*) node->macData[interfaceIndex]->macVar; event = msg->eventType; BOOL msgReuse = FALSE; switch (dataPtr->state) { case ALOHA_IDLE_STATE: switch (event) { case MSG_MAC_TimerExpired: dataPtr->state = ALOHA_RETRANSMIT; enterAlohaRetransmit(node, dataPtr, msg); break; case MSG_MAC_CheckTransmit: dataPtr->state = ALOHA_CHECKTRANSMIT; msgReuse = enterAlohaCheckTransmit(node, dataPtr, msg); break; default: assert(FALSE); } break; case ALOHA_HANDLEDATA: assert(FALSE); break; case ALOHA_RETRANSMIT: assert(FALSE); break; case ALOHA_RECEIVEPACKET: assert(FALSE); break; case ALOHA_TRANSMIT: assert(FALSE); break; case ALOHA_CHECKTRANSMIT: assert(FALSE); break; case ALOHA_RECEIVEACK: assert(FALSE); break; default: ERROR_ReportError("Illegal transition"); break; } if (msgReuse == FALSE) { MESSAGE_Free(node, msg); } }
void NodeData::Cancel_reTransMsg(Node* node, uint64_t msg_full_name) { map<uint64_t, Message*>::iterator it_msg; CcnMsgBufferMap_t::iterator it_ccnMsg; Message* timeoutMsg; it_msg = this->cancel_reTransMsg_map.find(msg_full_name); it_ccnMsg = this->reTrans_ccnMsgBuffer.find(msg_full_name); if(it_msg == this->cancel_reTransMsg_map.end()) { printf("[node%d][chunk_num%lu] \n", node->nodeId, msg_full_name); ERROR_ReportError("Not found cancel msg"); } if(it_ccnMsg == this->reTrans_ccnMsgBuffer.end()) { printf("[node%d][chunk_num%lu] \n", node->nodeId, msg_full_name); ERROR_ReportError("Not found cancel ccnMsg"); } timeoutMsg = it_msg->second; MESSAGE_CancelSelfMsg(node, timeoutMsg); this->cancel_reTransMsg_map.erase(it_msg); this->reTrans_ccnMsgBuffer.erase(it_ccnMsg); }
uint64_t NodeData::BufferPush(Node* node, CcnMsg* ccnMsg) { uint64_t freeNum; CcnMsgBufferMap_t::iterator it; for(freeNum = this->currentBufferNumber + 1; freeNum != this->currentBufferNumber; freeNum++) { it = this->ccnMsgBuffer.find(freeNum); if(it == this->ccnMsgBuffer.end()) { this->ccnMsgBuffer.insert(pair<uint64_t, CcnMsg*>(freeNum, ccnMsg)); this->currentBufferNumber = freeNum; return freeNum; } } ERROR_ReportError("No free space for ccnMsgBuffer\n"); }
CcnMsg* NodeData::BufferRetrieve_Client(Node* node, Message* msg) { TransportToAppOpenResult* openResult; openResult = (TransportToAppOpenResult*) MESSAGE_ReturnInfo(msg); CcnMsgBufferMap_t::iterator it; it = this->ccnMsgBuffer.find(openResult->uniqueId); if(it == this->ccnMsgBuffer.end()) { ERROR_ReportError("node open unexist msg from ccnMsgBuffer\n"); } CcnMsg* ccnMsg; ccnMsg = it->second; this->ccnMsgBuffer.erase(it); return ccnMsg; }
CcnMsg* NodeData::BufferRetrieve_Host(Node* node, Message* msg) { uint64_t ccnMsgMapKey; char* payload; payload = (char*)MESSAGE_ReturnPacket(msg); memcpy(&ccnMsgMapKey, &payload[0], sizeof(uint64_t)); CcnMsgBufferMap_t::iterator it; it = this->ccnMsgBuffer.find(ccnMsgMapKey); if(it == this->ccnMsgBuffer.end()) { ERROR_ReportError("node requests unexist msg from ccnMsgBuffer\n"); } CcnMsg* ccnMsg; ccnMsg = it->second; this->ccnMsgBuffer.erase(it); return ccnMsg; }
//------------------------------------------------------------------------- // FUNCTION TRANSPORT_Initialize // PURPOSE Initialization function for the TRANSPORT layer. // // Parameters: // node: node being initialized. // nodeInput: structure containing contents of input file //------------------------------------------------------------------------- void TRANSPORT_Initialize(Node * node, const NodeInput * nodeInput) { BOOL wasFound = FALSE; char buf[MAX_STRING_LENGTH]; node->transportData.tcpType = TCP_REGULAR; node->transportData.tcp = NULL; node->transportData.udp = NULL; TransportTcpInit(node, nodeInput); TransportUdpInit(node, nodeInput); // // Initialize RSVP. // IO_ReadString( node->nodeId, ANY_ADDRESS, nodeInput, "TRANSPORT-PROTOCOL-RSVP", &wasFound, buf); if (!wasFound || strcmp(buf, "YES") == 0) { // Defaults to use RSVP when parameter not found. node->transportData.rsvpProtocol = TRUE; // RsvpInit(node, nodeInput); } else if (strcmp(buf, "NO") == 0) { node->transportData.rsvpProtocol = FALSE; } else { ERROR_ReportError("Expecting YES or NO for " "TRANSPORT-PROTOCOL-RSVP parameter\n"); } // InsertPatch TRANSPORT_INIT_CODE }
// Macro to turn an address type into a string std::string STAT_AddrToString(STAT_DestAddressType type) { if (type == STAT_Unicast) { return std::string("Unicast"); } else if (type == STAT_Broadcast) { return std::string("Broadcast"); } else if (type == STAT_Multicast) { return std::string("Multicast"); } else { ERROR_ReportError("Not a valid address type"); return std::string(""); // To remove warning } }
// Copyright (c) 2001-2013, SCALABLE Network Technologies, Inc. All Rights Reserved. // 600 Corporate Pointe // Suite 1200 // Culver City, CA 90230 // [email protected] // // This source code is licensed, not sold, and is subject to a written // license agreement. Among other things, no portion of this source // code may be copied, transmitted, disclosed, displayed, distributed, // translated, used as the basis for a derivative work, or used, in // whole or in part, for any program or purpose other than its intended // use in compliance with the license agreement as part of the QualNet // software. This source code and certain of the algorithms contained // within it are confidential trade secrets of Scalable Network // Technologies, Inc. and may not be used as the basis for any other // software, hardware, product or service. #include "prop_cost_hata.h" // /** // FUNCTION :: COST231_HataInitialize // LAYER :: Physical Layer. // PURPOSE :: Initialize COST 231 Hata Propagation Models // PARAMETERS :: // + propChannel: PropChannel* : Pointer to Propagation Channel data-struct // + channelIndex: Int: Channel Index // + nodeInput: NodeInput*: Pointer to Node Input // RETURN :: void : NULL // // **/ void COST231_HataInitialize( PropChannel *propChannel, int channelIndex, const NodeInput *nodeInput) { BOOL wasFound; char propagationenvironment[MAX_STRING_LENGTH]; PropProfile* propProfile = propChannel->profile; IO_ReadStringInstance( ANY_NODEID, ANY_ADDRESS, nodeInput, "PROPAGATION-COST231-HATA-ENVIRONMENT", channelIndex, (channelIndex == 0), &wasFound, propagationenvironment); if (wasFound) { if (strcmp(propagationenvironment, "SUBURBAN") == 0) { propProfile->propagationEnvironment = SUBURBAN; } else if (strcmp(propagationenvironment, "URBAN") == 0) { propProfile->propagationEnvironment = URBAN; } else { ERROR_ReportError("Unrecognized propagation environment\n"); } } else { propProfile->propagationEnvironment = DEFAULT_PROPAGATION_COST231_HATA_ENVIRONMENT; } return; }
void STAT_Statistic::AddToHierarchy(D_Hierarchy* h, std::string& path) { // No path if statistic is not dynamically enabled if (h->IsEnabled()) { m_Value.SetStatistic(this); try { h->CreatePath(path); h->AddObject( path, new D_StatisticObj(&m_Value), GetDescription()); } catch (D_Exception& e) { std::string err; e.GetFullErrorString(err); ERROR_ReportError((char*) err.c_str()); } } }
//------------------------------------------------------------------------- // FUNCTION TRANSPORT_ProcessEvent // PURPOSE Models the behaviour of the TRANSPORT Layer on receiving the // message // // Parameters: // node: node which received the message // msg: message received by the layer //------------------------------------------------------------------------- void TRANSPORT_ProcessEvent(Node * node, Message * msg) { switch (MESSAGE_GetProtocol(msg)) { case TransportProtocol_UDP: { TransportUdpLayer(node, msg); break; } case TransportProtocol_TCP: { TransportTcpLayer(node, msg); break; } case TransportProtocol_RSVP: { #ifdef ENTERPRISE_LIB if (node->transportData.rsvpProtocol == FALSE) { // MPLS module is not enabled on this node. Just ignore it. // Free the message. MESSAGE_Free(node, msg); } else { RsvpLayer(node, msg); } break; #else // ENTERPRISE_LIB ERROR_ReportError("ENTERPRISE addon missing"); #endif // ENTERPRISE_LIB } //InsertPatch LAYER_FUNCTION default: assert(FALSE); abort(); break; }//switch// }
void AppLayerCCNHost(Node* node, Message* msg) { NodeData* nodeData; nodeData = (NodeData*)node->appData.nodeData; switch(msg->eventType) { /*//fujiwara// * 1. 移動を検知したらMR(interest)を作成してPoAとHOMEにおくる * 2. MR(data)を受け取ったら * さらに分岐 case hand_over_kenchi //やることを書く { clocktype send_delayTime; uint32_t chunk_num; map<uint32_t, clocktype>::iterator it; uint32_t next_msgName = global_node_data->return_MsgName(); uint32_t end_chunk_num = next_msgName % 40 + 10; CcnMsg* ccnMsg; ccnMsg = new CcnMsg(); ccnMsg->resent_times = 0; ccnMsg->ccn_method = DEFAULT; ccnMsg->msg_type = Interest; ccnMsg->msg_name = next_msgName; //msg_nameはよくわからない 多分解析のときにわかりやすくする狙いか? ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1; ccnMsg->EncodeFullNameMsg(); ccnMsg->sender_node_id = node->nodeId; // node->nodeid = このメッセージを送るノードのID ccnMsg->source_node_id = source_node_id; //ここを変更 source_node_id = 送信先ノード(現状サーバが一個しかとれない仕様……) ccnMsg->payload_length = 30; //ペイロードはヘッダを除いたデータ部分の大きさ ccnMsg->hops_limit = 20; ccnMsg->content_type = CommonData; ccnMsg->end_chunk_num = end_chunk_num; ccnMsg->interest_genTime = node->getNodeTime(); ccnMsg->data_genTime = node->getNodeTime(); nodeData->set_lastChunkNum(ccnMsg); //chunkの最後の値を記録 よくわからない 必要? nodeData->reqMapInput(node, ccnMsg); //msg_full_nameとノードのシミュレーション時間のペアを記録する nodeData->fibSend_DEFAULT(node, ccnMsg);//送信 nodeData->make_reTransMsg(node, ccnMsg);//再送の話 よくわからない 必要か? }*/ case MSG_APP_FromTransDataReceived: // データ受け取り時 { TransportToAppDataReceived *openResult; openResult = (TransportToAppDataReceived*) MESSAGE_ReturnInfo(msg); APP_TcpCloseConnection(node, openResult->connectionId); // msgからccnメッセージを取得 // ccnメッセージを処理 // データ送信の場合、TCP接続要求を送る // msgのキーからccnメッセージを取り出す CcnMsg* ccnMsg; ccnMsg = nodeData->BufferRetrieve_Host(node, msg); Node* remote_node; NodeData* remote_nodeData; remote_node = MAPPING_GetNodePtrFromHash(GlobalNodeData::nodeHash, ccnMsg->previous_node_id); remote_nodeData = (NodeData*)remote_node->appData.nodeData; // パケットロストによる取得エラー if(nodeData->node_role + remote_nodeData->node_role == CLIENT + RELAY_NODE) { if((rand() * 100.0) < (nodeData->error_rate * RAND_MAX)) { //printf("packet lost occured at %d->%d\n", remote_node->nodeId, node->nodeId); //nodeData->statData->packet_lostTimes++; if(ccnMsg->ccn_method == PROPOSAL && (ccnMsg->msg_type == Interest || ccnMsg->msg_type == Data)){ } else if(ccnMsg->ccn_method == PRIOR) { nodeData->statData->packet_lostTimes++; // this is not lost but unacquired break; } else { break; } } } nodeData->StatisticalInfo_recvCcnMsg(node, ccnMsg); // ホップカウント(loop検出用) if(!ccnMsg->checkHopCount()) { printf("hop count is over\n"); break; } switch(ccnMsg->ccn_method) { case DEFAULT: case DEFAULT_FAST: { switch(ccnMsg->msg_type) { case Interest: { // ソースノードまで転送 // PITに名前を記録(msg_full_name) // ソースノードならDataパケットを返送 // 返送する際はPITを参照 if(nodeData->pitInsert_DEFAULT(node, ccnMsg)) { // PITで登録済み delete ccnMsg; break; } if(nodeData->csSend(node, ccnMsg) == true) { // キャッシュヒット if(ccnMsg->content_type == CommonData) { nodeData->StatisticalInfo_cacheHit(node, ccnMsg); } break; } // ソースノード到着 if(ccnMsg->source_node_id == node->nodeId) { // InterestをDataに変換 nodeData->convertInterest_intoData(ccnMsg); // Dataの送信時間設定 clocktype send_delayTime; if(ccnMsg->content_type == VideoData) { map<uint32_t, clocktype>::iterator it; it = nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num); send_delayTime = it->second - node->getNodeTime(); } else { send_delayTime = 0; } // PITで設定時間に則った送信 if(send_delayTime < 0) { nodeData->pitSend_DEFAULT(node, ccnMsg); } else { nodeData->pitSend_DEFAULT(node, ccnMsg, send_delayTime); } } else { // FIBによるフォワーディング nodeData->fibSend_DEFAULT(node, ccnMsg); } break; } // Interest case Data: { //if(ccnMsg->content_type == CommonData) { // nodeData->statData->commonPacket_recv++; // nodeData->statData->commonPacketSize_recv += ccnMsg->payload_length; //} else if(ccnMsg->content_type == VideoData) { // nodeData->statData->videoPacket_recv++; // nodeData->statData->videoPacketSize_recv += ccnMsg->payload_length; //} if(nodeData->reqMapSearch(node, ccnMsg)) { if(ccnMsg->content_type == CommonData) { nodeData->statData->request_commonPacket_recv++; nodeData->statData->request_commonPacketSize_recv += ccnMsg->payload_length; } else if(ccnMsg->content_type == VideoData) { nodeData->statData->request_videoPacket_recv++; nodeData->statData->request_videoPacketSize_recv += ccnMsg->payload_length; } // PROPOSAL再送での誤爆回避 if(nodeData->ccn_method == PROPOSAL) { if(ccnMsg->content_type == VideoData) { nodeData->Cancel_reTransMsg(node, ccnMsg->msg_full_name); nodeData->recvRequestData(node, ccnMsg); // Statistical data delete ccnMsg; break; } } // 再送パケットは次のパケットを要求しないため、ここで終了 if(ccnMsg->resent_times > 0) { if(ccnMsg->content_type == VideoData) { if(nodeData->ccn_method == DEFAULT) { nodeData->Cancel_reTransMsg(node, ccnMsg->msg_full_name); nodeData->recvRequestData(node, ccnMsg); // Statistical data delete ccnMsg; break; } else if(nodeData->ccn_method == DEFAULT_FAST) { nodeData->Cancel_reTransMsg(node, ccnMsg->msg_full_name); nodeData->recvRequestData(node, ccnMsg); // Statistical data delete ccnMsg; break; } } } // 未取得chunkを取得 if(nodeData->ccn_method == DEFAULT_FAST) { if(ccnMsg->content_type == VideoData) { if(ccnMsg->msg_chunk_num > nodeData->return_lastRecvMsg(ccnMsg) + 1) { CcnMsg* t_ccnMsg; t_ccnMsg = nodeData->NewCcnMsg(ccnMsg); t_ccnMsg->msg_chunk_num = nodeData->return_lastRecvMsg(ccnMsg) + 1; t_ccnMsg->EncodeFullNameMsg(); t_ccnMsg->payload_length = 30; t_ccnMsg->resent_times = 1; t_ccnMsg->msg_type = Interest; t_ccnMsg->hops_limit = 20; nodeData->reqMapSearch(node, t_ccnMsg); nodeData->reqMapInput(node, t_ccnMsg); nodeData->Cancel_reTransMsg(node, t_ccnMsg->msg_full_name); nodeData->make_reTransMsg(node, t_ccnMsg); Node* source_node; map<uint32_t, clocktype>::iterator it; source_node = MAPPING_GetNodePtrFromHash(GlobalNodeData::nodeHash, source_node_id); nodeData->source_nodeData = (NodeData*)source_node->appData.nodeData; NodeData* source_nodeData; source_nodeData = nodeData->source_nodeData; it = source_nodeData->dataGenerateTime_map.find(t_ccnMsg->msg_chunk_num); t_ccnMsg->data_genTime = it->second; nodeData->set_windowSize(node, t_ccnMsg); nodeData->fibSend(node, t_ccnMsg); } } } nodeData->release_windowSize(node, ccnMsg); nodeData->set_lastRecvMsg(ccnMsg); nodeData->Cancel_reTransMsg(node, ccnMsg->msg_full_name); nodeData->recvRequestData(node, ccnMsg); // Statistical data if(ccnMsg->end_chunk_num < nodeData->return_lastChunkNum(ccnMsg) + 1) { delete ccnMsg; break; } // クライアントにData到着 ccnMsg->msg_type = Interest; ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1; ccnMsg->EncodeFullNameMsg(); ccnMsg->resent_times = 0; ccnMsg->payload_length = 30; ccnMsg->hops_limit = 20; ccnMsg->interest_genTime = node->getNodeTime(); map<uint32_t, clocktype>::iterator it; it = nodeData->source_nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num); ccnMsg->data_genTime = it->second; nodeData->set_lastChunkNum(ccnMsg); nodeData->set_windowSize(node, ccnMsg); nodeData->make_reTransMsg(node, ccnMsg); nodeData->reqMapInput(node, ccnMsg); nodeData->fibSend(node, ccnMsg); break; } nodeData->csInsert_DEFAULT(node, ccnMsg); nodeData->pitSend_DEFAULT(node, ccnMsg); break; } default: { ERROR_ReportError("Undefined msg type\n"); } } break; } case PRIOR: { switch(ccnMsg->msg_type) { case Interest: { // ソースノードまで転送 // PITに名前を記録(msg_name) // ソースノードならDataパケットを返送 // またDataパケットを一定時間ごとに生成・転送 // 返送する際はPITを参照 if(nodeData->csSend(node, ccnMsg) == true) { // キャッシュヒット nodeData->StatisticalInfo_cacheHit(node, ccnMsg); break; } if(nodeData->pitInsert_PRIOR(node, ccnMsg)) { // PITで登録済み delete ccnMsg; break; } if(ccnMsg->source_node_id == node->nodeId) { nodeData->convertInterest_intoData(ccnMsg); nodeData->set_lastChunkNum(ccnMsg); APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_DATA_SEND_PKT, 0 * MILLI_SECOND); } else { nodeData->fibSend_PRIOR(node, ccnMsg); } break; } case Data: { if(nodeData->reqMapSearch_PRIOR(node, ccnMsg)) { nodeData->recvRequestData(node, ccnMsg); // Statistical data delete ccnMsg; break; } nodeData->pitSend_PRIOR(node, ccnMsg); break; } default: ERROR_ReportError("Undefined msg type\n"); } break; } case PROPOSAL: { switch(ccnMsg->msg_type) { case Interest: { nodeData->fibModInsert(node, ccnMsg, ccnMsg->previous_node_id); if(nodeData->pitInsert_PROPOSAL(node, ccnMsg)) { // PITで登録済み delete ccnMsg; break; } if(ccnMsg->source_node_id == node->nodeId) { nodeData->set_lastChunkNum(ccnMsg); nodeData->convertInterest_intoData(ccnMsg); nodeData->pitSend_PROPOSAL(node, ccnMsg); // プッシュ配信登録 APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_fakeINTEREST_SEND_PKT, 0 * MILLI_SECOND); } else { nodeData->fibSend_PROPOSAL(node, ccnMsg); } break; } case Data: { if(nodeData->reqMapSearch(node, ccnMsg)) { nodeData->recvRequestData(node, ccnMsg); // Statistical data // プッシュ配信登録済みクライアントであることを記録 nodeData->reqModMapInput(node, ccnMsg); delete ccnMsg; break; } nodeData->pitSend_PROPOSAL(node, ccnMsg); break; } case fakeInterest: { nodeData->pitModInsert(node, ccnMsg); nodeData->csModInsert(node, ccnMsg); if(nodeData->node_role == CLIENT) if(ccnMsg->msg_name != msg_videoData_name + node->nodeId%3) printf("[node%d][msg%lu] fuckfuckfuck %d %d\n",node->nodeId, ccnMsg->msg_full_name, ccnMsg->msg_name, ccnMsg->msg_chunk_num); if(nodeData->reqModMapSearch(node, ccnMsg)) { // クライアント到着 nodeData->recvRequestData(node, ccnMsg); // Statistical data nodeData->recvModMapInsert(node, ccnMsg); nodeData->convertFakeInterest_intoFakeData(ccnMsg); nodeData->pitModSend(node, ccnMsg); // 未取得chunkを取得 if(ccnMsg->msg_chunk_num > nodeData->return_lastRecvMsg(ccnMsg) + 1) { CcnMsg* ccnMsg; ccnMsg = new CcnMsg(); ccnMsg->resent_times = 1; ccnMsg->ccn_method = DEFAULT; ccnMsg->msg_type = Interest; ccnMsg->msg_name = msg_videoData_name + node->nodeId % 3; ccnMsg->msg_chunk_num = nodeData->return_lastRecvMsg(ccnMsg) + 1; ccnMsg->EncodeFullNameMsg(); ccnMsg->sender_node_id = node->nodeId; ccnMsg->source_node_id = source_node_id; ccnMsg->payload_length = 30; ccnMsg->hops_limit = 20; ccnMsg->interest_genTime = node->getNodeTime(); ccnMsg->content_type = VideoData; ccnMsg->end_chunk_num = UINT16_MAX; Node* source_node; map<uint32_t, clocktype>::iterator it; source_node = MAPPING_GetNodePtrFromHash(GlobalNodeData::nodeHash, source_node_id); nodeData->source_nodeData = (NodeData*)source_node->appData.nodeData; NodeData* source_nodeData; source_nodeData = nodeData->source_nodeData; it = source_nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num); ccnMsg->data_genTime = it->second; nodeData->reqMapSearch(node, ccnMsg); nodeData->set_windowSize(node, ccnMsg); nodeData->reqMapInput(node, ccnMsg); nodeData->make_reTransMsg(node, ccnMsg); nodeData->fibSend(node, ccnMsg); } else if (ccnMsg->msg_chunk_num == nodeData->return_lastRecvMsg(ccnMsg) + 1){ //printf("Got actual packet\n"); } else { } nodeData->set_lastRecvMsg(ccnMsg); break; } if(nodeData->fibModSend(node, ccnMsg)) { delete ccnMsg; break; } break; } case fakeData: { // クライアントにデータ到着 if(ccnMsg->source_node_id == node->nodeId) { delete ccnMsg; break; } nodeData->pitModSend(node, ccnMsg); break; } default: ERROR_ReportError("Undefined msg type\n"); } break; } default: ERROR_ReportError("Undefined ccn_method\n"); } break; } case MSG_APP_FromTransOpenResult: // TCPでpassive open処理が終了 //if(node->nodeId == 1) printf("openResult->connectionId: %lu\n", openResult->connectionId); break; case MSG_APP_FromTransListenResult: // コネクション要求待機状態を確立 //if(node->nodeId == 1) printf("openResult->connectionId: %lu\n", openResult->connectionId); break; case MSG_APP_TimerExpired: { AppTimer* timer; timer = (AppTimer *)MESSAGE_ReturnInfo(msg); switch(timer->type) { case APP_TIMER_RE_SEND_PKT: nodeData->send_reTransMsg(node, timer->connectionId); break; } break; } case MSG_APP_FromTransCloseResult: break; default: printf("msg->eventType = %d\n", msg->eventType); ERROR_ReportError("msg->eventType error: undefined eventType\n"); } MESSAGE_Free(node, msg); }
void AppCCNNodeInit(Node* node, NodeRole role, const NodeInput *nodeInput) { char str[MAX_STRING_LENGTH]; BOOL wasFound = FALSE; if(global_node_data == NULL) { global_node_data = new GlobalNodeData(); } global_node_data->setMaxNodeId(node->nodeId); // nodeDataポインタをnodeに保存 // nodeDataはノードでのccnMsgの取り扱いを担う NodeData* nodeData; nodeData = (NodeData*) node->appData.nodeData; if(nodeData == NULL) { nodeData = new NodeData(node, nodeInput); node->appData.nodeData = nodeData; } nodeData->node_role = role; //FIB input nodeData->fibMapInput(node, "fib.conf"); // ハンドラの登録 APP_RegisterNewApp(node, APP_CCN_HOST, nodeData); // TCP受信準備 Address node_addr; node_addr = MAPPING_GetDefaultInterfaceAddressInfoFromNodeId(node, node->nodeId, NETWORK_IPV4); APP_TcpServerListen(node, APP_CCN_HOST, node_addr, (short) APP_CCN_LISTEN_PORT); std::ofstream ofs(nodeData->name_logFile.c_str()); ofs << "node->getNodeTime()" << ", " << "generateToRecv_Delay" << ", " << "sendToRecv_Delay" << ", " << "ccnMsg->msg_chunk_num" << std::endl; // ノードの役割ごとに初期設定 switch(role) { // クライアント case CLIENT: { // timer message送信 // ライブストリーミング if(nodeData->ccn_method != NO_VIDEO) { APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_SEND_PKT, 800 * MILLI_SECOND); } // 通常コンテンツ APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_REGULAR_SEND_PKT, 1 * SECOND + 10 * MILLI_SECOND * node->nodeId); break; } // 中継ノード case RELAY_NODE: { break; } // ソースノード case SERVER: { source_node_id = node->nodeId; uint32_t chunk_num; clocktype generateTime; generateTime = 0; double randNum; for(chunk_num = 0; chunk_num < 100000; chunk_num++) { generateTime += nodeData->return_packetRandomGenerateTime(); nodeData->dataGenerateTime_map.insert(pair<uint32_t, clocktype>(chunk_num, generateTime)); randNum = (double) (1.0 / (RAND_MAX + 1.0)) * rand(); nodeData->randomNum_map.insert(pair<uint32_t, double>(chunk_num, randNum)); } break; } default: ERROR_ReportError(""); } }
void AppLayerCCNClient(Node* node, Message* msg) { NodeData* nodeData; nodeData = (NodeData*)node->appData.nodeData; Node* source_node; source_node = MAPPING_GetNodePtrFromHash(GlobalNodeData::nodeHash, source_node_id); nodeData->source_nodeData = (NodeData*)source_node->appData.nodeData; NodeData* source_nodeData; source_nodeData = nodeData->source_nodeData; switch(msg->eventType) { // タイマーメッセージ case MSG_APP_TimerExpired: // タイマーメッセージ { AppTimer* timer; timer = (AppTimer *)MESSAGE_ReturnInfo(msg); // timer messageの種類によって処理を分ける switch(timer->type) { case APP_TIMER_SEND_PKT: { printf("この表示がなければ、APP_TIMER_SEND_PKTはビデオストリーミング確定 "); clocktype send_delayTime; uint32_t chunk_num; map<uint32_t, clocktype>::iterator it; chunk_num = 0; do { chunk_num++; it = source_nodeData->dataGenerateTime_map.find(chunk_num); if(it == source_nodeData->dataGenerateTime_map.end()) { ERROR_ReportError("dataGenerateTime_map error\n"); } send_delayTime = it->second - node->getNodeTime(); } while(send_delayTime < 0); nodeData->set_lastChunkNum(msg_videoData_name + node->nodeId % 3, chunk_num - 1); nodeData->set_lastRecvMsg(msg_videoData_name + node->nodeId % 3, chunk_num - 1); CcnMsg* ccnMsg; do { ccnMsg = new CcnMsg(); ccnMsg->ccn_method = nodeData->ccn_method; ccnMsg->resent_times = 0; ccnMsg->msg_type = Interest; ccnMsg->msg_name = msg_videoData_name + node->nodeId % 3; ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1; ccnMsg->EncodeFullNameMsg(); ccnMsg->sender_node_id = node->nodeId; ccnMsg->source_node_id = source_node_id; ccnMsg->payload_length = 30; ccnMsg->hops_limit = 20; ccnMsg->interest_genTime = node->getNodeTime(); ccnMsg->content_type = VideoData; ccnMsg->end_chunk_num = UINT32_MAX; it = source_nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num); ccnMsg->data_genTime = it->second; nodeData->set_lastChunkNum(ccnMsg); nodeData->fibSend(node, ccnMsg); if(ccnMsg->ccn_method == DEFAULT) { nodeData->make_reTransMsg(node, ccnMsg); nodeData->set_lastRecvMsg(msg_videoData_name + node->nodeId % 3, UINT32_MAX - 3); nodeData->reqMapInput(node, ccnMsg); } else if(ccnMsg->ccn_method == DEFAULT_FAST) { nodeData->make_reTransMsg(node, ccnMsg); nodeData->set_lastRecvMsg(msg_videoData_name + node->nodeId % 3, UINT32_MAX - 3); nodeData->reqMapInput(node, ccnMsg); } else if(ccnMsg->ccn_method == PRIOR) { nodeData->reqMapInput_PRIOR(node, ccnMsg); break; } else if(ccnMsg->ccn_method == PROPOSAL) { nodeData->set_lastRecvMsg(msg_videoData_name + node->nodeId % 3, UINT32_MAX - 1); nodeData->reqMapInput(node, ccnMsg); //printf("[node%d][msg%d] sendInterest\n", node->nodeId, ccnMsg->msg_name); break; } } while(nodeData->set_windowSize(node, ccnMsg)); break; } // APP_TIMER_SEND_PKT case APP_TIMER_DATA_SEND_PKT: { printf("この表示がなければ、APP_TIMER_DATA_SEND_PKTはいらない子。てかどうやってここはいるんだ… "); CcnMsg* ccnMsg; for(int i = 0; i < 3; i++) { ccnMsg = new CcnMsg(); ccnMsg->resent_times = 0; ccnMsg->ccn_method = PRIOR; ccnMsg->msg_type = Data; ccnMsg->msg_name = msg_videoData_name + i; ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1; ccnMsg->EncodeFullNameMsg(); ccnMsg->sender_node_id = node->nodeId; ccnMsg->source_node_id = source_node_id; ccnMsg->payload_length = nodeData->tcp_mss; ccnMsg->hops_limit = 20; ccnMsg->interest_genTime = node->getNodeTime(); ccnMsg->content_type = VideoData; ccnMsg->end_chunk_num = UINT32_MAX; map<uint32_t, clocktype>::iterator it; it = nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num); ccnMsg->data_genTime = it->second; clocktype send_delayTime; send_delayTime = ccnMsg->data_genTime - node->getNodeTime(); if(send_delayTime < 0) send_delayTime = 0; nodeData->set_lastChunkNum(ccnMsg); nodeData->pitSend_PRIOR(node, nodeData->NewCcnMsg(ccnMsg), send_delayTime); APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_DATA_SEND_PKT, send_delayTime); } delete ccnMsg; break; } // APP_TIMER_DATA_SEND_PKT case APP_TIMER_fakeINTEREST_SEND_PKT: { printf("この表示がなければ、APP_TIMER_fakeINTEREST_SEND_PKTはいらない子。てかここどうやって入るんだ… "); // 動画の配信分をすべて出す CcnMsg* ccnMsg; for(int i = 0; i < 3; i++) { ccnMsg = new CcnMsg(); ccnMsg->resent_times = 0; ccnMsg->ccn_method = PROPOSAL; ccnMsg->msg_type = fakeInterest; ccnMsg->msg_name = msg_videoData_name + i; ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1; ccnMsg->EncodeFullNameMsg(); ccnMsg->sender_node_id = node->nodeId; ccnMsg->source_node_id = source_node_id; ccnMsg->payload_length = nodeData->tcp_mss; ccnMsg->hops_limit = 20; ccnMsg->interest_genTime = node->getNodeTime(); ccnMsg->content_type = VideoData; ccnMsg->end_chunk_num = UINT32_MAX; map<uint32_t, clocktype>::iterator it; it = nodeData->dataGenerateTime_map.find(ccnMsg->msg_chunk_num); ccnMsg->data_genTime = it->second; clocktype send_delayTime; send_delayTime = ccnMsg->data_genTime - node->getNodeTime(); if(send_delayTime < 0) send_delayTime = 0; nodeData->set_lastChunkNum(ccnMsg); nodeData->fibModSend(node, nodeData->NewCcnMsg(ccnMsg), send_delayTime); APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_fakeINTEREST_SEND_PKT, send_delayTime); } delete ccnMsg; break; } // APP_TIMER_fakeINTEREST_SEND_PKT case APP_TIMER_REGULAR_SEND_PKT: { //printf("この表示は 予想ではたくさんでる。APP_TIMER_REGULAR_SEND_PKT\n"); clocktype send_delayTime; uint32_t chunk_num; map<uint32_t, clocktype>::iterator it; uint32_t next_msgName = global_node_data->return_MsgName(); uint32_t end_chunk_num = next_msgName % 40 + 10; CcnMsg* ccnMsg; do { ccnMsg = new CcnMsg(); ccnMsg->resent_times = 0; ccnMsg->ccn_method = DEFAULT; ccnMsg->msg_type = Interest; ccnMsg->msg_name = next_msgName; ccnMsg->msg_chunk_num = nodeData->return_lastChunkNum(ccnMsg) + 1; ccnMsg->EncodeFullNameMsg(); ccnMsg->sender_node_id = node->nodeId; ccnMsg->source_node_id = source_node_id; ccnMsg->payload_length = 30; ccnMsg->hops_limit = 20; ccnMsg->content_type = CommonData; ccnMsg->end_chunk_num = end_chunk_num; ccnMsg->interest_genTime = node->getNodeTime(); ccnMsg->data_genTime = node->getNodeTime(); nodeData->set_lastChunkNum(ccnMsg); nodeData->reqMapInput(node, ccnMsg); nodeData->fibSend_DEFAULT(node, ccnMsg); nodeData->make_reTransMsg(node, ccnMsg); if(ccnMsg->msg_chunk_num > ccnMsg->end_chunk_num) break; } while(nodeData->set_windowSize(node, ccnMsg)); APP_SetTimer(node, APP_CCN_CLIENT, 0, APP_CCN_LISTEN_PORT, APP_TIMER_REGULAR_SEND_PKT, nodeData->commonPacketGenerateTime); break; } // APP_TIMER_REGULAR_SEND_PKT default: ERROR_ReportError("Undefined timer type\n"); } break; } // MSG_APP_TimerExpired case MSG_APP_FromTransOpenResult: // TCPでactive open処理が完了 { // データ送信処理 // 送信データの操作は出来る限りHostの処理にしておく // ここでは送信処理だけ TransportToAppOpenResult *openResult; openResult = (TransportToAppOpenResult*) MESSAGE_ReturnInfo(msg); //TCPコネクションが不成立時(失敗) if (openResult->connectionId < 0) { char buf[MAX_STRING_LENGTH]; ctoa(node->getNodeTime(),buf); node->appData.numAppTcpFailure++; break; } // バッファーからccnメッセージを取り出し CcnMsg* ccnMsg; ccnMsg = nodeData->BufferRetrieve_Client(node, msg); nodeData->StatisticalInfo_sendCcnMsg(node, ccnMsg); ccnMsg->App_TcpSendCcnMsg(node, msg); break; } // MSG_APP_FromTransOpenResult case MSG_APP_FromTransDataSent: // TCPでデータ転送終了 TransportToAppDataSent *openResult; openResult = (TransportToAppDataSent*) MESSAGE_ReturnInfo(msg); APP_TcpCloseConnection(node, openResult->connectionId); break; case MSG_APP_FromTransCloseResult: break; default: ERROR_ReportError("msg->eventType error: undefined eventType\n"); } MESSAGE_Free(node, msg); }
/* * FUNCTION MacTdmaInit * PURPOSE Initialization function for TDMA protocol of MAC layer. * * Parameters: * node: node being initialized. * nodeInput: structure containing contents of input file */ void MacTdmaInit(Node* node, int interfaceIndex, const NodeInput* nodeInput, const int subnetListIndex, const int numNodesInSubnet) { BOOL wasFound; BOOL automaticScheduling = 0; char schedulingString[MAX_STRING_LENGTH]; int i; int numSlots; int numChannels = PROP_NumberChannels(node); MacDataTdma* tdma = (MacDataTdma *)MEM_malloc(sizeof(MacDataTdma)); clocktype duration; if (DEBUG) { printf("partition %d, node %d in tdmainitt\n", node->partitionData->partitionId, node->nodeId); printf("partition %d, node %d sees %d nodes in subnet\n" "subnetListIndex %d\n", node->partitionData->partitionId, node->nodeId, numNodesInSubnet, subnetListIndex); fflush(stdout); } ERROR_Assert(tdma != NULL, "TDMA: Unable to allocate memory for TDMA data structure."); memset(tdma, 0, sizeof(MacDataTdma)); tdma->myMacData = node->macData[interfaceIndex]; tdma->myMacData->macVar = (void *)tdma; // // TDMA-NUMBER-OF-SLOTS-PER-FRAME: number of slots per frame // IO_ReadInt(node,node->nodeId, interfaceIndex, nodeInput, "TDMA-NUM-SLOTS-PER-FRAME", &wasFound, &numSlots); if (wasFound) { tdma->numSlotsPerFrame = numSlots; } else { tdma->numSlotsPerFrame = numNodesInSubnet; } // // TDMA-SLOT-DURATION: slot duration // IO_ReadTime(node,node->nodeId, interfaceIndex, nodeInput, "TDMA-SLOT-DURATION", &wasFound, &duration); if (wasFound) { tdma->slotDuration = duration; } else { tdma->slotDuration = DefaultTdmaSlotDuration; } // // TDMA-GUARD-TIME: to be inserted between slots // IO_ReadTime(node,node->nodeId, interfaceIndex, nodeInput, "TDMA-GUARD-TIME", &wasFound, &duration); if (wasFound) { tdma->guardTime = duration; } else { tdma->guardTime = DefaultTdmaGuardTime; } // // TDMA-INTER-FRAME-TIME: to be inserted between frames // IO_ReadTime(node,node->nodeId, interfaceIndex, nodeInput, "TDMA-INTER-FRAME-TIME", &wasFound, &duration); if (wasFound) { tdma->interFrameTime = duration; } else { tdma->interFrameTime = DefaultTdmaInterFrameTime; } // // TDMA-SCHEDULING: type of scheduling (automatic or from file) // IO_ReadString(node,node->nodeId, interfaceIndex, nodeInput, "TDMA-SCHEDULING", &wasFound, schedulingString); if (wasFound) { if (strcmp(schedulingString, "AUTOMATIC") == 0) { automaticScheduling = TRUE; } else if (strcmp(schedulingString, "FILE") == 0) { automaticScheduling = FALSE; } else { ERROR_ReportError( "TDMA-SCHEDULING must be either AUTOMATIC or FILE\n"); } } else { automaticScheduling = TRUE; } // // Build frameDescriptor // // If TDMA-SCHEDULING = AUTOMATIC is specified, all nodes // other than transmitters listen to the channel. // // If TDMA-SCHEDULING = FILE is specified, all nodes stay // idle unless Rx or Tx is specified in TDMA-SCHEDULING-FILE. // tdma->frameDescriptor = (char*)MEM_malloc(tdma->numSlotsPerFrame * sizeof(char)); for (i = 0; i < tdma->numSlotsPerFrame; i++) { tdma->frameDescriptor[i] = TDMA_STATUS_IDLE; } if (automaticScheduling == TRUE) { for (i = 0; i < tdma->numSlotsPerFrame; i++) { if (subnetListIndex == i % numNodesInSubnet) { tdma->frameDescriptor[i] = TDMA_STATUS_TX; } else { tdma->frameDescriptor[i] = TDMA_STATUS_RX; } } } else { NodeInput scheduleInput; IO_ReadCachedFile(node,node->nodeId, interfaceIndex, nodeInput, "TDMA-SCHEDULING-FILE", &wasFound, &scheduleInput); if (wasFound == FALSE) { ERROR_ReportError("TDMA-SCHEDULING-FILE is missing\n"); } for (i = 0; i < scheduleInput.numLines; i++) { char token[MAX_STRING_LENGTH]; char *strPtr = NULL; char *returnValue = NULL; int slotId; ERROR_Assert(i < tdma->numSlotsPerFrame, "TDMA: Too many slots in TDMA Scheduling File."); IO_GetToken(token, scheduleInput.inputStrings[i], &strPtr); slotId = (int)atoi(token); ERROR_Assert(i == slotId, "TDMA: Line on TDMA Scheduling File does not correspond with slot ID"); returnValue = IO_GetToken(token, strPtr, &strPtr); while (returnValue != NULL) { char nodeString[MAX_STRING_LENGTH]; char *typeStr; NodeAddress nodeId; int numReturnVals = 0; numReturnVals = sscanf(token, "%s", nodeString); assert(numReturnVals == 1); IO_ConvertStringToLowerCase(nodeString); typeStr = strrchr(nodeString, '-'); *typeStr = 0; typeStr++; // to the next character if (strcmp(nodeString, "all") == 0) { if (strcmp(typeStr, "rx") != 0) { ERROR_ReportError("'All' must be used with '-Rx'\n"); } nodeId = node->nodeId; } else { nodeId = (NodeAddress)atoi(nodeString); } returnValue = IO_GetToken(token, strPtr, &strPtr); if (node->nodeId != nodeId) { continue; } if (strcmp(typeStr, "rx") == 0) { // // '-Tx' has priority over '-Rx' (likely from 'All-Rx') // if (tdma->frameDescriptor[slotId] != TDMA_STATUS_TX) { tdma->frameDescriptor[slotId] = TDMA_STATUS_RX; } } else if (strcmp(typeStr, "tx") == 0) { tdma->frameDescriptor[slotId] = TDMA_STATUS_TX; } else { ERROR_ReportError("Slot type must be either Rx or Tx\n"); } } } assert(i == tdma->numSlotsPerFrame); } if (DEBUG) { printf("partition %d, node %d: ", node->partitionData->partitionId, node->nodeId); for (i = 0; i < tdma->numSlotsPerFrame; i++) { printf("%d ", (int)tdma->frameDescriptor[i]); } printf("\n"); } // Use first listening channel for (i = 0; i < numChannels; i++) { if (PHY_IsListeningToChannel(node, tdma->myMacData->phyNumber, i) == TRUE) { tdma->channelIndex = i; break; } } tdma->stats.pktsSentUnicast = 0; tdma->stats.pktsSentBroadcast = 0; tdma->stats.pktsGotUnicast = 0; tdma->stats.pktsGotBroadcast = 0; tdma->stats.numTxSlotsMissed = 0; #ifdef PARALLEL //Parallel tdma->lookaheadHandle = PARALLEL_AllocateLookaheadHandle (node); PARALLEL_AddLookaheadHandleToLookaheadCalculator( node, tdma->lookaheadHandle, 0); // Also sepcific a minimum lookahead, in case EOT can't be used in the sim. PARALLEL_SetMinimumLookaheadForInterface(node, tdma->slotDuration); int index; for (index = 0; index < node->numberPhys; index ++ ) { if (node->phyData[index]->phyModel == PHY802_11a) { PARALLEL_SetMinimumLookaheadForInterface(node, DOT11_802_11a_DELAY_UNTIL_SIGNAL_AIRBORN); } if (node->phyData[index]->phyModel == PHY802_11b) { PARALLEL_SetMinimumLookaheadForInterface(node, DOT11_802_11b_DELAY_UNTIL_SIGNAL_AIRBORN); } } #endif //endParallel MacTdmaInitializeTimer(node, tdma); }
void STAT_Statistic::AddDataPoint(clocktype now, double val) { ERROR_ReportError("Not implemented"); }
/* * Protocol initialization function. Check parameters, allocate storage space, read parameters, etc. */ void DearInit(Node* node, DearData** dearPtr, const NodeInput* nodeInput, int interfaceIndex) { BOOL retVal; if (MAC_IsWiredNetwork(node, interfaceIndex)) ERROR_ReportError("DEAR supports only wireless interfaces"); if (node->numberInterfaces > 1) ERROR_ReportError("DEAR supports only one interface of node"); // Allocate memory for variables of this node. DearData* dear = (DearData*)MEM_malloc(sizeof(DearData)); (*dearPtr) = dear; // Reset transmission power. DearSetTxPower(node, DearGetTxPower(node)); // Initalize parameters. dear->destination = 1; dear->defaultPower = DearGetTxPower(node); dear->defaultRange = DearGetPropagationDistance(node); dear->neighbours = (DearTableEntry*)MEM_malloc((1 + node->numNodes) * sizeof(DearTableEntry)); // Read parameter(s). IO_ReadInt(node->nodeId, ANY_ADDRESS, nodeInput, "DEAR-DESTINATION", &retVal, (int*)(&dear->destination)); if (!retVal) ERROR_ReportError("DEAR-DESTINATION not specified!"); // Initialize statistics. dear->numIndirectTransmissions = dear->numDirectTransmissions = 0; // Obtain the neighbours. for (int i = 1; i <= node->numNodes; i++) { // Get the neighbour node. Node *neighbour = DearGetNodeById(node, i); Node *destination = DearGetNodeById(node, dear->destination); // Store the neighbour's maximum battery. dear->neighbours[i].battery_max = DearGetRemainingBattery(neighbour); // Get the positions. double x0, y0, z0, x1, y1, z1, x2, y2, z2; DearGetNodePosition(node, x0, y0, z0); DearGetNodePosition(neighbour, x1, y1, z1); DearGetNodePosition(destination, x2, y2, z2); // Calculate distance between destination and neighbour. // Then set the valid neighbour property. x0 -= x1; y0 -= y1; z0 -= z1; double distance0 = sqrt(x0 * x0 + y0 * y0 + z0 * z0); dear->neighbours[i].valid = (distance0 < dear->defaultRange); // Calculate distance between destination and neighbour. // Then estimate transmission power in dBm. Assume the default transmission power // is used for the given neighbour size (this is expected to preserve the error rate). x2 -= x1; y2 -= y1; z2 -= z1; double distance2 = sqrt(x2 * x2 + y2 * y2 + z2 * z2); dear->neighbours[i].power = DearGetPowerForDistance(neighbour, distance2, dear->defaultPower, dear->defaultRange) + DearPowerBoost; // NOTE the power does NOT fall below the default power (this violates "correctness"). if (dear->neighbours[i].power < dear->defaultPower) dear->neighbours[i].power = dear->defaultPower; } // Tell IP to use our function to route packets. NetworkIpSetRouterFunction(node, &DearRouterFunction, interfaceIndex); }