Code Search for Developers
 
 
  

centroute_upper.c from EmStar at Krugle


Show centroute_upper.c syntax highlighted

/*
 *
 * Copyright (c) 2003 The Regents of the University of California.  All
 * rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Neither the name of the University 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 REGENTS 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 REGENTS 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.
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <math.h>

#include "emrun/emrun.h"
#include "link/link.h"
#include <link/link_headers.h>
#include <libmisc/misc.h>
#include <libdev/status_dev.h>
#include <libdev/command_dev.h>
#include <libdev/query_dev.h>
#include <libdev/packet_client.h>
#include <libdev/packet_dev.h>
#include <libdev/em_sched.h>
#include <centroute_i.h>
#include <routing/routing_table.h>
#include <libdev/command_dev.h>
#include <devel/state/ssync.h>
#include <devel/herd/centroute.h>


#include "tos-contrib/herd/tos/system/CentTree_defs.h"
#include "tos-contrib/herd/tos/system/CentTree.h"

#ifndef SECOND
#define SECOND  1000
#endif
#ifndef TOS_BCAST_ADDR
#define TOS_BCAST_ADDR  0xFFFF
#endif


int centroute_data_dev_send(lp_context_t *lp, link_pkt_t *pkt, int datalen,
        int loop_needed);
int centroute_data_dev_status(lp_context_t *lp);
int centroute_data_dev_ioctl(lp_context_t *lp, int cmd, void *arg);
int centroute_data_dev_parse_commands(lp_context_t *lp, 
        parser_state_t *cmd_input);
void centroute_data_dev_usage(lp_context_t *lp, buf_t *buf);
//int send_data_pkt_to_pd(node_t *node, char *data, int len, cr_state_t *crstate);




int send_data_pkt_to_pd(node_t *node, char *data, uint8_t type, 
        int len, cr_state_t *crstate)
{
    pd_hdr_t *pd_hdr=NULL;
    int offset=0;
    int total_len=0;
    node_t *parent=NULL;
    int retcode=0;

    pd_hdr = create_downstream_pkt_hdr(node, DATA, type, 
            len, &offset, &total_len);

    if (pd_hdr==NULL) {
        elog(LOG_ERR, "Cannot send data pkt to node %u: NULL pd_hdr",
                node->id);
        return -1;
    }

    parent = find_parent_from_path(node, node->preferred_path);
    if (parent==NULL) {
        elog(LOG_ERR, "NULL (!) parent for node %u", node->id);
        exit(1);
    }

    // don't send data pkt if parent hasn't verified assoc
    if (parent->is_root==0) {
        if (parent->state != ASSOCIATED_VERIFIED) {
            elog(LOG_ERR, "Node %u's parent (%u) hasn't verified"
                    " its association (in state %d). Will not send data pkt",
                    node->id, parent->id, parent->state);
            goto done;
        }
    }

    // copy the payload
    memcpy(&pd_hdr->data[offset], data, len);
    // send the packet to PD
    retcode = pd_client_send(crstate->centroute_data_pd, pd_hdr, total_len);

    if (retcode < 0) {
        elog(LOG_ERR, "Could not send data pkt to node %u: %m", node->id);
        goto done;
    } else {
        elog(LOG_DEBUG(2), "Data pkt to node %u sent to PD successfully",
                node->id);
    }

done:
    free(pd_hdr);
    return retcode;
}


int centroute_data_dev_send(lp_context_t *lp, link_pkt_t *pkt, int datalen,
        int loop_needed)
{
    cr_state_t *crstate = (cr_state_t *)lp_data(lp);
    node_t *node=NULL;
    int n=0;
    uint16_t node_id= (uint16_t)(pkt->dst.id);
    link_pkt_t *link_pkt = (link_pkt_t *)pkt;

    if (pkt->type != PKT_TYPE_CENTROUTE_DATA) {
        elog(LOG_ERR, "Got unexpected pkt type %d, ignoring pkt", pkt->type);
        return EINVALIDTYPE;
    }


    node = find_node_in_local_nodes_list(node_id, crstate);

    // TODO: handle transmissions to nodes in OTHER FLOCKS!!!
    if (node==NULL) {
        elog(LOG_ERR, "Cannot send pkt to node %u; node doesn't exist in"
                " local nodes list!", node_id);
        return 0;
    }

    // TODO: perhaps handle A_P case?
    if (node->state!=ASSOCIATED_VERIFIED) {
        elog(LOG_ERR, "Cannot send data to node %u: node hasn't verified"
                " association (state = %d)", 
                node->id, node->state);
        return 0;
    }


    // node is good
    // send the pkt over
    n = send_data_pkt_to_pd(node, pkt->data, pkt->ext_type, datalen, crstate);
    if (loop_needed) {
        link_pkt->src.id = crstate->data_lp_status.if_id;
        lp_loop_receive(lp, link_pkt, datalen);
    }
   
    // XXX XXX XXX
    // Note: changing this to n instead of 0...need to figure out if it's ok
    return n;
}


int centroute_data_dev_status(lp_context_t *lp)
{
    cr_state_t *crstate = (cr_state_t *)lp_data(lp);
    lp_push_status(lp, &(crstate->data_lp_status));
    
    return EVENT_RENEW;
}


int centroute_data_dev_ioctl(lp_context_t *lp, int cmd, void *arg)
{
    return 0;
}


int centroute_data_dev_parse_commands(lp_context_t *lp, 
        parser_state_t *cmd_input)
{
    return 0;
}


void centroute_data_dev_usage(lp_context_t *lp, buf_t *buf)
{
}





int create_data_link_dev(cr_state_t *crstate, char *link_name_str, 
        char *class_name)
{
    lp_opts_t opts = {
        description: "Centroute raw data interface",
        opts: {
            name: link_name_str,
            if_class: class_name,
            data: crstate,
        },
        
        initial_status : {
            // TODO: fix the mtu!
            MTU: 200,
            if_id: my_node_id,
        },

        send: centroute_data_dev_send,
        status_request: centroute_data_dev_status,
        ioctl: centroute_data_dev_ioctl,

        command_request: centroute_data_dev_parse_commands,
        usage: centroute_data_dev_usage,

        we_are_root:1
    };


    if (lp_register(&opts, &(crstate->data_lp_context)) < 0) {
        elog(LOG_CRIT, "Can't create link device %s: %m",
                link_name(&opts.opts, NULL));
        exit(1);
    }

    if (crstate==NULL) {
        elog(LOG_ERR, "NULL crstate ptr!");
        exit(1);
    }

    crstate->data_lp_status.active=1;
    crstate->data_lp_status.POT=0;
    crstate->data_lp_status.MTU=opts.initial_status.MTU;
    crstate->data_lp_status.if_id = opts.initial_status.if_id;


    return 0;
}


int convert_raw_data_pkt_to_link_pkt(up_hdr_t *up_hdr, link_pkt_t **link_pkt,
        uint8_t client_type, int orig_len)
{
    int buf_len=sizeof(link_pkt_t)+orig_len;
    int payload_len=0;
    char *buf=NULL;
    int len_adjust=0;
    int offset=0;
    int i=0;

   
    if (link_pkt==NULL) {
        elog(LOG_ERR, "NULL link_pkt ptr");
        exit(1);
    }

    if (up_hdr==NULL) {
        elog(LOG_ERR, "NULL up_hdr ptr!");
        exit(1);
    }

    offset = up_hdr->path_entries * sizeof(up_path_entry_t);

    len_adjust = offset + sizeof(up_hdr_t);
    // adjust buf_len
    buf_len -= len_adjust;
    payload_len = buf_len - sizeof(link_pkt_t);

    // allocate mem for the buf based on the buf_length
    buf = malloc(buf_len);
    memset(buf, 0, buf_len);

    *link_pkt = (link_pkt_t *)buf;

    if (up_hdr->final_dst==TOS_BCAST_ADDR) {
        (*link_pkt)->dst.id = my_node_id;
    } else {
        (*link_pkt)->dst.id = up_hdr->final_dst;
    }
    (*link_pkt)->src.id = up_hdr->orig_src;
    (*link_pkt)->type = PKT_TYPE_CENTROUTE_DATA;
    (*link_pkt)->ext_type = client_type;
    // we're using max hop to store the number of path entries
    (*link_pkt)->max_hops = up_hdr->path_entries;

    for (i=0; i<up_hdr->path_entries; i++) {
        up_path_entry_t *entry = (up_path_entry_t *)(up_hdr->data);
        (*link_pkt)->numTx += entry->retx_count;
    }

    // copy payload
    memcpy((*link_pkt)->data, &up_hdr->data[offset], payload_len);

    // done, return buf_len which is the length of the entire link_pkt
    // INCLUDING the header
    return payload_len;
}





See more files for this project here

EmStar

EmStar is a software system for developing and deploying wireless sensor networks involving Linux-based platforms. As the wireless sensor network community has attempted to deploy more complex designs---large-scale, long-lived systems that need self-organization and adaptivity---a number of difficult software design issues have arisen. Advances in software design have not kept pace with the capabilities of hardware. This is because designing for an adaptive, efficient, and useful sensor network has turned out to be surprisingly complex and difficult. EmStar is a Linux-based software framework, whose goal is to dramatically reduce this complexity, enabling work to be shared and reused, and simplifying and speeding the design of new sensor network applications.

Project homepage: http://cvs.cens.ucla.edu/emstar/
Programming language(s): C,Shell Script
License: other

  BUILD
  centroute_i.h
  centroute_lt.c
  centroute_main.c
  centroute_query.c
  centroute_ssync.c
  centroute_status.c
  centroute_upper.c
  centroute_utils.c