Cleanups & Implementations to allow IPStack to compile
[tpg/acess2.git] / Modules / IPStack / link.c
1 /*
2  * Acess2 IP Stack
3  * - Link/Media Layer Interface
4  */
5 #include "ipstack.h"
6 #include "link.h"
7
8 // === CONSTANTS ===
9 #define MAX_PACKET_SIZE 2048
10
11 // === GLOBALS ===
12  int    giRegisteredTypes = 0;
13 struct {
14         Uint16  Type;
15         tPacketCallback Callback;
16 }       *gaRegisteredTypes;
17
18 // === CODE ===
19 /**
20  * \fn void Link_RegisterType(Uint16 Type, tPacketCallback Callback)
21  * \brief Registers a callback for a specific packet type
22  * 
23  * \todo Make thread safe (place a mutex on the list)
24  */
25 void Link_RegisterType(Uint16 Type, tPacketCallback Callback)
26 {
27          int    i;
28         void    *tmp;
29         for( i = giRegisteredTypes; i -- ; )
30         {
31                 if(gaRegisteredTypes[i].Type == Type) {
32                         Warning("[NET  ] Attempt to register 0x%x twice", Type);
33                         return ;
34                 }
35                 // Ooh! Free slot!
36                 if(gaRegisteredTypes[i].Callback == NULL)       break;
37         }
38         
39         if(i == -1)
40         {
41                 tmp = realloc(gaRegisteredTypes, (giRegisteredTypes+1)*sizeof(*gaRegisteredTypes));
42                 if(!tmp)        Panic("[NET  ] Out of heap space!");
43                 i = giRegisteredTypes;
44                 giRegisteredTypes ++;
45                 gaRegisteredTypes = tmp;
46         }
47         
48         gaRegisteredTypes[i].Callback = Callback;
49         gaRegisteredTypes[i].Type = Type;
50 }
51
52 /**
53  * \fn void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, int Length, void *Buffer)
54  * \brief Formats and sends a packet on the specified interface
55  */
56 void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, int Length, void *Buffer)
57 {
58          int    bufSize = sizeof(tEthernetHeader) + Length;
59         Uint8   buf[bufSize];
60         tEthernetHeader *hdr = (void*)buf;
61         
62         hdr->Dest = To;
63         hdr->Src = Adapter->MacAddr;
64         hdr->Type = htons(Type);
65         
66         memcpy(hdr->Data, Buffer, Length);
67         
68         VFS_Write(Adapter->DeviceFD, bufSize, buf);
69 }
70
71 /**
72  * \fn void Link_WatchDevice(tAdapter *Adapter)
73  * \brief Spawns a worker thread to watch the specified adapter
74  */
75 void Link_WatchDevice(tAdapter *Adapter)
76 {
77          int    tid = Proc_SpawnWorker();       // Create a new worker thread
78         
79         if(tid < 0) {
80                 Panic("[NET  ] Unable to create watcher thread for '%s'", Adapter->Device);
81         }
82         
83         if(tid > 0) {
84                 Log("[NET  ] Watching '%s' using tid %i", Adapter->Device, tid);
85                 return ;
86         }
87         
88         // Child Thread
89         while(Adapter->DeviceFD != -1)
90         {
91                 Uint8   buf[MAX_PACKET_SIZE];
92                 tEthernetHeader *hdr = (void*)buf;
93                  int    ret, i;
94                 
95                 // Wait for a packet (Read on a network device is blocking)
96                 ret = VFS_Read(Adapter->DeviceFD, MAX_PACKET_SIZE, buf);
97                 if(ret == -1)   break;
98                 
99                 if(ret <= sizeof(tEthernetHeader)) {
100                         Log("[NET  ] Recieved an undersized packet");
101                         continue;
102                 }
103                 
104                 // Check if there is a registered callback for this packet type
105                 for( i = giRegisteredTypes; i--; )
106                 {
107                         if(gaRegisteredTypes[i].Type == hdr->Type)      continue;
108                 }
109                 // No? Ignore it
110                 if( i == -1 )   continue;
111                 
112                 // Call the callback
113                 gaRegisteredTypes[i].Callback(
114                         Adapter,
115                         hdr->Src,
116                         ret - sizeof(tEthernetHeader),
117                         hdr->Data
118                         );
119         }
120         
121         Log("[NET  ] Watcher terminated (file closed)");
122 }

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