
              SIMPLIFIED ASYNCHRONOUS NETWORK PROCESSOR API


*****************
* FRAME BUFFERS *
*****************



Structure
---------

struct fbuffer
{
  int len;
  int ifnum;
  int ofnum;
  char frame[1];
};

A frame buffer (struct fbuffer) is a structure which stores a frame and 
information about it. 



Fields
------

The "len" field is set to the total length of the frame.

The "ifnum" field is set to the number of the interface on which the frame was
received.

The "ofnum" field is set to the number of the interface on which the frame will
be sent.  (by send_frame())

The "frame" field is a handle to the memory containing the actual frame data
including any frame headers.



Allocation
----------

A programmer should never declare a frame buffer variable directly.  He should 
instead allocate memory sufficient for holding a frame plus the control 
information held in a frame buffer, and store the address of this memory in a
frame buffer pointer.  The new_fbuf() function (see below) can be used to 
allocate a frame buffer from heap space (using malloc) specifying only the 
length of frame field.

Dynamically allocated frame buffers must be disposed of by the programmer.  
None of this API's functions attempt to deallocate the memory pointed to by a 
frame buffer pointer.

Examples: 
(assume we are working in an Ethernet only environment so frames have a maximum
size of 1500 bytes plus the Ethernet header)

  struct fbuffer *fb;
  int buffer[2048];

  fb = (struct fbuffer *)buffer;
  fb = malloc(1514 + sizeof(int) * 3);
  fb = new_fbuf(1514);



*************
* FUNCTIONS *
*************



Function List:
--------------
on_startup()
on_shutdown()
recv_frame()
send_frame()
delayed_call()
periodic_call()
cancel_call()
new_fbuf()
console_command()


Detailed Function Descriptions:
-------------------------------

Name:			-- The name of the function
Prototype:		-- The function's formal prototype
Arguments:		-- The parameters of the function
Summary:		-- A quick description of what the function does
Returns Value		-- What the function returns
Side Effects:		-- Values modified in global state or parameters
Description:		-- In depth description of the function



Name:
-----
on_startup


Prototype:
---------
void on_startup(void);


Arguments:
----------
None


Summary:
--------
Called during the initialization of a network processor program.


Return Value:
-------------
This function should return a 0 if initialization was completed successfully
and a negative value otherwise.  By default the function returns a 0.


Side Effects:
-------------
User defined.


Description:
------------
The on_startup() function is called during the initialization of the network 
processor software.  By default it does nothing.  However, a user can insert
code into this function to perform program-specific initialization tasks.  This
function should be located in startup.c.  This function should be written to
return a negative value if an error occurs during initialization and a 0 
otherwise.  Returning a negative value from this function will terminate the 
network processor program.





Name:
-----
on_shutdown


Prototype:
---------
void on_shutdown(void);


Arguments:
----------
None.


Summary:
--------
Called when a network processor program is finished running for cleanup.


Return Value:
-------------
None.


Side Effects:
-------------
User defined.


Description:
------------
This function is called just before a network processor program is terminated.
It is used to clean up any resources that won't be automatically reclaimed by
the operating system on termination as well as any persistent state (e.g.
status files).  This function does nothing by default, but the programmer can 
insert code as they see fit to handle cleanup tasks.  This function should be
located in on_shutdown.c.





Name:
-----
recv_frame


Prototype:
---------
void recv_frame(struct fbuffer *fbuf);


Arguments:
----------
fbuf		-- a pointer to a frame buffer.  The frame buffer contains a 
		   newly-received frame from the network.


Summary:
--------
Called when a new frame is received.


Return Value:
-------------
None.


Side Effects:
-------------
User defined.


Description:
------------
The recv_frame() function is called whenever a new frame is received by the 
network-processor program.  The entire frame is stored in the frame buffer data
section fbuf->frame.  The interface upon which this frame arrived is stored in
fbuf->ifnum.  The length of the entire frame is stored in fbuf->len.  This
frame buffer must be deallocated using free() once the packet is no longer 
needed.  Failing to deallocate the frame buffer creates a serious memory leak.

The default implementation of the recv_frame() function simply discards 
(i.e. free()'s) the frame passed to it.  The programmer should redefine this 
function to process input frames.

WARNING: The frame buffer passed to recv_frame() is sized precisely to the 
received frame.  Do not attempt to increase the length of this frame, for 
example, by inserting headers.  If you wish to do this, allocate a new frame 
(see above) and copy the original frame plus the extra data into it.



Name:
-----
send_frame


Prototype:
---------
int send_frame(struct fbuffer *fbuf);


Arguments:
----------
fbuf		-- A frame buffer fbuf to send out into the network.


Summary:
--------
Sends a frame into the network.


Return Value:
-------------
Returns a 0 on successful completion and a negative value if an error occurred.


Side Effects:
-------------
Creates network traffic on successful completion.


Description:
------------
The send_frame() function sends a frame stored in fbuf->frame out the network
interface fbuf->ofnum.  It returns a 0 if the frame was successfully enqueued
for output, and a negative value otherwise.  Note that successful queuing for
output is not a guarantee that the packet will be successfully transmitted.
The send_frame() function copies the frame buffer passed to it as input and does
not modify it in any way.  Thus dynamically created frame buffers (such as those
passed to recv_frame() as a parameter) must still be manually deallocated even
after send_frame() is called.





Name:
-----
delayed_call


Prototype:
---------
int delayed_call(timer_func f, void *arg, int delay);


Arguments:
----------
f		-- A function to call after a specified period of time
arg		-- An argument to pass to the function f when it is called
delay		-- The number of milliseconds to wait before calling f


Summary:
--------
Calls function "f" with argument "arg" after "delay" milliseconds.


Return Value:
-------------
Returns an integer handle for canceling the timer on success or a -1 on
failure.


Side Effects:
-------------
Schedules a function to be called later.


Description:
------------
The delayed_call() function is used to schedule another function ("f") to be
called asynchronously at some point in time in the future.  The function "f"
must have return a void value and take a void pointer for its only argument.
The "f" function is passed the "arg" parameter (to delayed_call()) as its
parameter when it is called.  This allows the function to be passed auxiliary
data.  The "delay" variable specifies the number of milliseconds to wait before
calling "f".  This function returns a handle which can be used to cancel the 
callback if desired.  (see cancel_call())  At most NTIMEEVENT callbacks can be
scheduled using delayed_call() and periodic_call() at one time.  If the
programmer tries to schedule more or if an internal error occurs in scheduling
the event, delayed_call() will return -1 and the callback will not be
scheduled.  NTIMEEVENT is defined in npapi.h.





Name:
-----
periodic_call


Prototype
int periodic_call(timer_func f, void *arg, int period);


Arguments:
----------
f		-- A function to called every "delay" seconds
arg		-- An argument to pass to the function f when it is called
period		-- The number of milliseconds to wait before calling f each time


Summary:
--------
Periodically calls function "f" with argument "arg" every "delay" milliseconds.


Return Value:
-------------
Returns an integer handle for canceling the timer on success or a -1 on
failure.


Side Effects:
-------------
Schedules a function to be called periodically.


Description:
------------
The periodic_call() function is used to schedule another function ("f") to be
called periodically and asynchronously.  The function "f" must have return a 
void value and take a void pointer for its only argument.  The "f" function is 
passed the "arg" parameter (of periodic_call()) as its parameter when it is 
called.  This allows the function to be passed auxiliary data.  The "period" 
variable specifies the number of milliseconds between each call of "f".  The
first call to "f" is delayed by "period" seconds.  This function returns a
handle which can be used to cancel the timer if desired.  (see cancel_call())
At most NTIMEEVENT callbacks can be scheduled using delayed_call() and
periodic_call() at one time.  If the programmer tries to schedule more or if
an internal error occurs in scheduling the event, periodic_call() will return
-1 and the callback will not be scheduled.  NTIMEEVENT is defined in npapi.h.





Name:
-----
cancel_call


Prototype:
---------
void cancel_call(int handle);


Arguments:
----------
handle		-- A callback handle returned by periodic_call() or 
		   delayed_call()


Summary:
--------
Cancels an asynchronous callback.


Return Value:
-------------
None.


Side Effects:
-------------
Cancels an outstanding time event.


Description:
------------
The cancel_call() function cancels an asynchronous callback scheduled using
periodic_call() or delayed_call().  The "call" parameter should be a
integer handle returned by periodic_call() or delayed_call().  Canceling a
periodic callback prevents all future invocations of that callback, not just
the next invocation.  A periodic callback could later be rescheduled using
periodic_call().





Name:
-----
new_fbuf


Prototype:
---------
struct fbuffer *new_fbuf(int framelength);


Arguments:
----------
framelength	-- The number of bytes to allocate for the frame


Summary:
--------
Allocates a new block of memory for a frame buffer.


Return Value:
-------------
A pointer to the newly allocated frame buffer, or 0 if the memory couldn't be
allocated or "framelength" was less than 1.


Side Effects:
-------------
None.


Description:
------------
The new_fbuf() function allocates memory for a new frame buffer in the heap.  
The new buffer's "frame" field is allocated "framelength" bytes.  The
"len" field is initialized to "framelength".  The ifnum field is initialized to
0 because even fabricated packets must be given a valid incoming interface
number in order to be transmitted properly by the underlying software.  If
"framelength" is less than 1 or the memory isn't available for a new frame
buffer, then the function returns 0.  Otherwise new_fbuf() returns a pointer to
the frame buffer structure.  This structure must be released with free() when
the network processor program is finished using it.





Name:
-----
console_command


Prototype:
---------
void console_command(const char *command);


Arguments:
----------
command		-- A command string sent from the console


Summary:
--------
User-defined action to take when the "send_command" application is run.


Return Value:
-------------
None.


Side Effects:
-------------
User-defined.


Description:
------------
The "console_command" function is called whenever the "send_command" application
is run.  The application sends a string to the ACE which is copied to the 
"command" argument to the console_command function.  The send_command program 
sends its first command-line argument to console_command.

The default implementation of console_command simply prints its argument back
to the console.  The user should redefine this function in console.c to accept
management commands from the console.

WARNING:  The command argument is deliberately passed as a "const" character
string.  Modifying the contents of this string, besides generating a compiler
warning or error, could cause unpredictable side effects.  If you need to
modify the command string, for example to parse it or store it, make a copy in
dynamic storage.

WARNING:  send_command only sends its first command line parameter to the ACE.
Thus if a user enters './send_command foo bar baz', the console_command function
will only receive the string "foo" since spaces delimit arguments in the shell.
A user can use quotes to offset this.  For example: 'send_command "foo bar baz"'
will result in console_command receiving "foo bar baz".
