/*
    Copyright 2000 (c) by David Schweikert,
    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/old/NetModules.c,v $
    Author(s):             
    Affiliation:           ETH Zuerich, TIK
    Version:               $Revision: 2936 $
    Creation Date:         
    Last Date of Change:   $Date: 2007-03-21 15:23:42 +0100 (Mit, 21 Mär 2007) $      by: $Author: baderma $
 
 
    $Log: NetModules.c,v $
    Revision 1.3  2001/01/23 09:43:31  cjeker
    moved to Net/old
 
    Revision 1.2  2000/11/15 10:12:14  ruf
    Repository Reorganisation
 
    Revision 1.1  2000/03/31 17:50:35  gfa
    Merged with /Net from several term projects
 
*/
#include <Topsy.h>
#include <Messages.h>
#include <Syscall.h>
#include <NetDebug.h>
#include <NetModules.h>

static ThreadId netmodMap[NETMODULE_LAST-1];

void netmodInit()
{
  int i = 0;

  for(i=0; i<NETMODULE_LAST-1; i++)
  {
    netmodMap[i]=0;
  }
  netdbgDisplay(NETDEBUG_MODULES, "NetModules initialized.\n");
}

void netmodAdd(NetModuleId m, ThreadId t)
{
  netmodMap[m-1]=t;
  netdbgPrintf(NETDEBUG_MODULES, "NetModules: NetModule %d added (threadId %d).\n",
               m, t);
}

int netmodMsgRecv(NetModMsg *msg)
{
  ThreadId expectedFrom = ANY;
  return (tmMsgRecv(&expectedFrom, ANYMSGTYPE, (Message *) msg, INFINITY) ==
          TM_MSGRECVOK);
}


/******************** SENDUP ********************/

void netmodSendUpThread(ThreadId to, NetBuf buf, NetAttrs attrs)
{
  NetModMsg msg;

  msg.id    = NETMOD_SENDUP;
  msg.buf   = buf;
  msg.attrs = attrs;
  msg.value = 0;

  netdbgPrintf(NETDEBUG_MODULES,
               "netmod: sending up packet to threadId %d (len %d).\n",to,
               NETBUF_LEN(buf));

  if (tmMsgSend(to, (Message *) &msg) != TM_MSGSENDOK)
  {
    netdbgDisplay(NETDEBUG_GENERIC,
                  "*** ERROR: netmodSendUp: tmMsgSend failed. Discarding packet.\n");
    netbufFree(buf);
    NETATTR_FREE(attrs);
    return;
  }
}

void netmodSendUp(NetModuleId to, NetBuf buf, NetAttrs attrs)
{
  ThreadId t;

  if(to<1 || to>(NETMODULE_LAST-1))
  {
    netbufFree(buf);
    NETATTR_FREE(attrs);
    return;
  }

  t=netmodMap[to-1];
  if(!t)
  {
    netdbgPrintf(NETDEBUG_GENERIC,
                 "*** ERROR: netmodule %d not found. Discarding packet.\n", to);
    netbufFree(buf);
    NETATTR_FREE(attrs);
    return;
  }

  netmodSendUpThread(t,buf,attrs);
}

/******************** SENDDOWN ********************/

void netmodSendDownThread(ThreadId to, NetBuf buf, NetAttrs attrs)
{
  NetModMsg msg;

  msg.id    = NETMOD_SENDDOWN;
  msg.buf   = buf;
  msg.attrs = attrs;
  msg.value = 0;

  netdbgPrintf(NETDEBUG_MODULES,
               "netmod: sending down packet to threadId %d (len %d).\n",
               to, to);

  if (tmMsgSend(to, (Message *) &msg) != TM_MSGSENDOK)
  {
    netdbgDisplay(NETDEBUG_GENERIC,
                  "*** ERROR: tmMsgSend failed. Discarding packet.\n");
    netbufFree(buf);
    NETATTR_FREE(attrs);
  }
}

void netmodSendDown(NetModuleId to, NetBuf buf, NetAttrs attrs)
{
  ThreadId t;

  if(to<1 || to>(NETMODULE_LAST-1))
  {
    netbufFree(buf);
    NETATTR_FREE(attrs);
    return;
  }

  t=netmodMap[to-1];
  if(!t)
  {
    netdbgDisplay(NETDEBUG_GENERIC, "*** ERROR: netmodule not found. Discarding packet.\n");
    netbufFree(buf);
    NETATTR_FREE(attrs);
    return;
  }

  netmodSendDownThread(t,buf,attrs);
}

/******************** LISTEN ********************/

void netmodListenThread(ThreadId to, NetAttrs attrs, long value)
{
  NetModMsg msg;

  msg.id    = NETMOD_LISTEN;
  msg.buf   = 0;
  msg.attrs = attrs;
  msg.value = value;

  netdbgPrintf(NETDEBUG_MODULES,
               "netmod: sending listen request to threadId %d.\n",
               to);

  if (tmMsgSend(to, (Message *) &msg) != TM_MSGSENDOK)
  {
    netdbgDisplay(NETDEBUG_GENERIC,
                  "*** ERROR: tmMsgSend failed. Discarding packet.\n");
    NETATTR_FREE(attrs);
  }
}

void netmodListen(NetModuleId to, NetAttrs attrs, long value)
{
  ThreadId t;

  if(to<1 || to>(NETMODULE_LAST-1))
  {
    NETATTR_FREE(attrs);
    return;
  }

  t=netmodMap[to-1];
  if(!t)
  {
    netdbgDisplay(NETDEBUG_GENERIC, "*** ERROR: netmodule not found. Discarding packet.\n");
    NETATTR_FREE(attrs);
    return;
  }

  netmodListenThread(t,attrs,value);
}

/******************** LISTENREPLY ********************/

void netmodListenReplyThread(ThreadId to, NetAttrs attrs, long value)
{
  NetModMsg msg;

  msg.id    = NETMOD_LISTENREPLY;
  msg.buf   = 0;
  msg.attrs = attrs;
  msg.value = value;

  netdbgPrintf(NETDEBUG_MODULES,
               "netmod: sending listen reply to threadId %d.\n",
               to);

  if (tmMsgSend(to, (Message *) &msg) != TM_MSGSENDOK)
  {
    netdbgDisplay(NETDEBUG_GENERIC,
                  "*** ERROR: tmMsgSend failed. Discarding packet.\n");
    NETATTR_FREE(attrs);
  }
}

void netmodListenReply(NetModuleId to, NetAttrs attrs, long value)
{
  ThreadId t;

  if(to<1 || to>(NETMODULE_LAST-1))
  {
    NETATTR_FREE(attrs);
    return;
  }

  t=netmodMap[to-1];
  if(!t)
  {
    netdbgDisplay(NETDEBUG_GENERIC, "*** ERROR: netmodule not found. Discarding packet.\n");
    NETATTR_FREE(attrs);
    return;
  }

  netmodListenReplyThread(t,attrs,value);
}

/******************** CLOSE ********************/

void netmodCloseThread(ThreadId to, NetAttrs attrs, long value)
{
  NetModMsg msg;

  msg.id    = NETMOD_CLOSE;
  msg.buf   = 0;
  msg.attrs = attrs;
  msg.value = value;

  netdbgPrintf(NETDEBUG_MODULES,
               "netmod: sending close request to threadId %d.\n",
               to);

  if (tmMsgSend(to, (Message *) &msg) != TM_MSGSENDOK)
  {
    netdbgDisplay(NETDEBUG_GENERIC,
                  "*** ERROR: tmMsgSend failed. Discarding packet.\n");
    NETATTR_FREE(attrs);
  }
}

void netmodClose(NetModuleId to, NetAttrs attrs, long value)
{
  ThreadId t;

  if(to<1 || to>(NETMODULE_LAST-1))
  {
    NETATTR_FREE(attrs);
    return;
  }

  t=netmodMap[to-1];
  if(!t)
  {
    netdbgDisplay(NETDEBUG_GENERIC, "*** ERROR: netmodule not found. Discarding packet.\n");
    NETATTR_FREE(attrs);
    return;
  }

  netmodCloseThread(t,attrs,value);
}
