Пример #1
0
//-----------------------------------------------------------------------------
// send a route request
void send_route_request(CnetAddr destaddr) {
    if (pending_route_requests[destaddr] == NULLTIMER) {
        ROUTE_PACKET req_packet;
        req_packet.type = RREQ;
        req_packet.source = nodeinfo.address;
        req_packet.dest = destaddr;
        req_packet.hop_count = 0;
        req_packet.total_delay = 0;
        req_packet.req_id = route_req_id;
        req_packet.min_mtu = 0;
        route_req_id++;
        uint16_t request_size = ROUTE_PACKET_SIZE(req_packet);
        DATAGRAM r_packet = alloc_datagram(__ROUTING__, nodeinfo.address,
                                           destaddr, (char*) &req_packet,
                                           request_size);

        // start timer for pending route request
        pending_route_requests[destaddr] =
                CNET_start_timer(EV_ROUTE_PENDING_TIMER, ROUTE_REQUEST_TIMEOUT, destaddr);
        route_notified[destaddr] = 0;

        // insert into local history table
        insert_local_history(req_packet.source,req_packet.dest, req_packet.req_id);
        broadcast_packet(r_packet, -1);
    }
}
Пример #2
0
void packet_loop(void) {
    sensor_data_t packet;
    char c;
    
    while (1) {
		memset(&packet, '\0', sizeof(sensor_data_t));
		#ifndef TESTMODE
        read(serial_port, &c, 1);
        if (c != 'A')
            continue;
        
        fprintf(stderr, "GOT START\n");
        
        // RTC
        myread(serial_port, &packet.rtc.tm_hour, 2);
        myread(serial_port, &packet.rtc.tm_min, 2);
        myread(serial_port, &packet.rtc.tm_sec, 2);
        
        // IMU
        myread(serial_port, &packet.imu.gx, 2);
        myread(serial_port, &packet.imu.gy, 2);
        myread(serial_port, &packet.imu.ax, 2);
        myread(serial_port, &packet.imu.ay, 2);
        myread(serial_port, &packet.imu.az, 2);
        
        // SCP
        myread(serial_port, &packet.bmp.raw_pressure, 4);
        myread(serial_port, &packet.bmp.raw_temperature, 2);
        
        // GPS
        myread(serial_port, &packet.gps.f_latitude, 4);
        myread(serial_port, &packet.gps.f_longitude, 4);
        myread(serial_port, &packet.gps.u_altitude, 2);
        myread(serial_port, &packet.gps.u_valid, 1);
        myread(serial_port, &packet.gps.u_satellites, 1);
        
        myread(serial_port, &packet.humidity, 2);
        myread(serial_port, &packet.bearing, 2);
        myread(serial_port, &packet.light, 2);
        myread(serial_port, &packet.internal_temp, 2);
		myread(serial_port, &packet.extern_temp, 2);

		myread(serial_port, &packet.gsm_registered, 1);
		myread(serial_port, &packet.gsm_ready, 1);
 
        myread(serial_port, &c, 1);
        if (c != 'Z')
            continue;
        #endif
        
        // push packet to telemetry topic
        char *xml = (char *)calloc(10000, sizeof(char));
        packet_to_xml(&packet, xml);
        int retval = broadcast_packet(xml, strlen(xml));
        free(xml);
        fprintf(stderr, "Published packet: %u\n", retval);
        sleep(1);
    }
}
Пример #3
0
/**
 * Forward packets to correct output buffers
 *
 * Packets, whose destination MAC address is already known from previously
 * received packets, are forwarded to the matching switch ports. Packets
 * destined to unknown addresses are broadcasted to all switch ports (except
 * the ingress port).
 *
 * @param pkt_tbl    Array of packets
 * @param num        Number of packets in the array
 * @param thr_arg    Thread arguments
 * @param port_in    Input port index
 */
static inline void forward_packets(odp_packet_t pkt_tbl[], unsigned num,
				   thread_args_t *thr_arg, uint8_t port_in)
{
	odp_packet_t pkt;
	odph_ethhdr_t *eth;
	unsigned i;
	unsigned buf_id;
	int ret;
	uint8_t port_out = 0;

	for (i = 0; i < num; i++) {
		pkt = pkt_tbl[i];

		if (!odp_packet_has_eth(pkt)) {
			odp_packet_free(pkt);
			continue;
		}

		eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);

		/* Lookup source MAC address */
		ret = mac_table_get(&eth->src, &port_out);

		/* Update for address table if necessary */
		if (ret < 0 || port_out != port_in)
			mac_table_put(&eth->src, port_in);

		/* Lookup destination MAC address */
		ret = mac_table_get(&eth->dst, &port_out);
		if (ret < 0) {
			/* If address was not found, broadcast packet */
			broadcast_packet(pkt, thr_arg, port_in);
			continue;
		}
		buf_id = thr_arg->tx_pktio[port_out].buf.len;

		thr_arg->tx_pktio[port_out].buf.pkt[buf_id] = pkt;
		thr_arg->tx_pktio[port_out].buf.len++;
	}
}
Пример #4
0
/*
 * RCrecv_callback()
 *
 * The receive packet callback routine.  This is called by
 * RCProcMsgQ() after the adapter posts buffers which have been
 * filled (one ethernet packet per buffer).
 */
static void
RCrecv_callback(U32  Status,
                U8   PktCount,
                U32  BucketsRemain,
                PU32 PacketDescBlock,
                U16  AdapterID)
{

    U32 len, count;
    PDPA pDpa;
    struct sk_buff *skb;
    struct device *dev;
    singleTCB tcb;
    psingleTCB ptcb = &tcb;


    pDpa = PCIAdapters[AdapterID];
    dev = pDpa->dev;

    ptcb->bcount = 1;

#ifdef RCDEBUG
    printk("rc: RCrecv_callback: 0x%x, 0x%x, 0x%x\n",
           (uint)PktCount, (uint)BucketsRemain, (uint)PacketDescBlock);
#endif

#ifdef RCDEBUG
    if ((pDpa->shutdown || pDpa->reboot) && !Status)
        printk("shutdown||reboot && !Status: PktCount = %d\n",PktCount);
#endif

    if ( (Status != RC_REPLY_STATUS_SUCCESS) || pDpa->shutdown)
    {
        /*
         * Free whatever buffers the adapter returned, but don't
         * pass them to the kernel.
         */

        if (!pDpa->shutdown && !pDpa->reboot)
            printk("rc: RCrecv error: status = 0x%x\n", (uint)Status);
        else
            printk("rc: Returning %d buffers, status = 0x%x\n",
                   PktCount, (uint)Status);
        /*
         * TO DO: check the nature of the failure and put the adapter in
         * failed mode if it's a hard failure.  Send a reset to the adapter
         * and free all outstanding memory.
         */
        if (Status == RC_REPLY_STATUS_ABORT_NO_DATA_TRANSFER)
        {
#ifdef RCDEBUG
            printk("RCrecv status ABORT NO DATA TRANSFER\n");
#endif
        }
        /* check for reset status: RC_REPLY_STATUS_ABORT_NO_DATA_TRANSFER */
        if (PacketDescBlock)
        {
            while(PktCount--)
            {
                skb = (struct sk_buff *)PacketDescBlock[0];
                skb->free = 1;
                skb->lock = 0;
#ifdef RCDEBUG
                printk("free skb 0x%p\n", skb);
#endif
                dev_kfree_skb(skb, FREE_READ);
                pDpa->numOutRcvBuffers--;
                PacketDescBlock += BD_SIZE; /* point to next context field */
            }
        }
        return;
    }
    else
    {
        while(PktCount--)
        {
            skb = (struct sk_buff *)PacketDescBlock[0];
#ifdef RCDEBUG
            if (pDpa->shutdown)
                printk("shutdown: skb=0x%x\n", (uint)skb);

            printk("skb = 0x%x: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", (uint)skb,
                   (uint)skb->data[0], (uint)skb->data[1], (uint)skb->data[2],
                   (uint)skb->data[3], (uint)skb->data[4], (uint)skb->data[5]);
#endif
            if ( (memcmp(dev->dev_addr, skb->data, 6)) &&
                    (!broadcast_packet(skb->data)))
            {
                /*
                 * Re-post the buffer to the adapter.  Since the adapter usually
                 * return 1 to 2 receive buffers at a time, it's not too inefficient
                 * post one buffer at a time but ... may be that should be
                 * optimized at some point.
                 */
                ptcb->b.context = (U32)skb;
                ptcb->b.scount = 1;
                ptcb->b.size = MAX_ETHER_SIZE;
                ptcb->b.addr = (U32)skb->data;

                if ( RCPostRecvBuffers(pDpa->id, (PRCTCB)ptcb ) != RC_RTN_NO_ERROR)
                {
                    printk("rc: RCrecv_callback: post buffer failed!\n");
                    skb->free = 1;
                    dev_kfree_skb(skb, FREE_READ);
                }
                else
                {
                    pDpa->numOutRcvBuffers++;
                }
            }
            else
            {
                len = PacketDescBlock[2];
                skb->dev = dev;
                skb_put( skb, len ); /* adjust length and tail */
                skb->protocol = eth_type_trans(skb, dev);
                netif_rx(skb);    /* send the packet to the kernel */
                dev->last_rx = jiffies;
            }
            pDpa->numOutRcvBuffers--;
            PacketDescBlock += BD_SIZE; /* point to next context field */
        }
    }

    /*
     * Replenish the posted receive buffers.
     * DO NOT replenish buffers if the driver has already
     * initiated a reboot or shutdown!
     */

    if (!pDpa->shutdown && !pDpa->reboot)
    {
        count = RC_allocate_and_post_buffers(dev,
                                             MAX_NMBR_RCV_BUFFERS-pDpa->numOutRcvBuffers);
        pDpa->numOutRcvBuffers += count;
    }

}
Пример #5
0
//-----------------------------------------------------------------------------
// process a routing datagram
void do_routing(int link, DATAGRAM datagram) {

    ROUTE_PACKET r_packet;
    size_t datagram_length = datagram.length;
    memcpy(&r_packet, &datagram.payload, datagram_length);

    switch (r_packet.type) {
    case RREQ:
        // check local history if we already processed this RREQ
        if (find_local_history(r_packet.source,r_packet.dest, r_packet.req_id) != -1) {
            break;
        }
        // insert into local history table
        insert_local_history(r_packet.source, r_packet.dest, r_packet.req_id);

        // set up mtu and delays
        if (r_packet.min_mtu == 0) {
            r_packet.min_mtu = linkinfo[link].mtu;
        } else {
            if (r_packet.min_mtu > linkinfo[link].mtu) {
                r_packet.min_mtu = linkinfo[link].mtu;
            }
        }
        if (r_packet.total_delay == 0) {
            r_packet.total_delay = linkinfo[link].propagationdelay;
        } else {
            r_packet.total_delay += linkinfo[link].propagationdelay;
        }
        r_packet.hop_count = r_packet.hop_count + 1;

        // the current node is not the destination
        if (nodeinfo.address != r_packet.dest) {
            // if a route exist to this destination
            if (is_neighbour(r_packet.dest)) {
                int next_link = get_next_link_for_dest(r_packet.dest);
                uint16_t request_size = ROUTE_PACKET_SIZE(r_packet);
                DATAGRAM rreq_datagram = alloc_datagram(__ROUTING__, r_packet.source,
                                                   r_packet.dest, (char*) &r_packet,
                                                   request_size);
                insert_reverse_route(r_packet.source,r_packet.dest,link,r_packet.req_id);
                send_packet_to_link(next_link,rreq_datagram);
            } else {
                // if no route rebroadcast
                uint16_t request_size = ROUTE_PACKET_SIZE(r_packet);
                DATAGRAM rreq_datagram =
                        alloc_datagram(__ROUTING__, r_packet.source,
                                       r_packet.dest, (char*) &r_packet, request_size);
                insert_reverse_route(r_packet.source, r_packet.dest,link, r_packet.req_id);
                broadcast_packet(rreq_datagram,link);
            }
        } else {
            // learn the route table
            insert_reverse_route(r_packet.source, r_packet.dest, link, r_packet.req_id);

            // send RREP
            ROUTE_PACKET rrep_packet;
            rrep_packet.source = r_packet.source;
            rrep_packet.dest = r_packet.dest;
            rrep_packet.type = RREP;
            rrep_packet.req_id = r_packet.req_id;
            rrep_packet.forward_min_mtu = r_packet.min_mtu;
            rrep_packet.min_mtu = linkinfo[link].mtu;
            rrep_packet.total_delay = linkinfo[link].propagationdelay;
            rrep_packet.hop_count = 0;
            uint16_t request_size = ROUTE_PACKET_SIZE(rrep_packet);
            DATAGRAM rrep_datagram =
                    alloc_datagram(__ROUTING__, r_packet.dest, r_packet.source,
                                   (char*) &rrep_packet, request_size);

            send_packet_to_link(link,rrep_datagram);
        }
        break;
    case RREP:
        r_packet.hop_count = r_packet.hop_count + 1;

        if (nodeinfo.address != r_packet.source) {
            // insert into the forward table
            insert_forward_route(r_packet.source, r_packet.dest, link, r_packet.req_id);
            // find a reverse link
            int reverse_link = find_reverse_route(r_packet.source, r_packet.dest,
                                                  r_packet.req_id);
            if (reverse_link == -1) {
                abort();
            }
            if (r_packet.min_mtu > linkinfo[reverse_link].mtu) {
                r_packet.min_mtu = linkinfo[reverse_link].mtu;
            }
            r_packet.total_delay += linkinfo[reverse_link].propagationdelay;
            uint16_t request_size = ROUTE_PACKET_SIZE(r_packet);
            DATAGRAM rrep_datagram =
                    alloc_datagram(__ROUTING__, r_packet.dest, r_packet.source,
                                   (char*) &r_packet, request_size);
            send_packet_to_link(reverse_link,rrep_datagram);

        } else {
            learn_route_table(r_packet.dest, r_packet.hop_count, link, r_packet.min_mtu,
                              r_packet.total_delay, r_packet.req_id);

        }
        break;
    }
}