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

📄 gateway.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:    gateway.c                                                     *//* Author     Adam Torgerson    adam.torgerson@colorado.edu               *//*   Date: 03/11/04                                                       *//*                                                                        *//* The gateway software, to be connected to a relay node and forward      *//*   packets on to connect visualization clients.                         *//**************************************************************************/#include <stdbool.h>#include "common.h"#include "msched.h"#include "cortex.h"#include "arg.h"#include "attributes.h"#include "snet.h"#include "cortex/include/net_event.h"#include "com.h"#include "serial.h"#include "net_event_list.h"static int lines_pending = 0;static gboolean read_eof = FALSE;GSList *conn_list = NULL;GMutex *conn_mutex = NULL;GMutex *write_mutex = NULL;static void server_func (GServer *server, GConn *conn, gpointer data);static void client_func (GConn *conn, GConnEvent *event, gpointer data);static gboolean stdin_func (GIOChannel *chan, GIOCondition cond, gpointer data);static void conn_write_func (gpointer data, gpointer user_data);void server_thread (void);/* TODO: unghettify this */#define BUF_SIZE 4096/* TODO: a better way to get the serial fd? */extern int serialfd;typedef struct {   uint16_t from;   uint16_t to;   uint16_t event;} node_net_event_t;/* watches the serial port and forwards data to all clients */void serial_select (void){   IF_SET set;   comBuf *recv_pkt;   light_temp_event_t ev;      while (1) {      //IF_ZERO (&set);      //IF_SET (IFACE_SERIAL, &set);      // wait on the serial port and receive a packet when ready      //com_select (&set, COM_BLOCK);      debug ("gonna com_recv");      recv_pkt = com_recv (IFACE_SERIAL);      debug ("com_recvd");            // unmarshall the packet into the event struct      node_net_event_t *event = (node_net_event_t *)recv_pkt->data;      //event->buffer = recv_pkt->data+6;      ev.node_id = event->from;      ev.light = recv_pkt->data[6];      ev.temp = recv_pkt->data[7];      //event->buffer[1];            printf ("Sensor Node: %d light: %d temp: %d\n",	      ev.node_id, recv_pkt->data[6], recv_pkt->data[7]);      com_free_buf (recv_pkt);            // call the write func for each connected client, give them the      // recvd packet       if (conn_list != NULL) {	 g_mutex_lock (conn_mutex);	 g_slist_foreach (conn_list, conn_write_func, &ev);	 g_mutex_unlock (conn_mutex);      } else {	 printf ("No clients connected yet\n");      }   }}int main (int argc, char *argv[]){   int port;   GServer *server;   GMainLoop *main_loop;   // GIOChannel *std_in;   printf ("MANTIS Gateway\n");   gnet_init ();   port = MANTIS_DEFAULT_PORT;   // create the main loop    main_loop = g_main_loop_new (NULL, FALSE);   arg_init (argc, argv);   // create the server    server = gnet_server_new (NULL, port, server_func, NULL);   if (!server) {      printf ("Could not start server\n");      exit (-1);   }   /* hook up stdin to a gio channel */   /*     std_in = g_io_channel_unix_new (fileno (stdin));     g_io_add_watch (std_in, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,     stdin_func, NULL);   */      // manually init xmos since we need our own main ()   sched_init ();   com_init ();   serial_init ();   com_mode (IFACE_SERIAL, IF_LISTEN);   conn_mutex = g_mutex_new ();   write_mutex = g_mutex_new ();   mos_thread_new (serial_select, 128, PRIORITY_NORMAL);   printf ("Waiting for connections...\n");   // start the gnet loop, waiting for events, etc   g_main_loop_run (main_loop);      return 0;}/* this function is a callback for g_slist_foreach   it writes the buffer to each connection in the slist*/void conn_write_func (gpointer data, gpointer user_data){   debug ("new write func");         // data is automatically set to the conn (they are the list elements)   GConn *conn = (GConn *)data;   gchar *buf;   time_t tv = time (NULL);   gint size;      // we passed in the comBuf packet struct   light_temp_event_t *ev = (light_temp_event_t *)user_data;      // pack the data, the recvd packet is node id, light, temp    size = gnet_pack_strdup ("!iiliii", &buf,			    sizeof (light_temp_event_t), NET_EVENT_LIGHT_TEMP, tv,			    ev->node_id, ev->light, ev->temp);   if (size == -1) {      printf ("Error packing during write\n");      return;   }   // write out the packed buf    debug ("attempting to write %d buf %p conn %p", size, buf, conn);   gnet_conn_write (conn, buf, size);   debug ("written");   g_free (buf);   debug ("freed");}/* reads from stdin and writes to each device in the conn_list */static gboolean stdin_func (GIOChannel *chan, GIOCondition cond, gpointer data){   guint bytes_read;      if (cond & G_IO_ERR) {      printf ("Socket error on stdin??\n");      exit (-1);   }   if (cond & G_IO_IN) {      GIOError error;      // TODO: something besides a buffer of 4096?       gchar *buf = g_malloc (BUF_SIZE);      // read data into buffer, check for error       error = gnet_io_channel_readline (chan, buf, BUF_SIZE, &bytes_read);      if (error != G_IO_ERROR_NONE) {	 printf ("Read error [%d]\n", error);	 exit (-1);      } else if (bytes_read == 0) {	 if (lines_pending == 0)	    exit (0);	 else	    read_eof = TRUE;	 g_free (buf);	 return FALSE;      }      // no error? read it in       else {	 /* write to all connections	    TODO: implement some kind of connection table? */	 printf ("Would have sent something to the clients\n");	 	 /* iterate through the list with our write callback */	 /*	   if (conn_list != NULL) {	   g_mutex_lock (conn_mutex);	   g_slist_foreach (conn_list, conn_write_func, &event);	   g_mutex_unlock (conn_mutex);	    	   } else {	   printf ("No clients connected yet\n");	   }	 */	 //g_free (buf);	 	 lines_pending++;      }   }      return TRUE;}/* this is the callback which occurs when a client first connects */void server_func (GServer *server, GConn *conn, gpointer data){   if (conn) {      gnet_conn_set_callback (conn, client_func, NULL);      debug ("Got a new connection from %s:%d",	     gnet_inetaddr_get_canonical_name (conn->inetaddr),	     gnet_inetaddr_get_port (conn->inetaddr));            // add the client to our list of all client connections      g_mutex_lock (conn_mutex);      conn_list = g_slist_append (conn_list, conn);      g_mutex_unlock (conn_mutex);            gnet_conn_set_watch_error (conn, TRUE);      gnet_conn_readn (conn, sizeof (net_event_header_t));   } else {      printf ("Error: conn was NULL?!\n");      gnet_server_delete (server);      exit (-1);   }}typedef struct {   gint node_id;   gint event;   gint arg;} node_net_event_command_t;/* this is the callback which occurs with some kind of client activity */void client_func (GConn *conn, GConnEvent *event, gpointer data){   static gint recv_state = STATE_IDLE;   static net_event_header_t header;   static light_temp_event_t ev;   debug ("in client func");         switch (event->type) {            // done reading   case GNET_CONN_READ: {      //g_mutex_lock (conn_mutex);      // printf ("Should not be reading...\n");            if (recv_state == STATE_IDLE) {	 int size;	 // read in the header for the next go around	 debug ("grabbing mutex");	 	 g_mutex_lock (conn_mutex);	 	 gnet_unpack ("!iil", event->buffer, event->length,		      &header.size, &header.event_type, &header.time_seconds);	 recv_state = STATE_GOT_SIZE;	 size = header.size;	 	 printf ("got a header of type %d, len %d\n", header.event_type,		 header.size);	 g_mutex_unlock (conn_mutex);	 gnet_conn_readn (conn, size);      } else if (recv_state == STATE_GOT_SIZE) {	 debug ("grabbing mutex");	 g_mutex_lock (conn_mutex);	 debug ("got normal packet");	 // already got a header, see what to do with the packet	 if (header.event_type == NET_EVENT_LIGHT_TEMP_RANDOM) {	    debug ("it's a random light temp");	    //g_mutex_lock (conn_mutex);	    gnet_unpack ("!iii", event->buffer, event->length,			 &ev.node_id, &ev.light, &ev.temp);	    debug ("unpacked");	    	    if (conn_list != NULL) {	       g_slist_foreach (conn_list, conn_write_func, &ev);	    } else {	       debug ("Not sending packet, no clients connected yet");	    }	    debug ("written");	    //g_mutex_unlock (conn_mutex);	 } else if (header.event_type == NET_EVENT_COMMAND) {	    printf ("got a cmd packet: len is %d\n", event->length);	    //g_mutex_lock (conn_mutex);	    	    comBuf send_pkt;	    node_net_event_command_t command;	    if (header.size == 12) {	       gnet_unpack ("!iii", event->buffer, header.size,			    &command.node_id, &command.event, &command.arg);	    } else if (header.size == 8) {	       gnet_unpack ("!ii", event->buffer, header.size,			    &command.node_id, &command.event);	    } else {	       debug ("UNHANDLED HEADER SIZE");	    }	    	    debug ("Sending a command packet: %d %d %d", command.event, header.size,		   command.node_id);	    //for(i=0;i<command.command_len);	    node_net_event_t *net_event = (node_net_event_t *)send_pkt.data;	    net_event->from = 0;	    net_event->to = command.node_id;	    net_event->event = command.event;	    if (header.size == 12) {	       send_pkt.data[6] = command.arg;	       send_pkt.size = 7;	    } else	       send_pkt.size = 6;	    	    com_send (IFACE_SERIAL, &send_pkt);	    debug ("sent command packet");	    	    //g_mutex_unlock (conn_mutex);	 } else {	    printf ("Received unknown event type %d\n", header.event_type);	 }	 recv_state = STATE_IDLE;	 g_mutex_unlock (conn_mutex);	 debug ("reading another header");	 gnet_conn_readn (conn, sizeof (net_event_header_t));	 debug ("done reading header");      }      //g_mutex_unlock (conn_mutex);            break;   }      // done writing   case GNET_CONN_WRITE: {      debug ("wrote");      break;   }   case GNET_CONN_CLOSE:   case GNET_CONN_TIMEOUT:   case GNET_CONN_ERROR: {      // client has timed-out / disconnected      //g_mutex_lock (conn_mutex);      printf ("Client %s:%d disconnected\n",	      gnet_inetaddr_get_canonical_name (conn->inetaddr),	      gnet_inetaddr_get_port (conn->inetaddr));            conn_list = g_slist_remove (conn_list, conn);      if (!g_slist_length (conn_list)) {	 debug ("Resetting conn_list to null");	 conn_list = NULL;      }      gnet_conn_delete (conn);      //g_mutex_unlock (conn_mutex);            recv_state = STATE_IDLE;      break;   }   default:      debug ("default case??");      g_assert_not_reached ();   }}

⌨️ 快捷键说明

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