Working on UDP, removed debug from some code, fixed ARP setting hwtype to 0x100 ...
authorJohn Hodge <[email protected]>
Thu, 25 Feb 2010 11:44:14 +0000 (19:44 +0800)
committerJohn Hodge <[email protected]>
Thu, 25 Feb 2010 11:44:14 +0000 (19:44 +0800)
- Other Misc changes

18 files changed:
Kernel/Makefile.BuildNum
Kernel/arch/x86/irq.c
Kernel/debug.c
Kernel/drv/kb.c
Kernel/heap.c
Kernel/include/tpl_drv_common.h
Modules/IPStack/arp.c
Modules/IPStack/tcp.c
Modules/IPStack/tcp.h
Modules/IPStack/udp.c
Modules/IPStack/udp.h
Modules/Storage/ATA/main.c
Usermode/Applications/axwin2_src/WM/main.c
Usermode/Applications/axwin2_src/WM/messages.c
Usermode/Applications/ifconfig_src/main.c
Usermode/Libraries/Makefile.cfg
Usermode/include/acess/sys.h
Usermode/include/axwin/messages.h

index da45617..e082886 100644 (file)
@@ -1 +1 @@
-BUILD_NUM = 1438
+BUILD_NUM = 1447
index c9fa726..9e0647f 100644 (file)
@@ -21,18 +21,18 @@ tIRQ_Callback       gIRQ_Handlers[16][MAX_CALLBACKS_PER_IRQ];
 void IRQ_Handler(tRegs *Regs)
 {
         int    i;
-       
+
        Regs->int_num -= 0xF0;  // Adjust
-       
+
        //Log("IRQ_Handler: (Regs={int_num:%i})", Regs->int_num);
-       
+
        for( i = 0; i < MAX_CALLBACKS_PER_IRQ; i++ )
        {
                //Log(" IRQ_Handler: Call %p", gIRQ_Handlers[Regs->int_num][i]);
                if( gIRQ_Handlers[Regs->int_num][i] )
                        gIRQ_Handlers[Regs->int_num][i](Regs->int_num);
        }
-       
+
        //Log(" IRQ_Handler: Resetting");
        if(Regs->int_num >= 8)
                outb(0xA0, 0x20);       // ACK IRQ (Secondary PIC)
@@ -49,10 +49,12 @@ int IRQ_AddHandler( int Num, void (*Callback)(int) )
        for( i = 0; i < MAX_CALLBACKS_PER_IRQ; i++ )
        {
                if( gIRQ_Handlers[Num][i] == NULL ) {
+                       Log("IRQ_AddHandler: Added IRQ%i Cb#%i %p", Num, i, Callback);
                        gIRQ_Handlers[Num][i] = Callback;
                        return 1;
                }
        }
-       
+
+       Warning("IRQ_AddHandler - No free callbacks on IRQ%i", Num);
        return 0;
 }
index 8404fc1..857ab59 100644 (file)
@@ -56,22 +56,22 @@ static void E9(char ch)
 {
        if(giDebug_KTerm != -1)
                VFS_Write(giDebug_KTerm, 1, &ch);
-       
+
        #if DEBUG_TO_SERIAL
        if(!gbDebug_SerialSetup) {
-               outb(SERIAL_PORT + 1, 0x00);    // Disable all interrupts
-               outb(SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
-               outb(SERIAL_PORT + 0, 0x03);    // Set divisor to 3 (lo byte) 38400 baud
-               outb(SERIAL_PORT + 1, 0x00);    //                  (hi byte)
-               outb(SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
-               outb(SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
-               outb(SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
+               outb(SERIAL_PORT + 1, 0x00);    // Disable all interrupts
+               outb(SERIAL_PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
+               outb(SERIAL_PORT + 0, 0x03);    // Set divisor to 3 (lo byte) 38400 baud
+               outb(SERIAL_PORT + 1, 0x00);    //                  (hi byte)
+               outb(SERIAL_PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
+               outb(SERIAL_PORT + 2, 0xC7);    // Enable FIFO with 14-byte threshold and clear it
+               outb(SERIAL_PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
                gbDebug_SerialSetup = 1;
        }
        while( (inb(SERIAL_PORT + 5) & 0x20) == 0 );
        outb(SERIAL_PORT, ch);
        #endif
-       
+
        #if DEBUG_TO_E9
        __asm__ __volatile__ ( "outb %%al, $0xe9" :: "a"(((Uint8)ch)) );
        #endif
@@ -90,7 +90,7 @@ void E9_Fmt(const char *format, va_list *args)
        char    *p = NULL;
         int    isLongLong = 0;
        Uint64  arg;
-       
+
        while((c = *format++) != 0)
        {
                // Non control character
@@ -98,15 +98,15 @@ void E9_Fmt(const char *format, va_list *args)
                        E9(c);
                        continue;
                }
-               
+
                c = *format++;
-               
+
                // Literal %
                if(c == '%') {
                        E9('%');
                        continue;
                }
-               
+
                // Pointer
                if(c == 'p') {
                        Uint    ptr = va_arg(*args, Uint);
@@ -115,17 +115,17 @@ void E9_Fmt(const char *format, va_list *args)
                        itoa(p, ptr, 16, BITS/4, '0');
                        goto printString;
                }
-               
+
                // Get Argument
                arg = va_arg(*args, Uint);
-               
+
                // Padding
                if(c == '0') {
                        pad = '0';
                        c = *format++;
                } else
                        pad = ' ';
-               
+
                // Minimum length
                minSize = 1;
                if('1' <= c && c <= '9')
@@ -138,7 +138,7 @@ void E9_Fmt(const char *format, va_list *args)
                                c = *format++;
                        }
                }
-               
+
                // Long (default)
                isLongLong = 0;
                if(c == 'l') {
@@ -151,7 +151,7 @@ void E9_Fmt(const char *format, va_list *args)
                                isLongLong = 1;
                        }
                }
-               
+
                p = tmpBuf;
                switch (c) {
                case 'd':
@@ -179,14 +179,14 @@ void E9_Fmt(const char *format, va_list *args)
                        if(arg) E9_Str("True");
                        else    E9_Str("False");
                        break;
-               
+
                case 's':
                        p = (char*)(Uint)arg;
                printString:
                        if(!p)          p = "(null)";
                        while(*p)       E9(*p++);
                        break;
-               
+
                // Single Character / Array
                case 'c':
                        if(minSize == 1) {
@@ -197,7 +197,7 @@ void E9_Fmt(const char *format, va_list *args)
                        if(!p)  goto printString;
                        while(minSize--)        E9(*p++);
                        break;
-               
+
                default:        E9(arg);        break;
                }
     }
@@ -218,11 +218,11 @@ void LogV(char *Fmt, va_list Args)
 void LogF(char *Fmt, ...)
 {
        va_list args;
-       
+
        va_start(args, Fmt);
-       
+
        E9_Fmt(Fmt, &args);
-       
+
        va_end(args);
 }
 /**
@@ -231,7 +231,7 @@ void LogF(char *Fmt, ...)
 void Log(char *Fmt, ...)
 {
        va_list args;
-       
+
        E9_Str("Log: ");
        va_start(args, Fmt);
        E9_Fmt(Fmt, &args);
@@ -255,9 +255,9 @@ void Panic(char *Fmt, ...)
        E9_Fmt(Fmt, &args);
        va_end(args);
        E9('\n');
-       
+
        Threads_Dump();
-       
+
        __asm__ __volatile__ ("xchg %bx, %bx");
        __asm__ __volatile__ ("cli;\n\thlt");
        for(;;) __asm__ __volatile__ ("hlt");
@@ -276,13 +276,13 @@ void Debug_Enter(char *FuncName, char *ArgTypes, ...)
        va_list args;
         int    i = gDebug_Level ++;
         int    pos;
-       
+
        va_start(args, ArgTypes);
-       
+
        while(i--)      E9(' ');
-       
+
        E9_Str(FuncName);       E9_Str(": (");
-       
+
        while(*ArgTypes)
        {
                pos = strpos(ArgTypes, ' ');
@@ -307,11 +307,11 @@ void Debug_Enter(char *FuncName, char *ArgTypes, ...)
                if(pos != -1) {
                        E9(',');        E9(' ');
                }
-               
+
                if(pos == -1)   break;
                ArgTypes = &ArgTypes[pos+1];
        }
-       
+
        va_end(args);
        E9(')');        E9('\n');
 }
@@ -320,14 +320,14 @@ void Debug_Log(char *FuncName, char *Fmt, ...)
 {
        va_list args;
         int    i = gDebug_Level;
-       
+
        va_start(args, Fmt);
-       
+
        while(i--)      E9(' ');
-       
+
        E9_Str(FuncName);       E9_Str(": ");
        E9_Fmt(Fmt, &args);
-       
+
        va_end(args);
        E9('\n');
 }
@@ -336,24 +336,24 @@ void Debug_Leave(char *FuncName, char RetType, ...)
 {
        va_list args;
         int    i = --gDebug_Level;
-       
+
        va_start(args, RetType);
-       
+
        if( i == -1 ) {
                gDebug_Level = 0;
                i = 0;
        }
        // Indenting
        while(i--)      E9(' ');
-       
+
        E9_Str(FuncName);       E9_Str(": RETURN");
-       
+
        // No Return
        if(RetType == '-') {
                E9('\n');
                return;
        }
-       
+
        E9(' ');
        switch(RetType)
        {
@@ -367,7 +367,7 @@ void Debug_Leave(char *FuncName, char RetType, ...)
        case 'X':       E9_Fmt("0x%llx", &args);        break;
        }
        E9('\n');
-       
+
        va_end(args);
 }
 
@@ -377,7 +377,7 @@ void Debug_HexDump(char *Header, void *Data, Uint Length)
        Uint    pos = 0;
        E9_Str(Header);
        LogF(" (Hexdump of %p)\n", Data);
-       
+
        while(Length >= 16)
        {
                Log("%04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
@@ -389,7 +389,7 @@ void Debug_HexDump(char *Header, void *Data, Uint Length)
                cdat += 16;
                pos += 16;
        }
-       
+
        LogF("Log: %04x: ", pos);
        while(Length)
        {
index b5428b5..a546153 100644 (file)
@@ -58,6 +58,7 @@ int KB_Install(char **Arguments)
 {
        IRQ_AddHandler(1, KB_IRQHandler);
        DevFS_AddDevice( &gKB_DevInfo );
+       //Log("KB_Install: Installed");
        return 1;
 }
 
@@ -72,17 +73,19 @@ void KB_IRQHandler()
        // int  keyNum;
 
        //if( inportb(0x64) & 0x20 )    return;
-       
+
        scancode = inb(0x60); // Read from the keyboard's data buffer
 
+       Log("KB_IRQHandler: scancode = 0x%02x", scancode);
+
        // Ignore ACKs
        if(scancode == 0xFA) {
                // Oh man! This is anachic (I'm leaving it here to represent the
-               // mess that acess once was
+               // mess that Acess once was)
                //kb_lastChar = KB_ACK;
                return;
        }
-       
+
        // Layer +1
        if(scancode == 0xE0) {
                giKB_KeyLayer = 1;
@@ -93,7 +96,7 @@ void KB_IRQHandler()
                giKB_KeyLayer = 2;
                return;
        }
-       
+
        #if KB_ALT_SCANCODES
        if(scancode == 0xF0)
        {
@@ -107,32 +110,32 @@ void KB_IRQHandler()
                gbKB_KeyUp = 1;
        }
        #endif
-       
+
        // Translate
        ch = gpKB_Map[giKB_KeyLayer][scancode];
        //keyNum = giKB_KeyLayer * 256 + scancode;
        // Check for unknown key
        if(!ch && !gbKB_KeyUp)
                Warning("UNK %i %x", giKB_KeyLayer, scancode);
-       
+
        // Key Up?
        if (gbKB_KeyUp)
        {
                gbKB_KeyUp = 0;
                gbaKB_States[giKB_KeyLayer][scancode] = 0;      // Unset key state flag
-               
+
                #if USE_KERNEL_MAGIC
                if(ch == KEY_LCTRL)     gbKB_MagicState &= ~1;
                if(ch == KEY_LALT)      gbKB_MagicState &= ~2;
                #endif
-               
+
                if(ch == KEY_LSHIFT)    gbKB_ShiftState &= ~1;
                if(ch == KEY_RSHIFT)    gbKB_ShiftState &= ~2;
-               
+
                // Call callback
                if(ch != 0 && gKB_Callback)
                        gKB_Callback( ch & 0x80000000 );
-               
+
                // Reset Layer
                giKB_KeyLayer = 0;
                return;
@@ -143,19 +146,19 @@ void KB_IRQHandler()
        // Set shift key bits
        if(ch == KEY_LSHIFT)    gbKB_ShiftState |= 1;
        if(ch == KEY_RSHIFT)    gbKB_ShiftState |= 2;
-       
+
        // Check for Caps Lock
        if(ch == KEY_CAPSLOCK) {
                gbKB_CapsState = !gbKB_CapsState;
                KB_UpdateLEDs();
        }
-       
+
        // Reset Layer
        giKB_KeyLayer = 0;
 
        // Ignore Non-Printable Characters
        if(ch == 0)             return;
-       
+
        // --- Check for Kernel Magic Combos
        #if USE_KERNEL_MAGIC
        if(ch == KEY_LCTRL)     gbKB_MagicState |= 1;
@@ -169,7 +172,7 @@ void KB_IRQHandler()
                }
        }
        #endif
-       
+
        // Is shift pressed
        // - Darn ugly hacks !(!x) means (bool)x
        if( !(!gbKB_ShiftState) ^ gbKB_CapsState)
@@ -204,7 +207,7 @@ void KB_IRQHandler()
                        break;
                }
        }
-       
+
        if(gKB_Callback && ch != 0)     gKB_Callback(ch);
 }
 
@@ -215,12 +218,12 @@ void KB_IRQHandler()
 void KB_UpdateLEDs()
 {
        Uint8   leds;
-       
+
        leds = (gbKB_CapsState ? 4 : 0);
-       
+
        while( inb(0x64) & 2 ); // Wait for bit 2 to unset
        outb(0x60, 0xED);       // Send update command
-       
+
        while( inb(0x64) & 2 ); // Wait for bit 2 to unset
        outb(0x60, leds);
 }
@@ -237,7 +240,7 @@ int KB_IOCtl(tVFS_Node *Node, int Id, void *Data)
        case DRV_IOCTL_IDENT:   memcpy(Data, "KB\0\0", 4);      return 1;
        case DRV_IOCTL_VERSION: return 0x100;
        case DRV_IOCTL_LOOKUP:  return 0;
-       
+
        // Sets the Keyboard Callback
        case KB_IOCTL_SETCALLBACK:
                // Sanity Check
@@ -247,7 +250,7 @@ int KB_IOCtl(tVFS_Node *Node, int Id, void *Data)
                // Set Callback
                gKB_Callback = Data;
                return 1;
-       
+
        default:
                return 0;
        }
index f42d59f..61f7881 100644 (file)
@@ -30,7 +30,7 @@ void  free(void *Ptr);
 void   Heap_Dump();
 
 // === GLOBALS ===
- int   giHeapSpinlock;
+ int   glHeap;
 void   *gHeapStart;
 void   *gHeapEnd;
 
@@ -140,7 +140,7 @@ void *malloc(size_t Bytes)
        Bytes = (Bytes + sizeof(tHeapHead) + sizeof(tHeapFoot) + BLOCK_SIZE-1) & ~(BLOCK_SIZE-1);
        
        // Lock Heap
-       LOCK(&giHeapSpinlock);
+       LOCK(&glHeap);
        
        // Traverse Heap
        for( head = gHeapStart;
@@ -154,6 +154,7 @@ void *malloc(size_t Bytes)
                        Warning("Size of heap address %p is invalid not aligned (0x%x)", head, head->Size);
                        Heap_Dump();
                        #endif
+                       RELEASE(&glHeap);
                        return NULL;
                }
                
@@ -165,7 +166,7 @@ void *malloc(size_t Bytes)
                        Warning("Magic of heap address %p is invalid (0x%x)", head, head->Magic);
                        Heap_Dump();
                        #endif
-                       RELEASE(&giHeapSpinlock);       // Release spinlock
+                       RELEASE(&glHeap);       // Release spinlock
                        return NULL;
                }
                
@@ -175,7 +176,7 @@ void *malloc(size_t Bytes)
                // Perfect fit
                if(head->Size == Bytes) {
                        head->Magic = MAGIC_USED;
-                       RELEASE(&giHeapSpinlock);       // Release spinlock
+                       RELEASE(&glHeap);       // Release spinlock
                        #if DEBUG_TRACE
                        LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0));
                        #endif
@@ -202,12 +203,12 @@ void *malloc(size_t Bytes)
                best = Heap_Extend( Bytes );
                // Check for errors
                if(!best) {
-                       RELEASE(&giHeapSpinlock);       // Release spinlock
+                       RELEASE(&glHeap);       // Release spinlock
                        return NULL;
                }
                // Check size
                if(best->Size == Bytes) {
-                       RELEASE(&giHeapSpinlock);       // Release spinlock
+                       RELEASE(&glHeap);       // Release spinlock
                        #if DEBUG_TRACE
                        LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0));
                        #endif
@@ -228,7 +229,7 @@ void *malloc(size_t Bytes)
        best->Size = Bytes;             // Update size in old header
        best->Magic = MAGIC_USED;       // Mark block as used
        
-       RELEASE(&giHeapSpinlock);       // Release spinlock
+       RELEASE(&glHeap);       // Release spinlock
        #if DEBUG_TRACE
        LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0));
        #endif
@@ -285,7 +286,7 @@ void free(void *Ptr)
        }
        
        // Lock
-       LOCK( &giHeapSpinlock );
+       LOCK( &glHeap );
        
        // Mark as free
        head->Magic = MAGIC_FREE;
@@ -293,7 +294,7 @@ void free(void *Ptr)
        Heap_Merge( head );
        
        // Release
-       RELEASE( &giHeapSpinlock );
+       RELEASE( &glHeap );
 }
 
 /**
index 31edb9c..f281c0e 100644 (file)
@@ -82,6 +82,19 @@ enum eTplDrv_IOCtl {
 //! These are the official lookup names of the core calls
 #define        DRV_IOCTLNAMES  "type", "ident", "version", "lookup"
 
+#define BASE_IOCTLS(_type, _ident, _version, _ioctls)  \
+       case DRV_IOCTL_TYPE:    LEAVE('i', (_type));    return (_type);\
+       case DRV_IOCTL_IDENT: {\
+               int tmp = ModUtil_SetIdent(Data, (_ident));\
+               LEAVE('i', tmp);        return tmp;\
+               }\
+       case DRV_IOCTL_VERSION: LEAVE('x', (_version)); return (_version);\
+       case DRV_IOCTL_LOOKUP:{\
+               int tmp = ModUtil_LookupString( (char**)(_ioctls), (char*)Data );\
+               LEAVE('i', tmp);\
+               return tmp;\
+               }
+
 /**
  * \enum eTplDrv_Type
  * \brief Driver Types returned by DRV_IOCTL_TYPE
index 3f91939..2b246cd 100644 (file)
@@ -16,7 +16,7 @@ extern tInterface     *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broad
 
 // === PROTOTYPES ===
  int   ARP_Initialise();
- int   ARP_int_Resolve4(tInterface *Interface, tIPv4 Address);
+tMacAddr       ARP_Resolve4(tInterface *Interface, tIPv4 Address);
 void   ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer);
 
 // === GLOBALS ===
@@ -64,6 +64,7 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address)
 {
         int    lastID;
         int    i;
+       struct sArpRequest4     req;
        
        ENTER("pInterface xAddress", Interface, Address);
        
@@ -87,37 +88,12 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address)
        RELEASE( &glARP_Cache4 );
        
        lastID = giARP_LastUpdateID;
-       ARP_int_Resolve4(Interface, Address);
-       for(;;)
-       {
-               while(lastID == giARP_LastUpdateID)     Threads_Yield();
-               lastID = giARP_LastUpdateID;
-               
-               LOCK( &glARP_Cache4 );
-               for( i = 0; i < giARP_Cache4Space; i++ )
-               {
-                       if(gaARP_Cache4[i].IP.L != Address.L)   continue;
-                       
-                       RELEASE( &glARP_Cache4 );
-                       return gaARP_Cache4[i].MAC;
-               }
-               RELEASE( &glARP_Cache4 );
-       }
-}
-
-/**
- * \fn int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address)
- * \brief Request the network to resolve an IPv4 Address
- * \return Boolean Success
- */
-int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address)
-{
-       struct sArpRequest4     req;
        
+       // Create request
        Log("[ARP4 ] Asking for address %i.%i.%i.%i",
                Address.B[0], Address.B[1], Address.B[2], Address.B[3]
                );
-       req.HWType = htons(0x100);      // Ethernet
+       req.HWType = htons(1);  // Ethernet
        req.Type   = htons(0x0800);
        req.HWSize = 6;
        req.SWSize = 4;
@@ -127,9 +103,25 @@ int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address)
        req.DestMac = cMAC_BROADCAST;
        req.DestIP = Address;
        
+       // Send Request
        Link_SendPacket(Interface->Adapter, 0x0806, req.DestMac, sizeof(struct sArpRequest4), &req);
        
-       return 0;
+       // Wait for a reply
+       for(;;)
+       {
+               while(lastID == giARP_LastUpdateID)     Threads_Yield();
+               lastID = giARP_LastUpdateID;
+               
+               LOCK( &glARP_Cache4 );
+               for( i = 0; i < giARP_Cache4Space; i++ )
+               {
+                       if(gaARP_Cache4[i].IP.L != Address.L)   continue;
+                       
+                       RELEASE( &glARP_Cache4 );
+                       return gaARP_Cache4[i].MAC;
+               }
+               RELEASE( &glARP_Cache4 );
+       }
 }
 
 /**
index dd94b92..9225ffa 100644 (file)
@@ -12,6 +12,7 @@
 // === PROTOTYPES ===
 void   TCP_Initialise();
 void   TCP_StartConnection(tTCPConnection *Conn);
+void   TCP_SendPacket( tTCPConnection *Conn, size_t Length, tTCPHeader *Data );
 void   TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer);
 void   TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Header);
 Uint16 TCP_GetUnusedPort();
@@ -61,16 +62,16 @@ void TCP_Initialise()
 void TCP_StartConnection(tTCPConnection *Conn)
 {
        tTCPHeader      hdr;
-       
-       hdr->SourcePort = Conn->LocalPort;
-       hdr->DestPort = Conn->RemotePort;
+
+       hdr.SourcePort = Conn->LocalPort;
+       hdr.DestPort = Conn->RemotePort;
        Conn->NextSequenceSend = rand();
-       hdr->SequenceNumber = Conn->NextSequenceSend;
-       hdr->DataOffset = (sizeof(tTCPHeader)+3)/4;
-       hdr->Flags = TCP_FLAG_SYN;
-       hdr->WindowSize = 0;    // TODO
-       hdr->Checksum = 0;      // TODO
-       hdr->UrgentPointer = 0;
+       hdr.SequenceNumber = Conn->NextSequenceSend;
+       hdr.DataOffset = (sizeof(tTCPHeader)+3)/4;
+       hdr.Flags = TCP_FLAG_SYN;
+       hdr.WindowSize = 0;     // TODO
+       hdr.Checksum = 0;       // TODO
+       hdr.UrgentPointer = 0;
        // SEND PACKET
        TCP_SendPacket( Conn, sizeof(tTCPHeader), &hdr );
        return ;
@@ -86,19 +87,19 @@ void TCP_SendPacket( tTCPConnection *Conn, size_t Length, tTCPHeader *Data )
 {
        size_t  buflen;
        Uint32  *buf;
-       switch( Conn->Interface.Type )
+       switch( Conn->Interface->Type )
        {
-       case 4:
+       case 4: // Append IPv4 Pseudo Header
                buflen = 4 + 4 + 4 + ((Length+1)&1);
                buf = malloc( buflen );
-               buf[0] = Conn->Interface.IP4.Address.L;
+               buf[0] = Conn->Interface->IP4.Address.L;
                buf[1] = Conn->RemoteIP.v4.L;
                buf[2] = (htons(Length)<<16) | (6<<8) | 0;
                Data->Checksum = 0;
-               memcpy( &buf[3], Data, buflen );
+               memcpy( &buf[3], Data, Length );
                Data->Checksum = IPv4_Checksum( buf, buflen );
                free(buf);
-               IPv4_SendPacket(Conn->Interface, Conn->RemoteIP.v4, IP4PROT_TCP, 0, sizeof(tTCPHeader), &hdr);
+               IPv4_SendPacket(Conn->Interface, Conn->RemoteIP.v4, IP4PROT_TCP, 0, buflen, buf);
                break;
        }
 }
@@ -112,7 +113,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
        tTCPHeader      *hdr = Buffer;
        tTCPListener    *srv;
        tTCPConnection  *conn;
-       
+
        Log("[TCP  ] sizeof(tTCPHeader) = %i", sizeof(tTCPHeader));
        Log("[TCP  ] DestPort = %i", ntohs(hdr->DestPort));
        Log("[TCP  ] DestPort = %i", ntohs(hdr->DestPort));
@@ -132,7 +133,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
        Log("[TCP  ] WindowSize = %i", htons(hdr->WindowSize));
        Log("[TCP  ] Checksum = 0x%x", htons(hdr->Checksum));
        Log("[TCP  ] UrgentPointer = 0x%x", htons(hdr->UrgentPointer));
-       
+
        // Check Servers
        {
                for( srv = gTCP_Listeners; srv; srv = srv->Next )
@@ -143,53 +144,53 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
                        if(srv->Interface && srv->Interface != Interface)       continue;
                        // Check the destination port
                        if(srv->Port != hdr->DestPort)  continue;
-                       
+
                        // Is this in an established connection?
                        for( conn = srv->Connections; conn; conn = conn->Next )
                        {
                                // Check that it is coming in on the same interface
                                if(conn->Interface != Interface)        continue;
-                               
+
                                // Check Source Port
                                if(conn->RemotePort != hdr->SourcePort) continue;
-                               
+
                                // Check Source IP
                                if(conn->Interface->Type == 6 && !IP6_EQU(conn->RemoteIP.v6, *(tIPv6*)Address))
                                        continue;
                                if(conn->Interface->Type == 4 && !IP4_EQU(conn->RemoteIP.v4, *(tIPv4*)Address))
                                        continue;
-                               
+
                                // We have a response!
-                               TCP_INT_HandleConnectionPacket(conn, hdr)
-                               
+                               TCP_INT_HandleConnectionPacket(conn, hdr);
+
                                return;
                        }
-                       
+
                        // Open a new connection (well, check that it's a SYN)
                        //TODO
-                       
+
                        break;
                }
        }
-       
-       
+
+
        // Check Open Connections
        {
                for( conn = gTCP_OutbountCons; conn; conn = conn->Next )
                {
                        // Check that it is coming in on the same interface
                        if(conn->Interface != Interface)        continue;
-                       
+
                        // Check Source Port
                        if(conn->RemotePort != hdr->SourcePort) continue;
-                       
+
                        // Check Source IP
                        if(conn->Interface->Type == 6 && !IP6_EQU(conn->RemoteIP.v6, *(tIPv6*)Address))
                                continue;
                        if(conn->Interface->Type == 4 && !IP4_EQU(conn->RemoteIP.v4, *(tIPv4*)Address))
                                continue;
-                       
-                       TCP_INT_HandleConnectionPacket(conn, hdr)
+
+                       TCP_INT_HandleConnectionPacket(conn, hdr);
                }
        }
 }
@@ -199,7 +200,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
  */
 void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Header)
 {
-       
+
 }
 
 /**
@@ -209,7 +210,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
 Uint16 TCP_GetUnusedPort()
 {
        Uint16  ret;
-       
+
        // Get Next outbound port
        ret = giTCP_NextOutPort++;
        while( gaTCP_PortBitmap[ret/32] & (1 << (ret%32)) )
@@ -220,10 +221,10 @@ Uint16 TCP_GetUnusedPort()
                        ret = giTCP_NextOutPort = TCP_MIN_DYNPORT;
                }
        }
-       
+
        // Mark the new port as used
        gaTCP_PortBitmap[ret/32] |= 1 << (ret%32);
-       
+
        return ret;
 }
 
@@ -236,10 +237,10 @@ int TCP_AllocatePort(Uint16 Port)
        // Check if the port has already been allocated
        if( gaTCP_PortBitmap[Port/32] & (1 << (Port%32)) )
                return 0;
-       
+
        // Allocate
        gaTCP_PortBitmap[Port/32] |= 1 << (Port%32);
-       
+
        return 1;
 }
 
@@ -252,10 +253,10 @@ int TCP_DeallocatePort(Uint16 Port)
        // Check if the port has already been allocated
        if( !(gaTCP_PortBitmap[Port/32] & (1 << (Port%32))) )
                return 0;
-       
+
        // Allocate
        gaTCP_PortBitmap[Port/32] &= ~(1 << (Port%32));
-       
+
        return 1;
 }
 
@@ -263,7 +264,7 @@ int TCP_DeallocatePort(Uint16 Port)
 tVFS_Node *TCP_Server_Init(tInterface *Interface)
 {
        tTCPListener    *srv = malloc( sizeof(tTCPListener) );
-       
+
        srv->Interface = Interface;
        srv->Port = 0;
        srv->NextID = 0;
@@ -276,12 +277,12 @@ tVFS_Node *TCP_Server_Init(tInterface *Interface)
        srv->Node.FindDir = TCP_Server_FindDir;
        srv->Node.IOCtl = TCP_Server_IOCtl;
        srv->Node.Close = TCP_Server_Close;
-       
+
        LOCK(&glTCP_Listeners);
        srv->Next = gTCP_Listeners;
        gTCP_Listeners = srv;
        RELEASE(&glTCP_Listeners);
-       
+
        return &srv->Node;
 }
 
@@ -296,14 +297,14 @@ char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos)
        tTCPListener    *srv = Node->ImplPtr;
        tTCPConnection  *conn;
        char    *ret;
-       
+
        while( srv->NewConnections == NULL )    Threads_Yield();
-       
+
        conn = srv->NewConnections;
        srv->NewConnections = conn->Next;
-       
+
        ret = malloc(9);
-       itoa(ret, conn->ImplInt, 16, '0', 8);
+       itoa(ret, Node->ImplInt, 16, '0', 8);
        return ret;
 }
 
@@ -320,27 +321,27 @@ tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, char *Name)
 int TCP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data)
 {
        tTCPListener    *srv = Node->ImplPtr;
-       
+
        switch(ID)
        {
        case 4: // Get/Set Port
                if(!Data)       // Get Port
                        return srv->Port;
-               
+
                if(srv->Port)   // Wait, you can't CHANGE the port
                        return -1;
-               
+
                if(!CheckMem(Data, sizeof(Uint16)))     // Sanity check
                        return -1;
-               
+
                // Permissions check
                if(Threads_GetUID() != 0
                && *(Uint16*)Data != 0
                && *(Uint16*)Data < 1024)
                        return -1;
-               
+
                // TODO: Check if a port is in use
-               
+
                // Set Port
                srv->Port = *(Uint16*)Data;
                if(srv->Port == 0)      // Allocate a random port
@@ -361,13 +362,13 @@ void TCP_Server_Close(tVFS_Node *Node)
 tVFS_Node *TCP_Client_Init(tInterface *Interface)
 {
        tTCPConnection  *conn = malloc( sizeof(tTCPConnection) );
-       
+
        conn->State = TCP_ST_CLOSED;
        conn->Interface = Interface;
        conn->LocalPort = 0;
        conn->RemotePort = 0;
        memset( &conn->RemoteIP, 0, sizeof(conn->RemoteIP) );
-       
+
        conn->Node.ImplPtr = conn;
        conn->Node.NumACLs = 1;
        conn->Node.ACLs = &gVFS_ACL_EveryoneRW;
@@ -375,12 +376,12 @@ tVFS_Node *TCP_Client_Init(tInterface *Interface)
        conn->Node.Write = TCP_Client_Write;
        conn->Node.IOCtl = TCP_Client_IOCtl;
        conn->Node.Close = TCP_Client_Close;
-       
+
        LOCK(&glTCP_OutbountCons);
        conn->Next = gTCP_OutbountCons;
        gTCP_OutbountCons = conn;
        RELEASE(&glTCP_OutbountCons);
-       
+
        return &conn->Node;
 }
 
@@ -394,10 +395,13 @@ Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buf
        return 0;
 }
 
+/**
+ * \brief Control a client socket
+ */
 int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data)
 {
        tTCPConnection  *conn = Node->ImplPtr;
-       
+
        switch(ID)
        {
        case 4: // Get/Set local port
@@ -407,20 +411,20 @@ int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data)
                        return -1;
                if(!CheckMem(Data, sizeof(Uint16)))
                        return -1;
-               
+
                if(Threads_GetUID() != 0 && *(Uint16*)Data < 1024)
                        return -1;
-               
+
                conn->LocalPort = *(Uint16*)Data;
                return 0;
-       
+
        case 5: // Get/Set remote port
                if(!Data)       return conn->RemotePort;
                if(conn->State != TCP_ST_CLOSED)        return -1;
                if(!CheckMem(Data, sizeof(Uint16)))     return -1;
                conn->RemotePort = *(Uint16*)Data;
                return 0;
-       
+
        case 6: // Set Remote IP
                if( conn->State != TCP_ST_CLOSED )
                        return -1;
@@ -435,17 +439,17 @@ int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data)
                        conn->RemoteIP.v6 = *(tIPv6*)Data;
                }
                return 0;
-       
+
        case 7: // Connect
                if(conn->LocalPort == -1)
                        conn->LocalPort = TCP_GetUnusedPort();
                if(conn->RemotePort == -1)
                        return 0;
-               
+
                TCP_StartConnection(conn);
                return 1;
        }
-       
+
        return 0;
 }
 
index ed517db..fd04f7b 100644 (file)
@@ -68,7 +68,7 @@ struct sTCPListener
         int    NextID;         //!< Name of the next connection
        tSpinlock       lConnections;   //!< Spinlock for connections
        tTCPConnection  *Connections;   //!< Connections (linked list)
-       volatile tTCPConnection *NewConnections;
+        tTCPConnection *volatile NewConnections;
 };
 
 struct sTCPConnection
index 194c62b..f014c55 100644 (file)
@@ -3,19 +3,38 @@
  * - UDP Handling
  */
 #include "ipstack.h"
+#include <tpl_drv_common.h>
 #include "udp.h"
 
+#define UDP_ALLOC_BASE 0xC000
+
 // === PROTOTYPES ===
 void   UDP_Initialise();
 void   UDP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer);
-// --- Channel
+// --- Listening Server
+tVFS_Node      *UDP_Server_Init(tInterface *Interface);
+char   *UDP_Server_ReadDir(tVFS_Node *Node, int ID);
+tVFS_Node      UDP_Server_FindDir(tVFS_Node *Node, char *Name);
+ int   UDP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data);
+void   UDP_Server_Close(tVFS_Node *Node);
+// --- Client Channels
 tVFS_Node      *UDP_Channel_Init(tInterface *Interface);
 Uint64 UDP_Channel_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
 Uint64 UDP_Channel_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
  int   UDP_Channel_IOCtl(tVFS_Node *Node, int ID, void *Data);
 void   UDP_Channel_Close(tVFS_Node *Node);
+// --- Helpers
+Uint16 UDP_int_AllocatePort();
+ int   UDP_int_MarkPortAsUsed(Uint16 Port);
+void   UDP_int_FreePort(Uint16 Port);
 
 // === GLOBALS ===
+tSpinlock      glUDP_Channels;
+tUDPChannel    *gpUDP_Channels;
+tSpinlock      glUDP_Ports;
+Uint32 gUDP_Ports[0x10000/32];
+//tSocketFile  gUDP_ServerFile = {NULL, "udps", UDP_Server_Init};
+tSocketFile    gUDP_ClientFile = {NULL, "udpc", UDP_Channel_Init};
 
 // === CODE ===
 /**
@@ -24,6 +43,7 @@ void  UDP_Channel_Close(tVFS_Node *Node);
  */
 void UDP_Initialise()
 {
+       IPStack_AddFile(&gUDP_ClientFile);
        IPv4_RegisterCallback(IP4PROT_UDP, UDP_GetPacket);
 }
 
@@ -34,9 +54,318 @@ void UDP_Initialise()
 void UDP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer)
 {
        tUDPHeader      *hdr = Buffer;
+       tUDPChannel     *chan;
+       tUDPPacket      *pack;
+        int    len;
        
        Log("[UDP  ] hdr->SourcePort = %i", ntohs(hdr->SourcePort));
        Log("[UDP  ] hdr->DestPort = %i", ntohs(hdr->DestPort));
        Log("[UDP  ] hdr->Length = %i", ntohs(hdr->Length));
        Log("[UDP  ] hdr->Checksum = 0x%x", ntohs(hdr->Checksum));
+       
+       // Check registered connections
+       LOCK(&glUDP_Channels);
+       for(chan = gpUDP_Channels;
+               chan;
+               chan = chan->Next)
+       {
+               if(chan->Interface != Interface)        continue;
+               if(chan->LocalPort != ntohs(hdr->DestPort))     continue;
+               if(chan->RemotePort != ntohs(hdr->SourcePort))  continue;
+               
+               if(Interface->Type == 4) {
+                       if(IP4_EQU(chan->RemoteAddr.v4, *(tIPv4*)Address))      continue;
+               }
+               else if(Interface->Type == 6) {
+                       if(IP6_EQU(chan->RemoteAddr.v6, *(tIPv6*)Address))      continue;
+               }
+               else {
+                       Warning("[UDP  ] Address type %i unknown", Interface->Type);
+                       RELEASE(&glUDP_Channels);
+                       return ;
+               }
+               
+               // Create the cached packet
+               len = ntohs(hdr->Length);
+               pack = malloc(sizeof(tUDPPacket) + len);
+               pack->Next = NULL;
+               pack->Length = len;
+               memcpy(pack->Data, hdr->Data, len);
+               
+               // Add the packet to the channel's queue
+               LOCK(&chan->lQueue);
+               if(chan->Queue)
+                       chan->QueueEnd->Next = pack;
+               else
+                       chan->QueueEnd = chan->Queue = pack;
+               RELEASE(&chan->lQueue);
+               RELEASE(&glUDP_Channels);
+               return ;
+       }
+       
+       // TODO: Server/Listener
+       
+       RELEASE(&glUDP_Channels);
+}
+
+/**
+ * \brief Send a packet
+ * \param Channel      Channel to send the packet from
+ * \param Data Packet data
+ * \param Length       Length in bytes of packet data
+ */
+void UDP_SendPacket(tUDPChannel *Channel, void *Data, size_t Length)
+{
+       tUDPHeader      *hdr;
+       
+       switch(Channel->Interface->Type)
+       {
+       case 4:
+               // Create the packet
+               hdr = malloc(sizeof(tUDPHeader)+Length);
+               hdr->SourcePort = htons( Channel->LocalPort );
+               hdr->DestPort = htons( Channel->RemotePort );
+               hdr->Length = htons( Length );
+               hdr->Checksum = 0;      // Checksum can be zero on IPv4
+               memcpy(hdr->Data, Data, Length);
+               // Pass on the the IPv4 Layer
+               IPv4_SendPacket(Channel->Interface, Channel->RemoteAddr.v4, IP4PROT_UDP, 0, sizeof(tUDPHeader)+Length, hdr);
+               // Free allocated packet
+               free(hdr);
+               break;
+       }
+}
+
+// --- Client Channels
+tVFS_Node *UDP_Channel_Init(tInterface *Interface)
+{
+       tUDPChannel     *new;
+       new = calloc( sizeof(tUDPChannel), 1 );
+       new->Interface = Interface;
+       new->Node.ImplPtr = new;
+       new->Node.NumACLs = 1;
+       new->Node.ACLs = &gVFS_ACL_EveryoneRW;
+       new->Node.Read = UDP_Channel_Read;
+       new->Node.Write = UDP_Channel_Write;
+       new->Node.IOCtl = UDP_Channel_IOCtl;
+       new->Node.Close = UDP_Channel_Close;
+       
+       LOCK(&glUDP_Channels);
+       new->Next = gpUDP_Channels;
+       gpUDP_Channels = new;
+       RELEASE(&glUDP_Channels);
+       
+       return &new->Node;
+}
+
+/**
+ * \brief Read from the channel file (wait for a packet)
+ */
+Uint64 UDP_Channel_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+       tUDPChannel     *chan = Node->ImplPtr;
+       tUDPPacket      *pack;
+       
+       if(chan->LocalPort == 0)        return 0;
+       if(chan->RemotePort == 0)       return 0;
+       
+       while(chan->Queue == NULL)      Threads_Yield();
+       
+       for(;;)
+       {
+               LOCK(&chan->lQueue);
+               if(chan->Queue == NULL) {
+                       RELEASE(&chan->lQueue);
+                       continue;
+               }
+               pack = chan->Queue;
+               chan->Queue = pack->Next;
+               if(!chan->Queue)        chan->QueueEnd = NULL;
+               RELEASE(&chan->lQueue);
+               break;
+       }
+       
+       // Clip length to packet length
+       if(Length > pack->Length)       Length = pack->Length;
+       // Copy packet data from cache
+       memcpy(Buffer, pack->Data, Length);
+       // Free cached packet
+       free(pack);     
+       
+       return Length;
+}
+
+/**
+ * \brief Write to the channel file (send a packet)
+ */
+Uint64 UDP_Channel_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+       tUDPChannel     *chan = Node->ImplPtr;
+       if(chan->RemotePort == 0)       return 0;
+       
+       UDP_SendPacket(chan, Buffer, (size_t)Length);
+       
+       return 0;
+}
+
+/**
+ * \brief Names for channel IOCtl Calls
+ */
+static const char *casIOCtls_Channel[] = {
+       DRV_IOCTLNAMES,
+       "getset_localport",
+       "getset_remoteport",
+       "set_remoteaddr",
+       NULL
+       };
+/**
+ * \brief Channel IOCtls
+ */
+int UDP_Channel_IOCtl(tVFS_Node *Node, int ID, void *Data)
+{
+       tUDPChannel     *chan = Node->ImplPtr;
+       ENTER("pNode iID pData", Node, ID, Data);
+       switch(ID)
+       {
+       BASE_IOCTLS(DRV_TYPE_MISC, "UDP Channel", 0x100, casIOCtls_Channel);
+       
+       case 4: // getset_localport (returns bool success)
+               if(!Data)       LEAVE_RET('i', chan->LocalPort);
+               if(!CheckMem( Data, sizeof(Uint16) ) ) {
+                       LOG("Invalid pointer %p", Data);
+                       LEAVE_RET('i', -1);
+               }
+               // Set port
+               chan->LocalPort = *(Uint16*)Data;
+               // Permissions check (Ports lower than 1024 are root-only)
+               if(chan->LocalPort != 0 && chan->LocalPort < 1024) {
+                       if( Threads_GetUID() != 0 ) {
+                               LOG("Attempt by non-superuser to listen on port %i", chan->LocalPort);
+                               chan->LocalPort = 0;
+                               LEAVE_RET('i', -1);
+                       }
+               }
+               // Allocate a random port if requested
+               if( chan->LocalPort == 0 )
+                       chan->LocalPort = UDP_int_AllocatePort();
+               else
+               {
+                       // Else, mark the requested port as used
+                       if( UDP_int_MarkPortAsUsed(chan->LocalPort) == 0 ) {
+                               LOG("Port %i us currently in use", chan->LocalPort);
+                               chan->LocalPort = 0;
+                               LEAVE_RET('i', 0);
+                       }
+                       LEAVE_RET('i', 1);
+               }
+               LEAVE_RET('i', 1);
+       
+       case 5: // getset_remoteport (returns bool success)
+               if(!Data)       LEAVE_RET('i', chan->RemotePort);
+               if(!CheckMem( Data, sizeof(Uint16) ) ) {
+                       LOG("Invalid pointer %p", Data);
+                       LEAVE_RET('i', -1);
+               }
+               chan->RemotePort = *(Uint16*)Data;
+               return 1;
+       
+       case 6: // set_remoteaddr (returns bool success)
+               switch(chan->Interface->Type)
+               {
+               case 4:
+                       if(!CheckMem(Data, sizeof(tIPv4))) {
+                               LOG("Invalid pointer %p", Data);
+                               LEAVE_RET('i', -1);
+                       }
+                       chan->RemoteAddr.v4 = *(tIPv4*)Data;
+                       break;
+               }
+               break;
+       }
+       LEAVE_RET('i', 0);
+}
+
+/**
+ * \brief Close and destroy an open channel
+ */
+void UDP_Channel_Close(tVFS_Node *Node)
+{
+       tUDPChannel     *chan = Node->ImplPtr;
+       tUDPChannel     *prev;
+       
+       // Remove from the main list first
+       LOCK(&glUDP_Channels);
+       if(gpUDP_Channels == chan)
+               gpUDP_Channels = gpUDP_Channels->Next;
+       else
+       {
+               for(prev = gpUDP_Channels;
+                       prev->Next && prev->Next != chan;
+                       prev = prev->Next);
+               if(!prev->Next)
+                       Warning("[UDP  ] Bookeeping Fail, channel %p is not in main list", chan);
+               else
+                       prev->Next = prev->Next->Next;
+       }
+       RELEASE(&glUDP_Channels);
+       
+       // Clear Queue
+       LOCK(&chan->lQueue);
+       while(chan->Queue)
+       {
+               tUDPPacket      *tmp;
+               tmp = chan->Queue;
+               chan->Queue = tmp->Next;
+               free(tmp);
+       }
+       RELEASE(&chan->lQueue);
+       
+       // Free channel structure
+       free(chan);
+}
+
+/**
+ * \return Port Number on success, or zero on failure
+ */
+Uint16 UDP_int_AllocatePort()
+{
+        int    i;
+       LOCK(&glUDP_Ports);
+       // Fast Search
+       for( i = UDP_ALLOC_BASE; i < 0x10000; i += 32 )
+               if( gUDP_Ports[i/32] != 0xFFFFFFFF )
+                       break;
+       if(i == 0x10000)        return 0;
+       for( ;; i++ )
+       {
+               if( !(gUDP_Ports[i/32] & (1 << (i%32))) )
+                       return i;
+       }
+       RELEASE(&glUDP_Ports);
+}
+
+/**
+ * \brief Allocate a specific port
+ * \return Boolean Success
+ */
+int UDP_int_MarkPortAsUsed(Uint16 Port)
+{
+       LOCK(&glUDP_Ports);
+       if( gUDP_Ports[Port/32] & (1 << (Port%32)) ) {
+               return 0;
+               RELEASE(&glUDP_Ports);
+       }
+       gUDP_Ports[Port/32] |= 1 << (Port%32);
+       RELEASE(&glUDP_Ports);
+       return 1;
+}
+
+/**
+ * \brief Free an allocated port
+ */
+void UDP_int_FreePort(Uint16 Port)
+{
+       LOCK(&glUDP_Ports);
+       gUDP_Ports[Port/32] &= ~(1 << (Port%32));
+       RELEASE(&glUDP_Ports);
 }
index be2ff64..36c36e1 100644 (file)
@@ -9,6 +9,8 @@
 #include "ipv4.h"
 
 typedef struct sUDPHeader      tUDPHeader;
+typedef struct sUDPPacket      tUDPPacket;
+typedef struct sUDPChannel     tUDPChannel;
 
 struct sUDPHeader
 {
@@ -19,4 +21,27 @@ struct sUDPHeader
        Uint8   Data[];
 };
 
+struct sUDPPacket
+{
+       struct sUDPPacket       *Next;
+       size_t  Length;
+       Uint8   Data[];
+};
+
+struct sUDPChannel
+{
+       struct sUDPChannel      *Next;
+       tInterface      *Interface;
+       Uint16  LocalPort;
+       union {
+               tIPv4   v4;
+               tIPv6   v6;
+       }       RemoteAddr;
+       Uint16  RemotePort;
+       tVFS_Node       Node;
+       tSpinlock       lQueue;
+       tUDPPacket      * volatile Queue;
+       tUDPPacket      *QueueEnd;
+};
+
 #endif
index 41f0873..1ba124b 100644 (file)
@@ -2,7 +2,7 @@
  * Acess2 IDE Harddisk Driver
  * - main.c
  */
-#define DEBUG  0
+#define DEBUG  1
 #include <acess.h>
 #include <modules.h>
 #include <vfs.h>
@@ -110,17 +110,17 @@ tPRDT_Ent gATA_PRDTs[2] = {
 int ATA_Install()
 {
        int     ret;
-       
+
        ret = ATA_SetupIO();
        if(ret != 1)    return ret;
-       
+
        ATA_SetupPartitions();
-       
+
        ATA_SetupVFS();
-       
+
        if( DevFS_AddDevice( &gATA_DriverInfo ) == 0 )
                return MODULE_INIT_FAILURE;
-       
+
        return MODULE_INIT_SUCCESS;
 }
 
@@ -132,9 +132,9 @@ int ATA_SetupIO()
 {
         int    ent;
        tPAddr  addr;
-       
+
        ENTER("");
-       
+
        // Get IDE Controller's PCI Entry
        ent = PCI_GetDeviceByClass(0x0101, 0xFFFF, -1);
        LOG("ent = %i", ent);
@@ -156,25 +156,25 @@ int ATA_SetupIO()
                // Bit 0 is left set as a flag to other functions
                LOG("gATA_BusMasterBase = 0x%x", gATA_BusMasterBase & ~1);
        }
-       
+
        IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri );
        IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec );
-       
+
        gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( (Uint)&gATA_Buffers[0] );
        gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( (Uint)&gATA_Buffers[1] );
-       
+
        LOG("gATA_PRDTs = {PBufAddr: 0x%x, PBufAddr: 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr);
-       
+
        addr = MM_GetPhysAddr( (Uint)&gATA_PRDTs[0] );
        LOG("addr = 0x%x", addr);
        ATA_int_BusMasterWriteDWord(4, addr);
        addr = MM_GetPhysAddr( (Uint)&gATA_PRDTs[1] );
        LOG("addr = 0x%x", addr);
        ATA_int_BusMasterWriteDWord(12, addr);
-       
+
        outb(IDE_PRI_BASE+1, 1);
        outb(IDE_SEC_BASE+1, 1);
-       
+
        LEAVE('i', MODULE_INIT_SUCCESS);
        return MODULE_INIT_SUCCESS;
 }
@@ -201,7 +201,7 @@ void ATA_SetupPartitions()
 void ATA_SetupVFS()
 {
         int    i, j, k;
-       
+
        // Count number of nodes needed
        giATA_NumNodes = 0;
        for( i = 0; i < MAX_ATA_DISKS; i++ )
@@ -210,10 +210,10 @@ void ATA_SetupVFS()
                giATA_NumNodes ++;
                giATA_NumNodes += gATA_Disks[i].NumPartitions;
        }
-       
+
        // Allocate Node space
        gATA_Nodes = malloc( giATA_NumNodes * sizeof(void*) );
-       
+
        // Set nodes
        k = 0;
        for( i = 0; i < MAX_ATA_DISKS; i++ )
@@ -223,7 +223,7 @@ void ATA_SetupVFS()
                for( j = 0; j < gATA_Disks[i].NumPartitions; j ++ )
                        gATA_Nodes[ k++ ] = &gATA_Disks[i].Partitions[j].Node;
        }
-       
+
        gATA_DriverInfo.RootNode.Size = giATA_NumNodes;
 }
 
@@ -239,19 +239,19 @@ int ATA_ScanDisk(int Disk)
        Uint8   val;
         int    i;
        tVFS_Node       *node;
-       
+
        ENTER("iDisk", Disk);
-       
+
        base = ATA_GetBasePort( Disk );
-       
+
        LOG("base = 0x%x", base);
-       
+
        // Send Disk Selector
        if(Disk == 1 || Disk == 3)
                outb(base+6, 0xB0);
        else
                outb(base+6, 0xA0);
-       
+
        // Send IDENTIFY
        outb(base+7, 0xEC);
        val = inb(base+7);      // Read status
@@ -259,27 +259,27 @@ int ATA_ScanDisk(int Disk)
                LEAVE('i', 0);
                return 0;       // Disk does not exist
        }
-       
+
        // Poll until BSY clears and DRQ sets or ERR is set
        while( ((val & 0x80) || !(val & 0x08)) && !(val & 1))   val = inb(base+7);
-       
+
        if(val & 1) {
                LEAVE('i', 0);
                return 0;       // Error occured, so return false
        }
-       
+
        // Read Data
        for(i=0;i<256;i++)      buf[i] = inw(base);
-       
+
        // Populate Disk Structure
        if(identify->Sectors48 != 0)
                gATA_Disks[ Disk ].Sectors = identify->Sectors48;
        else
                gATA_Disks[ Disk ].Sectors = identify->Sectors28;
-       
-       
+
+
        LOG("gATA_Disks[ Disk ].Sectors = 0x%x", gATA_Disks[ Disk ].Sectors);
-       
+
        if( gATA_Disks[ Disk ].Sectors / (2048*1024) )
                Log("Disk %i: 0x%llx Sectors (%i GiB)", Disk,
                        gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / (2048*1024));
@@ -289,21 +289,21 @@ int ATA_ScanDisk(int Disk)
        else
                Log("Disk %i: 0x%llx Sectors (%i KiB)", Disk,
                        gATA_Disks[ Disk ].Sectors, gATA_Disks[ Disk ].Sectors / 2);
-       
+
        // Create Name
        gATA_Disks[ Disk ].Name[0] = 'A'+Disk;
        gATA_Disks[ Disk ].Name[1] = '\0';
-       
+
        // Get pointer to vfs node and populate it
        node = &gATA_Disks[ Disk ].Node;
        node->Size = gATA_Disks[Disk].Sectors * SECTOR_SIZE;
        node->NumACLs = 0;      // Means Superuser only can access it
        node->Inode = (Disk << 8) | 0xFF;
        node->ImplPtr = gATA_Disks[ Disk ].Name;
-       
+
        node->ATime = node->MTime
                = node->CTime = now();
-       
+
        node->Read = ATA_ReadFS;
        node->Write = ATA_WriteFS;
        node->IOCtl = ATA_IOCtl;
@@ -313,13 +313,13 @@ int ATA_ScanDisk(int Disk)
        LOG("Reading MBR");
        // Read Boot Sector
        ATA_ReadDMA( Disk, 0, 1, mbr );
-       
+
        // Check for a GPT table
        if(mbr->Parts[0].SystemID == 0xEE)
                ATA_ParseGPT(Disk);
        else    // No? Just parse the MBR
                ATA_ParseMBR(Disk);
-       
+
        LEAVE('i', 0);
        return 1;
 }
@@ -345,7 +345,7 @@ void ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start
        Part->Node.NumACLs = 0; // Only root can read/write raw block devices
        Part->Node.Inode = (Disk << 8) | Num;
        Part->Node.ImplPtr = Part->Name;
-       
+
        Part->Node.Read = ATA_ReadFS;
        Part->Node.Write = ATA_WriteFS;
        Part->Node.IOCtl = ATA_IOCtl;
@@ -401,7 +401,7 @@ tVFS_Node *ATA_FindDir(tVFS_Node *Node, char *Name)
                        return NULL;
                return &gATA_Disks[Name[0]-'A'].Node;
        }
-       
+
        // Partitions
        if(Name[1] < '0' || '9' < Name[1])      return NULL;
        if(Name[2] == '\0') {   // <= 9
@@ -412,12 +412,12 @@ tVFS_Node *ATA_FindDir(tVFS_Node *Node, char *Name)
        // > 9
        if('0' > Name[2] || '9' < Name[2])      return NULL;
        if(Name[3] != '\0')     return NULL;
-       
+
        part = (Name[1] - '0') * 10;
        part += Name[2] - '0';
        part --;
        return &gATA_Disks[Name[0]-'A'].Partitions[part].Node;
-       
+
 }
 
 /**
@@ -427,7 +427,7 @@ Uint64 ATA_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
 {
         int    disk = Node->Inode >> 8;
         int    part = Node->Inode & 0xFF;
-       
+
        // Raw Disk Access
        if(part == 0xFF)
        {
@@ -445,7 +445,7 @@ Uint64 ATA_ReadFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                        Length = gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE - Offset;
                Offset += gATA_Disks[disk].Partitions[part].Start * SECTOR_SIZE;
        }
-       
+
        //Log("ATA_ReadFS: (Node=%p, Offset=0x%llx, Length=0x%llx, Buffer=%p)", Node, Offset, Length, Buffer);
        return DrvUtil_ReadBlock(Offset, Length, Buffer, ATA_ReadRaw, SECTOR_SIZE, disk);
 }
@@ -457,7 +457,7 @@ Uint64 ATA_WriteFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
 {
         int    disk = Node->Inode >> 8;
         int    part = Node->Inode & 0xFF;
-       
+
        // Raw Disk Access
        if(part == 0xFF)
        {
@@ -475,7 +475,7 @@ Uint64 ATA_WriteFS(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                        Length = gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE - Offset;
                Offset += gATA_Disks[disk].Partitions[part].Start * SECTOR_SIZE;
        }
-       
+
        Log("ATA_WriteFS: (Node=%p, Offset=0x%llx, Length=0x%llx, Buffer=%p)", Node, Offset, Length, Buffer);
        Debug_HexDump("ATA_WriteFS", Buffer, Length);
        return DrvUtil_WriteBlock(Offset, Length, Buffer, ATA_ReadRaw, ATA_WriteRaw, SECTOR_SIZE, disk);
@@ -503,7 +503,7 @@ Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
         int    ret;
        Uint    offset;
        Uint    done = 0;
-        
+
        // Pass straight on to ATA_ReadDMAPage if we can
        if(Count <= MAX_DMA_SECTORS)
        {
@@ -511,7 +511,7 @@ Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
                if(ret == 0)    return 0;
                return Count;
        }
-       
+
        // Else we will have to break up the transfer
        offset = 0;
        while(Count > MAX_DMA_SECTORS)
@@ -524,7 +524,7 @@ Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
                Count -= MAX_DMA_SECTORS;
                offset += MAX_DMA_SECTORS*SECTOR_SIZE;
        }
-       
+
        ret = ATA_ReadDMA(Disk, Address+offset, Count, Buffer+offset);
        if(ret != 1)    return 0;
        return done+Count;
@@ -538,7 +538,7 @@ Uint ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
         int    ret;
        Uint    offset;
        Uint    done = 0;
-        
+
        // Pass straight on to ATA_WriteDMA if we can
        if(Count <= MAX_DMA_SECTORS)
        {
@@ -546,7 +546,7 @@ Uint ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
                if(ret == 0)    return 0;
                return Count;
        }
-       
+
        // Else we will have to break up the transfer
        offset = 0;
        while(Count > MAX_DMA_SECTORS)
@@ -559,7 +559,7 @@ Uint ATA_WriteRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
                Count -= MAX_DMA_SECTORS;
                offset += MAX_DMA_SECTORS*SECTOR_SIZE;
        }
-       
+
        ret = ATA_WriteDMA(Disk, Address+offset, Count, Buffer+offset);
        if(ret != 1)    return 0;
        return done+Count;
@@ -573,9 +573,9 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
         int    cont = (Disk>>1)&1;     // Controller ID
         int    disk = Disk & 1;
        Uint16  base;
-       
+
        ENTER("iDisk XAddress iCount pBuffer", Disk, Address, Count, Buffer);
-       
+
        // Check if the count is small enough
        if(Count > MAX_DMA_SECTORS) {
                Warning("Passed too many sectors for a bulk DMA read (%i > %i)",
@@ -583,19 +583,19 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
                LEAVE('i');
                return 0;
        }
-       
+
        // Get exclusive access to the disk controller
        LOCK( &giaATA_ControllerLock[ cont ] );
-       
+
        // Set Size
        gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
-       
+
        // Get Port Base
        base = ATA_GetBasePort(Disk);
-       
+
        // Reset IRQ Flag
        gaATA_IRQs[cont] = 0;
-       
+
        // Set up transfer
        outb(base+0x01, 0x00);
        if( Address > 0x0FFFFFFF )      // Use LBA48
@@ -610,12 +610,12 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
        {
                outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); //Disk,Magic,High addr
        }
-       
+
        outb(base+0x02, (Uint8) Count);         // Sector Count
        outb(base+0x03, (Uint8) Address);               // Low Addr
        outb(base+0x04, (Uint8) (Address >> 8));        // Middle Addr
        outb(base+0x05, (Uint8) (Address >> 16));       // High Addr
-       
+
        LOG("Starting Transfer");
        #if START_BEFORE_CMD
        // Start transfer
@@ -632,7 +632,7 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
        // Start transfer
        ATA_int_BusMasterWriteByte( cont << 3, 9 );     // Read and start
        #endif
-       
+
        // Wait for transfer to complete
        //ATA_int_BusMasterWriteByte( (cont << 3) + 2, 0x4 );
        while( gaATA_IRQs[cont] == 0 ) {
@@ -640,18 +640,18 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
                //LOG("val = 0x%02x", val);
                Threads_Yield();
        }
-       
+
        // Complete Transfer
        ATA_int_BusMasterWriteByte( cont << 3, 0 );     // Write and stop
-       
+
        LOG("Transfer Completed & Acknowledged");
-       
+
        // Copy to destination buffer
        memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE );
-       
+
        // Release controller lock
        RELEASE( &giaATA_ControllerLock[ cont ] );
-       
+
        LEAVE('i', 1);
        return 1;
 }
@@ -664,19 +664,19 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
         int    cont = (Disk>>1)&1;     // Controller ID
         int    disk = Disk & 1;
        Uint16  base;
-       
+
        // Check if the count is small enough
        if(Count > MAX_DMA_SECTORS)     return 0;
-       
+
        // Get exclusive access to the disk controller
        LOCK( &giaATA_ControllerLock[ cont ] );
-       
+
        // Set Size
        gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
-       
+
        // Get Port Base
        base = ATA_GetBasePort(Disk);
-       
+
        // Set up transfer
        outb(base+0x01, 0x00);
        if( Address > 0x0FFFFFFF )      // Use LBA48
@@ -691,7 +691,7 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
        {
                outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F)); //Disk,Magic,High addr
        }
-       
+
        outb(base+0x02, (Uint8) Count);         // Sector Count
        outb(base+0x03, (Uint8) Address);               // Low Addr
        outb(base+0x04, (Uint8) (Address >> 8));        // Middle Addr
@@ -700,25 +700,25 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
                outb(base+0x07, HDD_DMA_W48);   // Write Command (LBA48)
        else
                outb(base+0x07, HDD_DMA_W28);   // Write Command (LBA28)
-       
+
        // Reset IRQ Flag
        gaATA_IRQs[cont] = 0;
-       
+
        // Copy to output buffer
        memcpy( gATA_Buffers[cont], Buffer, Count*SECTOR_SIZE );
-       
+
        // Start transfer
        ATA_int_BusMasterWriteByte( cont << 3, 1 );     // Write and start
-       
+
        // Wait for transfer to complete
        while( gaATA_IRQs[cont] == 0 )  Threads_Yield();
-       
+
        // Complete Transfer
        ATA_int_BusMasterWriteByte( cont << 3, 0 );     // Write and stop
-       
+
        // Release controller lock
        RELEASE( &giaATA_ControllerLock[ cont ] );
-       
+
        return 1;
 }
 
@@ -728,7 +728,7 @@ int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
 void ATA_IRQHandlerPri(int unused)
 {
        Uint8   val;
-       
+
        // IRQ bit set for Primary Controller
        val = ATA_int_BusMasterReadByte( 0x2 );
        LOG("IRQ val = 0x%x", val);
@@ -748,6 +748,7 @@ void ATA_IRQHandlerSec(int unused)
        Uint8   val;
        // IRQ bit set for Secondary Controller
        val = ATA_int_BusMasterReadByte( 0xA );
+       LOG("IRQ val = 0x%x", val);
        if(val & 4) {
                LOG("IRQ hit (val = 0x%x)", val);
                ATA_int_BusMasterWriteByte( 0xA, 4 );
@@ -785,7 +786,7 @@ void ATA_int_BusMasterWriteByte(int Ofs, Uint8 Value)
  */
 void ATA_int_BusMasterWriteDWord(int Ofs, Uint32 Value)
 {
-       
+
        if( gATA_BusMasterBase & 1 )
                outd( (gATA_BusMasterBase & ~1) + Ofs, Value );
        else
index 13039a3..7d26b39 100644 (file)
@@ -38,7 +38,8 @@ int main(int argc, char *argv[])
        // Main Loop
        for(;;)
        {
-               yield();
+               Messages_PollIPC();
+               //yield();
        }
        return 0;
 }
index bf2d2b8..0147e5f 100644 (file)
@@ -22,13 +22,13 @@ void        Messages_Handle(tAxWin_Message *Msg, tMessages_Handle_Callback *Respond, in
 void Messages_PollIPC()
 {
         int    len;
-        int    tid = 0;
+       pid_t   tid = 0;
        char    staticBuf[STATICBUF_SIZE];
        tAxWin_Message  *msg;
        
        // Wait for a message
-       while( (len = SysGetMessage(&tid, NULL)) )
-               yield();
+       while( (len = SysGetMessage(&tid, NULL)) == 0 )
+               sleep();
        
        // Allocate the space for it
        if( len <= STATICBUF_SIZE )
index 7f8746b..eb8fa19 100644 (file)
@@ -61,7 +61,6 @@ void DumpInterfaces(int DumpAll)
        while( readdir(dp, filename) )
        {
                if(filename[0] == '.')  continue;
-               if(filename[0] != 'i' || filename[1] != 'p')    continue;
                
                fd = open(path, OPENFLAG_READ);
                if(fd == -1) {
@@ -142,7 +141,7 @@ int DoAutoConfig( char *Device )
        tmp = AddInterface(Device);
        if( tmp < 0 )   return tmp;
        
-       sprintf(path, IPSTACK_ROOT"/ip%i", tmp);
+       sprintf(path, IPSTACK_ROOT"/%i", tmp);
        
        fd = open(path, OPENFLAG_READ);
        if( fd == -1 ) {
index e4a4aac..abd8c81 100644 (file)
@@ -6,6 +6,6 @@
 MAKEDEP  = $(CC) -M
 
 ASFLAGS  = -felf
-CPPFLAGS = -I../../include/
+CPPFLAGS = -I$(ACESSDIR)/Usermode/include/
 CFLAGS   = -Wall -fPIC -fno-builtin -fno-stack-protector $(CPPFLAGS)
 LDFLAGS  = -nostdlib -shared -I/Acess/Libs/ld-acess.so -e SoMain -x -L.. -lacess
index 7f4d7db..c034b77 100644 (file)
@@ -7,11 +7,15 @@
 #include <stdint.h>
 
 // === CONSTANTS ===
+#ifndef NULL
+# define NULL  ((void*)0)
+#endif
+
 #define OPENFLAG_EXEC  0x01
 #define OPENFLAG_READ  0x02
 #define OPENFLAG_WRITE 0x04
 #define        OPENFLAG_NOLINK 0x40
-#define        OPENFLAG_CREATE 0x40
+#define        OPENFLAG_CREATE 0x80
 #ifndef SEEK_CUR
 # define SEEK_SET      1
 # define SEEK_CUR      0
@@ -23,6 +27,8 @@
 #define FILEFLAG_SYMLINK       0x20
 
 // === TYPES ===
+typedef uint   pid_t;
+
 struct s_sysACL {
        union {
                struct {
@@ -90,8 +96,8 @@ extern int    _SysGetACL(int fd, t_sysACL *dest);
 extern int     _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options);
 
 // --- IPC ---
-extern int     SysSendMessage(int dest, int length, void *Data);
-extern int     SysGetMessage(int *src, void *Data);
+extern int     SysSendMessage(pid_t dest, uint length, void *Data);
+extern int     SysGetMessage(pid_t *src, void *Data);
 
 // --- MEMORY ---
 uint64_t       _SysGetPhys(uint vaddr);
index c11b864..e4ed1fe 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef _AXWIN_MESSAGES_H
 #define _AXWIN_MESSAGES_H
 
+#include <stdint.h>
+
 typedef struct sAxWin_Message  tAxWin_Message;
 
 /**
@@ -16,7 +18,7 @@ enum eAxWin_Messages
        // Server Requests
        MSG_SREQ_PING,
        // - Windows
-       MSG_SREQ_NEWWINDOW,
+       MSG_SREQ_NEWWINDOW,     // (short x, y, w, h, uint32_t flags)
        MSG_SREQ_GETFLAGS,      MSG_SREQ_SETFLAGS,
        MSG_SREQ_GETRECT,       MSG_SREQ_SETRECT,
        // - Drawing
@@ -29,19 +31,54 @@ enum eAxWin_Messages
        
        // Server Responses
        MSG_SRSP_PONG,
+       MSG_SRSP_WINDOW,        // Returns the new window ID
        MSG_SRSP_IMG,   // Returns the image ID
        
        NUM_MSG
 };
 
+// --- Server Requests (Requests from the client of the server)
 /**
- * \brief New Window Request structure
+ * \brief Server Request - Ping (Get Server Version)
  */
-struct sAxWin_Req_NewWindow
+struct sAxWin_SReq_Ping
 {
-       
 };
 
+/**
+ * \brief Server Request - New Window
+ * \see eAxWin_Messages.MSG_SREQ_NEWWINDOW
+ */
+struct sAxWin_SReq_NewWindow
+{
+       uint16_t        X, Y, W, H;
+       uint32_t        Flags;
+};
+
+
+// --- Server Responses
+/**
+ * \brief Server Response - Pong
+ * \see eAxWin_Messages.MSG_SRSP_PONG
+ */
+struct sAxWin_SRsp_Pong
+{
+       uint8_t Major;
+       uint8_t Minor;
+       uint16_t        Build;
+};
+
+/**
+ * \brief Server Response - New Window
+ * \see eAxWin_Messages.MSG_SRSP_NEWWINDOW
+ */
+struct sAxWin_SRsp_NewWindow
+{
+       uint32_t        Handle;
+};
+
+
+// === Core Message Structure
 /**
  * \brief Overarching Message Structure
  * \note sizeof(tAxWin_Message) is never valid
@@ -50,6 +87,15 @@ struct sAxWin_Message
 {
        uint16_t        ID;
        uint16_t        Size;   //!< Size in DWORDS
+       union
+       {
+               struct sAxWin_SReq_Ping SReq_Pong;
+               struct sAxWin_SReq_NewWindow    SReq_NewWindow;
+               
+               // Server Responses
+               struct sAxWin_SRsp_Pong SRsp_Pong;
+               struct sAxWin_SRsp_NewWindow    SRsp_Window;
+       };
 };
 
 #endif

UCC git Repository :: git.ucc.asn.au