⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net.c

📁 MANTIS是由科罗拉多大学开发的传感器网络嵌入式操作系统。 这是mantis的0.9.5版本的源码。
💻 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:       net.c                                                      *//* Author:     Jeff Rose               :  rosejn@colorado.edu             *//* Author:     Charles Gruenwald III   :  gruenwal@colorado.edu           *//*   Date: 04/15/04                                                       *//* Modified:   Cyrus Hall              :  hallcp@colorado.edu             *//*   Date: 07/22/04                                                       *//*                                                                        *//* Top level event based networking layer.                                *//**************************************************************************//** @file net.c * @brief Top level event based networking layer. * @author Jeff Rose, Charles Gruenwald III * @author Modified: Cyrus Hall * @date Created: 04/15/2004 * @date Modified: 07/22/2004 */#include "net.h"#include "msched.h" /** @brief List of current protocols. */net_proto protocols[NET_PROTO_MAX];/** @brief default_protocol **/uint8_t default_proto;/** @brief pointer to last received comBuf **/comBuf * currentComBuf;/** @brief list of threads blocked on recv **/static thread_t *waitingThreads;static mos_mutex_t netMutex;#ifdef MOS_NO_USE_DYNAMIC_MEMORYstatic uint8_t net_stack[192];#endif/** @brief Initialize the net layer variables   */void net_init(){   uint8_t i;      for(i = 0; i < NET_PROTO_MAX; i++)      protocols[i].proto_id = 0;      currentComBuf = NULL;   waitingThreads = NULL;   mos_mutex_init(&netMutex);#ifdef MOS_NO_USE_DYNAMIC_MEMORY   mos_thread_new_havestack(net_thread, 192, net_stack, PRIORITY_NORMAL);#else   mos_thread_new(net_thread, 192, PRIORITY_NORMAL);#endif}/** @brief net_send method called by applications  * @param pkt comBuf from application * @param proto_id protocol's ID * @param port destination port * @return ret not useful so far.. should probably return number of bytes sent? */int8_t net_send(comBuf *pkt, uint8_t proto_id, uint8_t port, ...){    uint8_t i;    va_list ap;    uint8_t ret;    uint8_t old_size;        if(proto_id == 0)	return NET_PROTO_INVALID;    /* store the old size since we modify it */    old_size = pkt->size;        /* Make sure we have a valid protocol id, then send. */    for(i = 0; i < NET_PROTO_MAX; i++)    {  	if(protocols[i].proto_id == proto_id)	{	    /* Setup the va_list. */	    va_start(ap, port);	    /* Now send to protocol to add protocol specific footers. */	    ret = protocols[i].sfunc(pkt, ap);	    va_end(ap);	    	    /* add the dest port to the packet footer*/	    pkt->data[pkt->size] = port;	    pkt->size++;	    /* add the protocol id to the packet footer*/	    pkt->data[pkt->size] = proto_id;	    pkt->size++;	    /*the net layer actually sends the packet */#ifdef PLATFORM_AVRDEV	    com_send(IFACE_SERIAL2, pkt);#else	    com_send(IFACE_RADIO, pkt);#endif	    // set the packet size to be its original size	    // since we modified it	    pkt->size = old_size;	    return ret;	}    }    /* Not a valid protocol. */    return NET_PROTO_INVALID;}/* * @param sfunc Protocol send function * @param rfunc Protocol receive function * @param ifunc Protocol io control function * @return NET_PROTO_INVALID if protocol invalid, -1 if no space left, else return */int8_t net_proto_register(uint8_t proto, net_proto_send sfunc,			  net_proto_recv rfunc, net_proto_ioctl ifunc){    uint8_t i;    /* Make sure the passed in ID is valid, i.e., not 0. */    if(proto == 0)	return NET_PROTO_INVALID;    /* Find the next available slot. */    for(i = 0; i < NET_PROTO_MAX; i++)    {	if(protocols[i].proto_id == proto ||	   protocols[i].proto_id == 0)	{	    protocols[i].proto_id = proto;	    protocols[i].sfunc = sfunc;	    protocols[i].rfunc = rfunc;	    protocols[i].ifunc = ifunc;	 	    return 0;	}    }    /* No space left. */    return -1;}/** @brief Set some protocol specific options.  * @param proto Protocol * @param request IO Request * @return NET_PROTO_INVALID if protocol invalid, else return retval */int8_t net_ioctl(uint8_t proto, uint8_t request, ...){    uint8_t i;    uint8_t retval;    va_list ap;    if(proto == 0)	return NET_PROTO_INVALID;       /* Make sure we have a valid protocol id, then call the func. */    for(i = 0; i < NET_PROTO_MAX; i++)    {	if(protocols[i].proto_id == proto)	{	    /* Now ship it off to the protocol. */	    va_start(ap, request);	    retval = protocols[i].ifunc(request, ap);	   	    va_end(ap);	   	    return retval;	}    }    /* Not a valid protocol. */    return NET_PROTO_INVALID;}/** @brief A background thread that listens on everything for event traffic.*/void net_thread(){    comBuf *pkt;    uint8_t i;    uint8_t proto;    uint8_t port;    uint8_t *footer;    boolean toApp;#ifdef PLATFORM_AVRDEV    com_mode(IFACE_SERIAL2, IF_LISTEN);#else    com_mode(IFACE_RADIO, IF_LISTEN);#endif    while(1)    {#ifdef PLATFORM_AVRDEV       pkt = com_recv(IFACE_SERIAL2);#else       pkt = com_recv(IFACE_RADIO);#endif	/* Now that we have a packet we pull the protocol ID and port and send it	   to the correct protocol handler. */	proto = pkt->data[pkt->size - 1];	pkt->size--;	port = pkt->data[pkt->size - 1];	pkt->size--;		/* If the proto is 0, we've received an invalid packet. */	if(proto == 0)	{	    com_free_buf(pkt);	    continue;	}      	for(i = 0; i < NET_PROTO_MAX && protocols[i].proto_id != proto; i++);	/* Bogus protocol id... */	if(i == NET_PROTO_MAX)	{	    com_free_buf(pkt);	    continue;	}      	/* set the current comBuf to the currently received packet */	currentComBuf = pkt;		/* check to see if the protocol is going to send the packet to the app */	toApp = protocols[i].rfunc(pkt, &footer, port);	/* if it doesn't free the buffer.  If it does, it's the Apps job to free	   the buffer */	if (!toApp){	   com_free_buf(pkt);	}	    }}/** @brief is_app_waiting_on() method called by protocols * @param port check all waiting threads for the specified port * @return true if it sent the packet to an app, false if it did not. */boolean is_app_waiting_on(uint8_t port){   thread_t *current;   thread_t *previous;      mos_mutex_lock(&netMutex);   previous = waitingThreads;   current = waitingThreads;   /* first check to see if the first thread is waiting on the specified port */   if (previous->port == port)   {      waitingThreads = waitingThreads->next;      //give current packet back to app      mos_thread_resume(current);      mos_mutex_unlock(&netMutex);      return true;   }   /* it wasn't the first thread, so check the rest */   current = current->next;      while (current != NULL)   {      /* found a waiting thread */      if (current->port == port)      {	 /* remove it from list */	 previous->next = current->next;	 /* resume the app (gives the current packet to the app) */	 mos_thread_resume(current);	 mos_mutex_unlock(&netMutex);	 return true;      }      current = current->next;      previous = previous->next;   }   mos_mutex_unlock(&netMutex);    return false;      } /** @brief net_recv method called by applications * @param port listening on specified port * @return returns comBuf to application */comBuf *net_recv(uint8_t port){   thread_t *head;    /* set the port the thread will wait on */   mos_thread_set_port(port);      mos_mutex_lock(&netMutex);   /* if no threads waiting, make this the first in the list */   if (waitingThreads == NULL){       waitingThreads = mos_thread_current();   }   /* otherwise, add it to the end of the list of waiting threads */   else   {      head = waitingThreads;      while (head->next != NULL){	 head = head->next;      }      head->next = mos_thread_current();   }      mos_mutex_unlock(&netMutex);    /* suspend the thread until a packet with the specified port is received */   mos_thread_suspend();      /* we've been woken up by the is_app_waiting_on(port) call, so the current      packet must be for this app */   return currentComBuf;   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -