//
//  CS461 Distributed Computing and Networking
//  Princeton University
//  Tammo Spalink, Andy Bavier
// 
//  Revision 9
//

#ifndef _INTERFACE_H
#define _INTERFACE_H

#include <sys/socket.h>
#include <sys/types.h>

typedef enum {
    CS461_INTOFF   = 0,
    CS461_INTCLOCK = 1,
    CS461_INTRECV  = 2,
    CS461_INTON    = 3
} CS461_InterruptState;

extern void
CS461_Initialize(
    unsigned short protocol,       // e.g. IPPROTO_TCP
    void (* recvCallback)(void *), // called for incoming packets
    void (* clockCallback)(void),  // called at clockPeriod intervals
    unsigned long long clockPeriod,// time in milliseconds
    int debug)                     // Boolean to debug or not to debug
    // This will initialize the interface library.  It will create a
    // firewall rule to capture all packets destined to the extra
    // cluster IP addresses and forward them to user space.  Only
    // "protocol" packets will be captured.  Debugging messages for
    // the library will be turned on if the "debug" flag is TRUE.
    // Whenever data arrives, the callback function will be called
    // with the the new packet.  If either callback is NULL, it will
    // be disabled.  The recvCallback is passed a region of memory
    // that begins with an IP header.  The memory region must be freed 
    // using CS461_Free() after processing is complete.
;

extern CS461_InterruptState
CS461_GetInterruptState()
    // Returns the current recv and clock callback state
;

extern CS461_InterruptState
CS461_InterruptToggle(CS461_InterruptState state)
    // Toggle the use of the revc and clock callbacks.  This is
    // important to synchronize the execution of the callbacks so that
    // they do not interfere with other tasks.  If a callback would
    // have occurred one or more times during a toggle to off period,
    // it will be called only once immediately after a toggle to on.
    // The previous toggle setting is returned.
;

extern unsigned int
CS461_GetIpAlias(void)
    // Returns the IP address at which data may be recieved.
;

extern void
CS461_Block(void)
    // Wait for a an event to occur.  Regardless of the state of
    // CS461_Interrupts, CS461_Block return after either a clock or
    // packet event has occurred and after the appropriate callback
    // has been issued.
;

extern void
CS461_SendIov(
    unsigned long int nextHop,  // Where packet is actually sent to
    struct iovec *iov,          // Vector of data to send from
    size_t iovlen)              // Number of elements in the vector
    // Send the data specified by the iov.  Wait until the send has
    // completed.  The data must start with an IP header.  IOVs are
    // described in bits/uio.h
;

extern void
CS461_Free(void *ptr)
    // Free a packet that was delivered to recvCallback()  
    // Always call this after packet processing is complete.
;

#endif // _INTERFACE_H

