📄 sicslowmac.c
字号:
/* * Copyright (c) 2008, Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file is part of the Contiki operating system. * * $Id: sicslowmac.c,v 1.5 2008/11/08 03:29:15 c_oflynn Exp $ *//** * \file * Example glue code between the existing MAC code and the * Contiki mac interface * * \author * Adam Dunkels <adam@sics.se> * Eric Gnoske <egnoske@gmail.com> * Blake Leverett <bleverett@gmail.com> * * \addtogroup rf230mac */#include <stdlib.h>#include <stdbool.h>#include <string.h>#include <stdio.h>#include <avr/eeprom.h>#include <util/delay.h>#include "net/rime/rimebuf.h"#include "zmac.h"#include "mac.h"#include "frame.h"#include "radio.h"#include "tcpip.h"#include "sicslowmac.h"#include "sicslowpan.h"#include "ieee-15-4-manager.h"/* Macros */#define DEBUG 0#define MAX_EVENTS 10#if DEBUG#define PRINTF(...) printf(__VA_ARGS__)#define SICSLOW_CORRECTION_DELAY 70#else#define PRINTF(...)#define SICSLOW_CORRECTION_DELAY 7#endif#ifdef JACKDAW#include "sicslow_ethernet.h"#define LOG_FRAME(x,y) mac_logTXtoEthernet(x,y)#else#define LOG_FRAME(x,y)#endif/* Globals */static struct mac_driver mac_driver_struct;static struct mac_driver *pmac_driver = &mac_driver_struct;extern ieee_15_4_manager_t ieee15_4ManagerAddress;static parsed_frame_t *parsed_frame;const struct mac_driver sicslowmac_driver = { sicslowmac_dataRequest, /* read_packet, */ /* set_receive_function, */ /* on, */ /* off, */};static struct { uint8_t head; uint8_t tail; event_object_t event_object[MAX_EVENTS];} event_queue;/* Prototypes */static void setinput(void (*r)(const struct mac_driver *d));void (*pinput)(const struct mac_driver *r);void sicslowmac_unknownIndication(void);void (*sicslowmac_snifferhook)(const struct mac_driver *r) = NULL;/*---------------------------------------------------------------------------*//** * \brief Checks for any pending events in the queue. * * \return True if there is a pending event, else false. */uint8_tmac_event_pending(void){ return (event_queue.head != event_queue.tail);}/*---------------------------------------------------------------------------*//** * \brief Puts an event into the queue of events. * * \param object is a pointer to the event to add to queue. */voidmac_put_event(event_object_t *object){ uint8_t newhead; if ((event_queue.head + 1) % MAX_EVENTS == event_queue.tail){ /* queue full, get outta here */ return; } newhead = event_queue.head; /* store in queue */ event_queue.event_object[newhead] = *object; /* calculate new head index */ newhead++; if (newhead >= MAX_EVENTS){ newhead = 0; } event_queue.head = newhead;}/*---------------------------------------------------------------------------*//** * \brief Pulls an event from the event queue. * Assumes that there is an event in the queue. See mac_event_pending(). * * \return Pointer to the event object, or NULL in the event of empty queue. */event_object_t*mac_get_event(void){ event_object_t *object = NULL; volatile uint8_t newtail; newtail = event_queue.tail; object = &(event_queue.event_object[newtail]); /* calculate new tail */ newtail++; if (newtail >= MAX_EVENTS){ newtail = 0; } event_queue.tail = newtail; return(object);}void mac_pollhandler(void){ mac_task(0, NULL);}/*---------------------------------------------------------------------------*//** * \brief This is the main loop task for the MAC. Called by the * main application loop. */voidmac_task(process_event_t ev, process_data_t data){ /* check for event in queue */ event_object_t *event; if(mac_event_pending()){ event = mac_get_event(); /* Handle events from radio */ if (event){ if (event->event == MAC_EVENT_RX){ /* got a frame, find out with kind of frame */ parsed_frame = (parsed_frame_t *)event->data; if (parsed_frame->fcf->frameType == DATAFRAME){ sicslowmac_dataIndication(); } else { /* Hook to cath unknown frames */ sicslowmac_unknownIndication(); } /* Frame no longer in use */ parsed_frame->in_use = false; } if (event->event == MAC_EVENT_DROPPED){ /* Frame was dropped */ PRINTF("sicslowmac: Frame Dropped!\n"); } } }}/*---------------------------------------------------------------------------*/voidsetinput(void (*r)(const struct mac_driver *d)){ pinput = r;}/*---------------------------------------------------------------------------*/static uint8_t dest_reversed[8];static uint8_t src_reversed[8];voidsicslowmac_dataIndication(void){ rimebuf_clear(); /* Finally, get the stuff into the rime buffer.... */ rimebuf_copyfrom(parsed_frame->payload, parsed_frame->payload_length); rimebuf_set_datalen(parsed_frame->payload_length); memcpy(dest_reversed, (uint8_t *)parsed_frame->dest_addr, 8); memcpy(src_reversed, (uint8_t *)parsed_frame->src_addr, 8); /* Change addresses to expected byte order */ byte_reverse((uint8_t *)dest_reversed, 8); byte_reverse((uint8_t *)src_reversed, 8); rimebuf_set_addr(RIMEBUF_ADDR_RECEIVER, (const rimeaddr_t *)dest_reversed); rimebuf_set_addr(RIMEBUF_ADDR_SENDER, (const rimeaddr_t *)src_reversed); PRINTF("sicslowmac: hand off frame to sicslowpan \n"); pinput(pmac_driver);}voidsicslowmac_unknownIndication(void){ if (sicslowmac_snifferhook) { rimebuf_clear(); /* Finally, get the stuff into the rime buffer.... */ rimebuf_copyfrom(parsed_frame->payload, parsed_frame->payload_length); rimebuf_set_datalen(parsed_frame->payload_length); memcpy(dest_reversed, (uint8_t *)parsed_frame->dest_addr, 8); memcpy(src_reversed, (uint8_t *)parsed_frame->src_addr, 8); /* Change addresses to expected byte order */ byte_reverse((uint8_t *)dest_reversed, 8); byte_reverse((uint8_t *)src_reversed, 8); rimebuf_set_addr(RIMEBUF_ADDR_RECEIVER, (const rimeaddr_t *)dest_reversed); rimebuf_set_addr(RIMEBUF_ADDR_SENDER, (const rimeaddr_t *)src_reversed); PRINTF("sicslowmac: hand off frame to sniffer \n"); sicslowmac_snifferhook(pmac_driver); } }/*---------------------------------------------------------------------------*//** * \brief This is the implementation of the 15.4 MAC Data Request * primitive.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -