/*!
  \file  mones.cpp
  \brief Code:Monesメイン

  Copyright (c) 2004 Yamami
  All rights reserved.
  License=MIT/X Licnese

  \author  Yamami
  \version $Revision: 1.2 $
  \date   create:2004/08/08 update:$Date: 2004/09/20 15:29:03 $
*/


//ここで、Monesのグローバルオブジェクトをインスタンス化する
#define MONES_GLOBAL_VALUE_DEFINED
#include "MonesGlobal.h"

#include <monapi.h>
#include "AbstractMonic.h"
#include "Ne2000MoNic.h"
#include "MoEther.h"
#include "MonesConfig.h"



using namespace MonAPI;


/*!
    \brief MonaMain
        Code:Monesメイン

    \param List<char*>* pekoe

    \author  Yamami
    \date    create:2004/08/08 update:2004/08/28
*/
int MonaMain(List<char*>* pekoe)
{
    //syscall_get_io  
    //このプロセス動作中は、IOを特権レベル3まで許可する
    syscall_get_io();
    
    // NICのインスタンス化
    // Yamami!! 本来ならばここで、は環境(設定)に応じたNICドライバをロードする。
    // initilize Mona Network
    Ne2000MoNic* insAbstractNic = new Ne2000MoNic();
    insAbstractNic->init();

    //Etherクラスのインスタンス化
    g_MoEther = new MoEther();
    g_MoEther->etherInit(insAbstractNic);

    //ARPクラスのインスタンス化
    g_MoArp = new MoArp();
    g_MoArp->initArp(insAbstractNic);

    //IPクラスのインスタンス化
    g_MoIp = new MoIp();
    g_MoIp->initIp(insAbstractNic);


    // initilize destination list
    //List<dword>* destList = new HList<dword>();
    MessageInfo info;

    // Server start ok
    dword targetID = Message::lookupMainThread("MONITOR.BIN");
    if (targetID == 0xFFFFFFFF)
    {
        printf("Mones:INIT not found\n");
        exit(1);
    }

    // create message
    Message::create(&info, MSG_SERVER_START_OK, 0, 0, 0, NULL);

    // send
    if (Message::send(targetID, &info)) {
        printf("Mones:INIT error\n");
    }

    //ネットワークのIRQマスクEnable
    insAbstractNic->enableNetWork();

    //IRQレシーバとして登録 (IRQは、NICドライバクラスより得る)
    syscall_set_irq_receiver(insAbstractNic->getNicIRQ());


//Yamami デバッグ
//FileOutputStream fos("MONES.LOG", true);
//printf("open=%x\n", fos.open());

//char logStr[1024];    //ログ出力文字列


    /* Message loop */
    //ここでメッセージループ
    for (;;)
    {
        /* receive */
        if (!Message::receive(&info))
        {
            
            switch(info.header)
            {
            case MSG_INTERRUPTED:
                
                //printf("MSG_INTERRUPTED\n");
                
                dword    i;
                
                //パケット受信
                insAbstractNic->frame_input();
                
                //Etherクラスに登録
                i = g_MoEther->setEtherFrame(insAbstractNic->frame_buf ,insAbstractNic->frame_len);
                //イーサネットフレーム受信処理 
                i = g_MoEther->receiveEther();
                
                break;

            //Yamami!! パケット送信処理、未実装
            //case MSG_NET_PACKET_SEND:
                //パケット送信
                //テスト 自己MACアドレスへ出力処理
                // insAbstractNic->frame_output( (byte *)ne_test_pattern, ether_mac_addr, ne_sizeof_test_pattern, 0x0806 );
                //ホストアドレスへ出力処理
                // insAbstractNic->frame_output( (byte *)ne_test_pattern, dest_ether_mac_addr, ne_sizeof_test_pattern, 0x0806 );

                //break;


            default:
                /* igonore this message */
                break;
            }

        }
    }
    return 0;
}

