/*
    Copyright 2000 (c) by Claudio Jeker,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.
 
    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.
 
    For further information, please visit http://www.tik.ee.ethz.ch/~topsy
 
    This software is provided under the terms of the GNU General Public 
    Licence. A full copy of the GNU GPL is provided in the file COPYING 
    found in the development root of Topsy.
*/
/*
	
    File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/Net/NetModulesNew.h,v $
    Affiliation:           ETH Zuerich, TIK
    Version:               $Revision: 2922 $
    Last Date of Change:   $Date: 2007-03-19 17:48:52 +0100 (Mon, 19 Mär 2007) $  by: $Author: baderma $
 
*/
#ifndef _NETMODULESNEW_H_ /* XXX */
#define _NETMODULESNEW_H_

#include "Messages.h"
#include "NetBuf.h"
#include "NetAttr.h"
#include "LWThreads.h"


#define NET_MODOK 0
#define NET_MODFAILED 1

typedef struct NetModuleDesc_t *NetModule;
typedef struct NetModuleReg_t *NetModuleReg;

typedef long NetModuleId;
typedef unsigned long NetModuleType;

typedef LWThreadMainFunction ModuleMainFunction;
typedef int (*ModuleConfFunction)(NetModule this, Message *msg);
typedef void (*ModuleInitFunction)(NetModule this);

#define NET_MOD_NAMESIZE 16

typedef struct NetModuleReg_t
{
  NetModuleReg		prev, next;
  NetModuleType		type;
  unsigned long		count;
  ModuleMainFunction	mainFunc;
  ModuleConfFunction	confFunc;
  ModuleInitFunction	initFunc;
  char				name[NET_MOD_NAMESIZE];
}
NetModuleRegDesc;


typedef struct NetModuleDesc_t
{
  NetModule		chain;
  NetModule		prev, next;
  NetModuleId		id;
  NetModuleReg	head;
  NetAttrs		attributes;
  unsigned long	count;
  void*			extra;
}
NetModuleDesc;

typedef struct NetChain_t
{
  ModuleMainFunction	function;
  NetModuleId			id;
  NetModule			arg;
}
NetChain;

/* don't forget to change the shifting values below if you make changes here! */
/* XXX this method of error returning is not very logic. Sorry */
#define CONF_SUCCED_RETURN_MASK 0xFF
#define CONF_IGNORE_RETURN_MASK 0xFF00
#define CONF_FAILED_RETURN_MASK 0xFF0000

#define CONF_SUCCEDPLUS(x) \
		x = (x & ~CONF_SUCCED_RETURN_MASK) | \
			(((x & CONF_SUCCED_RETURN_MASK) + 1) & CONF_SUCCED_RETURN_MASK)
#define CONF_IGNOREPLUS(x) \
		x = (x & ~CONF_IGNORE_RETURN_MASK) | \
			(((x & CONF_IGNORE_RETURN_MASK) + (1 << 8) ) & CONF_IGNORE_RETURN_MASK)
#define CONF_FAILEDPLUS(x) \
		x = (x & ~CONF_FAILED_RETURN_MASK) | \
			(((x & CONF_FAILED_RETURN_MASK) + (1 << 16) ) & CONF_FAILED_RETURN_MASK)

#define CHAINNEXT(x) (x)->chain->id
#define MODNAME(x)   (x)->head->name
#define PACKSTART(x) (x)->count++
#define PACKDONE(x)  (x)->count--
#define PACKERROR(x) (x)->count--

void netmodSend(LWPool lw, NetModuleId to,  NetBuf data, NetAttrs meta);
void netmodRecv(LWPool lw, NetBuf *data, NetAttrs *meta);
void netmodRIP(LWPool lw, NetBuf data, NetAttrs meta, char *s);


#endif

