Show idr_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.
*
*/
/*
* idr_upper.c: The "upper" half of idr, i.e. the interface that
* we provide to users of the idr service.
*
* $Id: idr_upper.c,v 1.6 2003/07/11 22:29:52 cerpa Exp $
*/
char idr_upper_c_cvsid[] = "$Id: idr_upper.c,v 1.6 2003/07/11 22:29:52 cerpa Exp $";
#include <stdio.h>
#include <stdlib.h>
#include "link/link.h"
#include "idr_i.h"
/********************************************************************/
/*
* Called when a local client tries to write a packet to our idr
* device file. Check the packet is valid before admitting it to the
* queue.
*/
static int idr_enqueue(pd_context_t *pd, const void *packet, int packetlen)
{
idr_state_t *f = (idr_state_t *) pd_data(pd);
if (packetlen < sizeof(link_pkt_t)) {
elog(LOG_ERR, "short packet (%d bytes) written to %s", packetlen, idr_dev_name(f));
return -EINVAL;
}
return 0;
}
/*
static void pktbuf_add(buf_t *buf, idr_state_t *s)
{
if (s->pktbuf[s->index]!=NULL) {
buf_free(s->pktbuf[s->index]);
}
s->pktbuf[s->index]=buf;
s->index++;
if (s->index>=PKT_QUEUE_SIZE) {
s->index=0;
}
}
*/
/*
* Callback when the queue of packets written to our local device file
* is serviced
*/
static int idr_send(pd_context_t *pd, const void *packet,
int packetlen, int loop_needed)
{
idr_state_t *f = (idr_state_t *) pd_data(pd);
// link_pkt_in is the packet being given to us by the user to send.
link_pkt_t *link_pkt_in = (link_pkt_t *) packet;
int data_len = packetlen - sizeof(link_pkt_t);
// pkt_out is the packet we're getting ready to transmit
buf_t *pkt_out = buf_new();
// Create our *outgoing* link header
link_pkt_t link_hdr = {
dst: {
id: LINK_BROADCAST, // we always want to broadcast our message
},
type: PKT_TYPE_IDR,
};
// Create the idr-specific header
idr_pkt_t idr_hdr = {
sender: my_node_id,
sub_type: IDR_DATA,
};
idr_data_pkt_t idr_data_hdr = {
inner_type: link_pkt_in->type,
toAddr: 0,
count: 0,
};
// Construct the packet: outer link header, inner idr header and idr
// data sub packet, user payload
bufcpy(pkt_out, &link_hdr, sizeof(link_hdr));
bufcpy(pkt_out, &idr_hdr, sizeof(idr_hdr));
bufcpy(pkt_out, &idr_data_hdr, sizeof(idr_data_hdr));
bufcpy(pkt_out, link_pkt_in->data, data_len);
// Send to all interfaces
idr_send_to_all(f,
(link_pkt_t *) pkt_out->buf,
pkt_out->len - sizeof(link_pkt_t));
// add buffer to the buffer queue, so the we can retx it later
// pktbuf_add(pkt_out, f);
// remove any old packets currently in the component state buffer queue
if (f->pktbuf!=NULL) {
buf_free(f->pktbuf);
}
// add the current packet to the buffer queue
f->pktbuf=pkt_out;
return 0;
}
/*
* Register the idr device that other processes open to send idr
* packets
*/
void idr_register_packetdev(idr_state_t *f)
{
/* set options for the packetdev */
packet_dev_opts_t pd_opts = {
send: idr_send,
enqueue: idr_enqueue,
filter: link_standard_filter,
device: {
device_info: (void *) f,
}
};
// and options to tell it what we're trying to register
memset(&(f->pd_link_opts), 0, sizeof(link_opts_t));
f->pd_link_opts.dev_type = LINK_DEV_IDR;
/* try to register the packetdev as a link interface */
if (link_register(&pd_opts, &f->pd_context, &f->pd_link_opts) < 0) {
elog(LOG_CRIT, "can't create packetdev %s: %m", pd_opts.device.devname);
exit(1);
}
elog(LOG_INFO, "created upper interface, %s", pd_opts.device.devname);
}
See more files for this project here