📄 mst.c
字号:
// This file is part of MANTIS OS, Operating System// See http://mantis.cs.colorado.edu///// Copyright (C) 2003,2004,2005 University of Colorado, Boulder//// This program is free software; you can redistribute it and/or// modify it under the terms of the mos license (see file LICENSE)/**************************************************************************//* File: mst.c *//* Author: Anmol Sheth: anmol.sheth@colorado.edu *//* Date: 11/12/04 *//* *//* MST protocol example *//**************************************************************************//** @file mst.c * @brief MST protocol example * @author Carl Hartung * @date Created: 11/12/2004 */#include <stdlib.h>#include <string.h>#include "led.h"#include "node_id.h"#include "mutex.h"#include "mst.h"#include "net.h"uint8_t myDtb; // my distance (hop count) to the base stationuint8_t myParentID; //upstream parent ID ( == rtable[0])uint8_t myID;uint8_t seqNo;uint8_t beaconSeqNo;uint8_t lstctrlfwd; //the seqno of the last control pkt this node forwarded#define MAX_DIAMETER_NETWORK 20#define MAX_NODES 256 //1-byte address allows for 256 - 1 nodes(1 broadcaast)uint8_t rtable [MAX_NODES] = {0}; //Downstream routing table indexed by // dest address uint8_t mst_dtb(){ return myDtb;}uint8_t mst_parent(){ return myParentID;}void mst_proto_init(){ /* must be called by all protocols */ net_proto_register(MST_PROTO_ID, mst_proto_send, mst_proto_recv, mst_proto_ioctl); myDtb = MAX_DIAMETER_NETWORK; myID = 0xFF; seqNo = 0; beaconSeqNo = 0; lstctrlfwd = 0;}/*Send function for MST * Required args: * uint8_t fromApp: 1 if sender is source * uint8_t pkt_type: Type of packet * uint8_t dest: Final destination of packet */int8_t mst_proto_send(comBuf *pkt, va_list args){ uint8_t fromApp; uint8_t pkt_type; uint8_t dest; fromApp = va_arg(args, int); pkt_type = va_arg(args, int); dest = va_arg(args, int); if (!fromApp) { //This is a packet in mid path. Just send it off. return 0; } else{ //It is a data packet from the application. Initialize it and send //it off //Sender DTB pkt->data[pkt->size] = myDtb; pkt->size++; //Last Hop pkt->data[pkt->size] = myID; pkt->size++; //Source address pkt->data[pkt->size] = myID; pkt->size++; //Destination address pkt->data[pkt->size] = dest; pkt->size++; //Type pkt->data[pkt->size] = pkt_type; pkt->size++; //SeqNo if (pkt_type == MST_CONTROL){ pkt->data[pkt->size] = beaconSeqNo++; } else { pkt->data[pkt->size] = seqNo++; } pkt->size++; //DTB pkt->data[pkt->size] = myDtb; pkt->size++; //TTL pkt->data[pkt->size] = 10; pkt->size++; //Next Hop pkt->data[pkt->size] = rtable[dest]; pkt->size++; /*printf("Initial Send Src:%C Dest:%C Type:%C LH:%C NH:%C Seq:%C Size:%C\n", pkt->data[pkt->size-7], pkt->data[pkt->size-6], pkt->data[pkt->size-5], pkt->data[pkt->size-8], pkt->data[pkt->size-1], pkt->data[pkt->size-4], pkt->size);*/ return 1; }}boolean mst_proto_recv(comBuf *pkt, uint8_t **footer, uint8_t port){ uint8_t nxt_hop, ttl, pkt_dtb, seqno, type, dest, src, lst_hop; //We have received a packet from the net_thread. We need to check //whether it is a control or a data packet and send it off to the //higher app layer. // We extract Next Hop, TTL, DTB, SeqNo, type, Dest, Src, and Last Hop nxt_hop = pkt->data[pkt->size-1]; ttl = pkt->data[pkt->size-2]; pkt_dtb = pkt->data[pkt->size-3]; seqno = pkt->data[pkt->size-4]; type = pkt->data[pkt->size-5]; dest = pkt->data[pkt->size-6]; src = pkt->data[pkt->size-7]; lst_hop = pkt->data[pkt->size-8]; //printf("Recv myID:%C Src:%C Dest:%C Type:%C LH:%C Seq:%C Size:%C port:%C\n",myID,src,dest,type,lst_hop,seqno, pkt->size, port); if (type == MST_CONTROL) { //Control packet update the Dtb if needed. Change the parent //only if the new DTB is < Current DTB. Do not change otherwise //(prevent ping-ponging between 2 parent nodes with same DTB) //Node lost its parent and has no better candidate //myDtb = max to find best available parent //(seqno - 2): 2 missed cycles of broadcast to indicate a lost link if (seqno - 2 > lstctrlfwd && src != myID){ myDtb = MAX_DIAMETER_NETWORK; } //If control packet is from parent or better, store seqno and forward if((pkt_dtb + 1 < myDtb || (pkt_dtb + 1 == myDtb && lst_hop == rtable[src])) && ttl != 1) { //Update routing table rtable[src] = lst_hop; lstctrlfwd = seqno; //Found a better path if(pkt_dtb + 1 < myDtb) { myDtb = pkt_dtb +1; } //Dec TTL pkt->data[pkt->size-2] = ttl - 1; //Inc DTB pkt->data[pkt->size-3] = myDtb ; //Change the last hop address pkt->data[pkt->size-8] = myID; net_send(pkt, MST_PROTO_ID, port, false, type, dest); } //A return value of 0 causes the net thread to return the buffer //to the common pool. return 0; } if (type == MST_DATA) { //Data frame so we need to send it up to the app only if the //dest addr == myaddr. If not check if I am on the path and //forward it upstream if necessary if(dest == myID) { //dest is the final dest of the packet //Update routing table rtable[src] = lst_hop; /* must be called if the protocol wants to try to send the packet * to the app */ return is_app_waiting_on(port); } else { //I may be on the path. net_send would check if I am on the //path and forward the packet upstream if necessary. if(ttl != 1 && nxt_hop == myID) { //Update routing table rtable[src] = lst_hop; //need to forward the packet upstream pkt->data[pkt->size-8] = myID; //add self as last hop pkt->data[pkt->size-3] = pkt_dtb - 1; //decrement the DtB pkt->data[pkt->size-1] = rtable[dest]; //change the next hop ID pkt->data[pkt->size-2] = ttl - 1; //decrement the ttl net_send(pkt, MST_PROTO_ID, port, false, type, dest); return 0; // Free the buffer after sending it out } } } // unknown type, shouldn't get here return 0;}int8_t mst_proto_ioctl(uint8_t request, va_list args){ switch(request) { case SET_ADDR: myID = va_arg(args, int); printf("Set my ID to %C\n", myID); break; case SET_DTB: myDtb = va_arg(args, int); printf("Set my DTB to %C\n", myDtb); break; default: return 0; break; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -