📄 puma.cc
字号:
/* Copyright (c) 2007 Sidney Doria * Federal University of Campina Grande * Brazil * * This file is part of PUMA. * * PUMA is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, * or(at your option) any later version. * * PUMA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PUMA; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA */#include "puma.h"/* * Message Cache */boolMessageCacheItem::isEqualTo(MessageCacheItem* itemToCompare) { if (itemToCompare != NULL) if ((source() == itemToCompare->source()) && (sequenceNumber() == itemToCompare->sequenceNumber())) return true; return false;}voidMessageCache::append(MessageCacheItem* newItem) { if (newItem != NULL) { newItem->nextItem_ = NULL; if (size() == 0) { rear_ = newItem; front_ = newItem; } else { rear_->nextItem_ = newItem; rear_ = rear_->nextItem_; } ++(size()); agent_->routingSetTimer(FLUSH_TABLES, NULL, FLUSH_INTERVAL); } }voidMessageCache::removeFront() { if (front_ != NULL) { MessageCacheItem* temp = front_; front_ = front_->nextItem_; delete temp; --(size()); if (size() == 0) rear_ = NULL; }}boolMessageCache::find(MessageCacheItem* item) { MessageCacheItem* temp; if (item != NULL) for (temp = front_; temp != NULL; temp = temp->nextItem_) if (temp->isEqualTo(item)) return true; return false;}/* * Connectivity List */boolConnectivityListItem::isEqualTo(ConnectivityListItem* itemToCompare) { return nextHop() == itemToCompare->nextHop();}boolConnectivityListItem::isBetterThan(ConnectivityListItem* itemToCompare) { if (sequenceNumber() > itemToCompare->sequenceNumber()) return true; else if (sequenceNumber() < itemToCompare->sequenceNumber()) return false; else if (distanceToCore() < itemToCompare->distanceToCore()) return true; else if (distanceToCore() > itemToCompare->distanceToCore()) return false; else if (nextHop() > itemToCompare->nextHop()) return true; else return false;}voidConnectivityList::addSorted(ConnectivityListItem* newItem) { if (newItem != NULL) { remove(newItem); // If that entry already exists, remove it before. if (start_ == NULL) { newItem->nextItem_ = NULL; start_ = newItem; } else if (newItem->isBetterThan(start_)) { newItem->nextItem_ = start_; start_ = newItem; } else { ConnectivityListItem* temp = start_; while (temp->nextItem_ != NULL) { if (newItem->isBetterThan(temp->nextItem_)) break; temp = temp->nextItem_; } newItem->nextItem_ = temp->nextItem_; temp->nextItem_ = newItem; } }}voidConnectivityList::remove(ConnectivityListItem* itemToRemove) { if ((itemToRemove != NULL) && (start_ != NULL)) { ConnectivityListItem* temp = start_; if (start_->isEqualTo(itemToRemove)) { start_ = start_->nextItem_; delete temp; return; } while (temp->nextItem_ != NULL) { if (temp->nextItem_->isEqualTo(itemToRemove)) { ConnectivityListItem* toBeFreed = temp->nextItem_; temp->nextItem_ = temp->nextItem_->nextItem_; delete toBeFreed; return; } temp = temp->nextItem_; } }}/* * Multicast Groups */boolMulticastGroup::reset() { delete connectivityList_; connectivityList_ = new ConnectivityList(); meshMember() = false; neighborConfirmationWait() = false; partitionConfirmationWait() = false; delayedMAPending() = false; lastSequenceNumber() = 0; coreId() = INVALID_ADDRESS; lastMAOriginated() = NEVER; lastMAReceived() = NEVER;return true;}voidMulticastGroups::append(MulticastGroup* newGroup) { newGroup->nextItem_ = start_; start_ = newGroup;}MulticastGroup*MulticastGroups::find(nsaddr_t groupAddress) { MulticastGroup* temp = start_; while (temp != NULL) { if (temp->multicastAddress() == groupAddress) return temp; temp = temp->nextItem_; } return NULL;}intMulticastGroups::getNumberOfGroups() { MulticastGroup* temp; int i = 0; for (temp = start_; temp != NULL; temp = temp->nextItem_) { i++; } return i;}voidACKTable::removeObsoleteEntries() { int i; i = getFirstOccupiedSlot(); while((NOW - elementAt(i).timeHeard()) > ACK_TIMEOUT_INTERVAL && numberOfACKTableEntries() > 0) { (numberOfACKTableEntries())--; i++; i%=NUMBER_OF_ACK_TABLE_ENTRIES; }}intACKTable::getFirstOccupiedSlot() { int firstOccupiedSlot; if (numberOfACKTableEntries() <= nextEmptySlotInACKTable()) firstOccupiedSlot = nextEmptySlotInACKTable() - numberOfACKTableEntries(); else firstOccupiedSlot = NUMBER_OF_ACK_TABLE_ENTRIES + nextEmptySlotInACKTable() - numberOfACKTableEntries(); return(firstOccupiedSlot);}ACKTableItemACKTable::elementAt(short index) { return ACKTableData_[index];}/* * TCL Hooks */int hdr_puma::offset_;static class PUMAHeaderClass : public PacketHeaderClass {public: PUMAHeaderClass() : PacketHeaderClass("PacketHeader/PUMA", sizeof(hdr_puma)) { bind_offset(&hdr_puma::offset_); }} class_rtProtoPUMA_hdr;static class PUMAClass : public TclClass {public: PUMAClass() : TclClass("Agent/PUMA") {} TclObject* create(int argc, const char*const* argv) { return (new PUMA((nsaddr_t) Address::instance().str2addr(argv[4]))); }} class_rtProtoPUMA;/* * Routing Timer */voidRoutingTimer::handle(Event* e) { agent_->handleProtocolEvent(e);}/* * PUMA Agent */intPUMA::command(int argc, const char*const* argv) { if (argc == 2) { Tcl& tcl = Tcl::instance(); if (strncasecmp(argv[1], "start", 2) == 0) { return TCL_OK; } if (strncasecmp(argv[1], "id", 2) == 0) { tcl.resultf("%d", id_); return TCL_OK; } } else if (argc == 3) { if (strcmp(argv[1], "log-target") == 0 || strcmp(argv[1], "tracetarget") == 0) { logTarget_ = (Trace*)TclObject::lookup(argv[2]); if (logTarget_ == NULL) return TCL_ERROR; return TCL_OK; } if (strcmp(argv[1], "port-dmux") == 0) { dmux_ = (PortClassifier*)TclObject::lookup(argv[2]); if (dmux_ == NULL) return TCL_ERROR; return TCL_OK; } if (strcmp(argv[1], "join") == 0) { handleJoinFromTransport(atoi(argv[2])); return TCL_OK; } if (strcmp(argv[1], "leave") == 0) { handleLeaveFromTransport(atoi(argv[2])); return TCL_OK; } } return Agent::command(argc, argv);}voidPUMA::recv(Packet* p, Handler*) { if ((HDR_CMN(p)->ptype() == PT_PUMA)) handleProtocolPacket(p); else handleDataFromTransport(p);}voidPUMA::setRetransmissionTimer(nsaddr_t nextHop, short eventType, double timeoutInterval, nsaddr_t multicastAddress) { struct ACKTimeoutMessage* message = (ACKTimeoutMessage*)malloc(sizeof(struct ACKTimeoutMessage)); message->multicastAddress_ = multicastAddress; message->nextHop_ = nextHop; routingSetTimer(eventType, message, timeoutInterval); }voidPUMA::routingSetTimer(short eventType, void* data, double delay) { RoutingEvent* e = new RoutingEvent(eventType, data); Scheduler::instance().schedule(routingTimer_, e, delay);}voidPUMA::handleProtocolEvent(Event* e) { if (e != NULL) { RoutingEvent* event = (RoutingEvent*)e; switch (event->eventType()) { case SEND_NEXT_BUCKET: { sendNextBucket(); break; } case FLUSH_TABLES: { messageCache_.removeFront(); break; } case JOIN_ACK_TIMEOUT: {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -