1 | // DS Wifi interface code |
---|
2 | // Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org |
---|
3 | // wifi_arm9.c - arm9 wifi support code |
---|
4 | /****************************************************************************** |
---|
5 | DSWifi Lib and test materials are licenced under the MIT open source licence: |
---|
6 | Copyright (c) 2005-2006 Stephen Stair |
---|
7 | |
---|
8 | Permission is hereby granted, free of charge, to any person obtaining a copy of |
---|
9 | this software and associated documentation files (the "Software"), to deal in |
---|
10 | the Software without restriction, including without limitation the rights to |
---|
11 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies |
---|
12 | of the Software, and to permit persons to whom the Software is furnished to do |
---|
13 | so, subject to the following conditions: |
---|
14 | |
---|
15 | The above copyright notice and this permission notice shall be included in all |
---|
16 | copies or substantial portions of the Software. |
---|
17 | |
---|
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
---|
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
---|
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
---|
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
---|
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
---|
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
---|
24 | SOFTWARE. |
---|
25 | ******************************************************************************/ |
---|
26 | |
---|
27 | #include <unistd.h> |
---|
28 | |
---|
29 | #include <nds.h> |
---|
30 | #include "dsregs.h" |
---|
31 | |
---|
32 | #include "wifi_arm9.h" |
---|
33 | #include <stdarg.h> |
---|
34 | #include <stdlib.h> |
---|
35 | #include <sys/socket.h> |
---|
36 | |
---|
37 | |
---|
38 | |
---|
39 | |
---|
40 | |
---|
41 | |
---|
42 | |
---|
43 | |
---|
44 | |
---|
45 | #ifdef WIFI_USE_TCP_SGIP |
---|
46 | |
---|
47 | #include "sgIP.h" |
---|
48 | |
---|
49 | |
---|
50 | sgIP_Hub_HWInterface * wifi_hw; |
---|
51 | |
---|
52 | |
---|
53 | int sgIP_DisableInterrupts() { |
---|
54 | int a; |
---|
55 | a=REG_IME; |
---|
56 | REG_IME=0; |
---|
57 | return a; |
---|
58 | } |
---|
59 | void sgIP_RestoreInterrupts(int old_ime) { |
---|
60 | REG_IME=old_ime; |
---|
61 | } |
---|
62 | |
---|
63 | void sgIP_IntrWaitEvent() { |
---|
64 | // __asm( ".ARM\n swi 0x060000\n" ); |
---|
65 | int i,j; |
---|
66 | j=0; |
---|
67 | for(i=0;i<20000;i++) { |
---|
68 | j+=i; |
---|
69 | } |
---|
70 | } |
---|
71 | |
---|
72 | void * sgIP_malloc(int size) __attribute__((weak)); |
---|
73 | void sgIP_free(void * ptr) __attribute__((weak)); |
---|
74 | |
---|
75 | |
---|
76 | |
---|
77 | ////////////////////////////////////////////////////////////////////////// |
---|
78 | // wifi heap allocator system |
---|
79 | |
---|
80 | #define WHEAP_RECORD_FLAG_INUSE 0 |
---|
81 | #define WHEAP_RECORD_FLAG_UNUSED 1 |
---|
82 | #define WHEAP_RECORD_FLAG_FREED 2 |
---|
83 | |
---|
84 | typedef struct WHEAP_RECORD { |
---|
85 | struct WHEAP_RECORD * next; |
---|
86 | unsigned short flags, unused; |
---|
87 | int size; |
---|
88 | } wHeapRecord; |
---|
89 | |
---|
90 | #ifdef SGIP_DEBUG |
---|
91 | #define WHEAP_FILL_START 0xAA |
---|
92 | #define WHEAP_FILL_END 0xBB |
---|
93 | #define WHEAP_PAD_START 4 |
---|
94 | #define WHEAP_PAD_END 4 |
---|
95 | #define WHEAP_DO_PAD |
---|
96 | #else |
---|
97 | #define WHEAP_PAD_START 0 |
---|
98 | #define WHEAP_PAD_END 0 |
---|
99 | #undef WHEAP_DO_PAD |
---|
100 | #endif |
---|
101 | #define WHEAP_RECORD_SIZE (sizeof(wHeapRecord)) |
---|
102 | #define WHEAP_PAD_SIZE ((WHEAP_PAD_START)+(WHEAP_PAD_END)) |
---|
103 | #define WHEAP_SIZE_CUTOFF ((WHEAP_RECORD_SIZE)+64) |
---|
104 | |
---|
105 | |
---|
106 | int wHeapsize; |
---|
107 | wHeapRecord * wHeapStart; // start of heap |
---|
108 | wHeapRecord * wHeapFirst; // first free block |
---|
109 | void wHeapAllocInit(int size) { |
---|
110 | wHeapStart=(wHeapRecord *)malloc(size); |
---|
111 | wHeapFirst=wHeapStart; |
---|
112 | wHeapStart->flags=WHEAP_RECORD_FLAG_UNUSED; |
---|
113 | wHeapStart->next=0; |
---|
114 | wHeapStart->size=size-sizeof(wHeapRecord); |
---|
115 | } |
---|
116 | |
---|
117 | |
---|
118 | void * wHeapAlloc(int size) { |
---|
119 | wHeapRecord * rec = wHeapFirst; |
---|
120 | void * voidptr; |
---|
121 | int n; |
---|
122 | size=(size+3)&(~3); |
---|
123 | if(size==0) size=4; |
---|
124 | size+=WHEAP_PAD_SIZE; |
---|
125 | if(!rec) { SGIP_DEBUG_MESSAGE(("wHeapAlloc: heap full!")); return 0; } // should not happen given normal use. |
---|
126 | while(rec->size<size) { |
---|
127 | if(!rec->next) { SGIP_DEBUG_MESSAGE(("wHeapAlloc: heap too full!")); return 0; } // cannot alloc |
---|
128 | if(rec->next->flags!=WHEAP_RECORD_FLAG_INUSE) { // try to merge with next one |
---|
129 | rec->size+=rec->next->size+WHEAP_RECORD_SIZE; |
---|
130 | rec->next=rec->next->next; |
---|
131 | } else { // skip ahead to more friendly waters |
---|
132 | rec=rec->next; |
---|
133 | while(rec->next) { |
---|
134 | if(rec->flags!=WHEAP_RECORD_FLAG_INUSE) break; |
---|
135 | rec=rec->next; |
---|
136 | } |
---|
137 | if(rec->flags==WHEAP_RECORD_FLAG_INUSE) { SGIP_DEBUG_MESSAGE(("wHeapAlloc: heap too full!")); return 0; } // no empty slots :( |
---|
138 | } |
---|
139 | } |
---|
140 | rec->flags=WHEAP_RECORD_FLAG_INUSE; |
---|
141 | n=rec->size-size; |
---|
142 | voidptr = ((char *)rec)+WHEAP_RECORD_SIZE+WHEAP_PAD_START; |
---|
143 | if(n<WHEAP_SIZE_CUTOFF) { // pad to include unused portion |
---|
144 | rec->unused=n; |
---|
145 | } else { // chop block into 2 |
---|
146 | wHeapRecord * rec2; |
---|
147 | rec2=(wHeapRecord *)(((char *)rec)+WHEAP_RECORD_SIZE+size); |
---|
148 | rec2->flags=WHEAP_RECORD_FLAG_UNUSED; |
---|
149 | rec2->size=rec->size-size-WHEAP_RECORD_SIZE; |
---|
150 | rec->size=size; |
---|
151 | rec2->next=rec->next; |
---|
152 | rec->next=rec2; |
---|
153 | rec->unused=0; |
---|
154 | } |
---|
155 | if(rec==wHeapFirst) { |
---|
156 | while(wHeapFirst->next && wHeapFirst->flags==WHEAP_RECORD_FLAG_INUSE) wHeapFirst=wHeapFirst->next; |
---|
157 | if(wHeapFirst->flags==WHEAP_RECORD_FLAG_INUSE) wHeapFirst=0; |
---|
158 | } |
---|
159 | #ifdef WHEAP_DO_PAD |
---|
160 | { |
---|
161 | int i; |
---|
162 | for(i=0;i<WHEAP_PAD_START;i++) { |
---|
163 | (((unsigned char *)rec)+WHEAP_RECORD_SIZE)[i]=WHEAP_FILL_START; |
---|
164 | } |
---|
165 | for(i=0;i<WHEAP_PAD_END;i++) { |
---|
166 | (((unsigned char *)rec)+WHEAP_RECORD_SIZE+size-WHEAP_PAD_END)[i]=WHEAP_FILL_END; |
---|
167 | } |
---|
168 | } |
---|
169 | #endif |
---|
170 | return voidptr; |
---|
171 | } |
---|
172 | |
---|
173 | void wHeapFree(void * data) { |
---|
174 | wHeapRecord * rec = (wHeapRecord *)(((char *)data)-WHEAP_RECORD_SIZE-WHEAP_PAD_START); |
---|
175 | #ifdef WHEAP_DO_PAD |
---|
176 | { |
---|
177 | int size=rec->size-rec->unused; |
---|
178 | int i; |
---|
179 | for(i=0;i<WHEAP_PAD_START;i++) { |
---|
180 | if((((unsigned char *)rec)+WHEAP_RECORD_SIZE)[i]!=WHEAP_FILL_START) break; |
---|
181 | } |
---|
182 | if(i!=WHEAP_PAD_START) { // note heap error |
---|
183 | SGIP_DEBUG_MESSAGE(("wHeapFree: Corruption found before allocated data! 0x%X",data)); |
---|
184 | } |
---|
185 | for(i=0;i<WHEAP_PAD_END;i++) { |
---|
186 | if((((unsigned char *)rec)+WHEAP_RECORD_SIZE+size-WHEAP_PAD_END)[i]!=WHEAP_FILL_END) break; |
---|
187 | } |
---|
188 | if(i!=WHEAP_PAD_END) { // note heap error |
---|
189 | SGIP_DEBUG_MESSAGE(("wHeapFree: Corruption found after allocated data! 0x%x",data)); |
---|
190 | } |
---|
191 | } |
---|
192 | #endif |
---|
193 | if(rec->flags!=WHEAP_RECORD_FLAG_INUSE) { // note heap error |
---|
194 | SGIP_DEBUG_MESSAGE(("wHeapFree: Data already freed! 0x%X",data)); |
---|
195 | } |
---|
196 | rec->flags=WHEAP_RECORD_FLAG_FREED; |
---|
197 | if(rec<wHeapFirst || !wHeapFirst) wHeapFirst=rec; // reposition the "starting" pointer. |
---|
198 | } |
---|
199 | |
---|
200 | |
---|
201 | ////////////////////////////////////////////////////////////////////////// |
---|
202 | |
---|
203 | |
---|
204 | |
---|
205 | |
---|
206 | |
---|
207 | void * sgIP_malloc(int size) { return wHeapAlloc(size); } |
---|
208 | void sgIP_free(void * ptr) { wHeapFree(ptr); } |
---|
209 | |
---|
210 | |
---|
211 | #endif |
---|
212 | |
---|
213 | |
---|
214 | |
---|
215 | |
---|
216 | |
---|
217 | void ethhdr_print(char f, void * d) { |
---|
218 | char buffer[33]; |
---|
219 | int i; |
---|
220 | int t,c; |
---|
221 | buffer[0]=f; |
---|
222 | buffer[1]=':'; |
---|
223 | buffer[14]=' '; |
---|
224 | buffer[27]=' '; |
---|
225 | buffer[32]=0; |
---|
226 | for(i=0;i<6;i++) { |
---|
227 | t=((u8 *)d)[i]; |
---|
228 | c=t&15; |
---|
229 | if(c>9) c+='A'-10; else c+='0'; |
---|
230 | buffer[3+i*2]=c; |
---|
231 | c=(t>>4)&15; |
---|
232 | if(c>9) c+='A'-10; else c+='0'; |
---|
233 | buffer[2+i*2]=c; |
---|
234 | |
---|
235 | t=((u8 *)d)[i+6]; |
---|
236 | c=t&15; |
---|
237 | if(c>9) c+='A'-10; else c+='0'; |
---|
238 | buffer[16+i*2]=c; |
---|
239 | c=(t>>4)&15; |
---|
240 | if(c>9) c+='A'-10; else c+='0'; |
---|
241 | buffer[15+i*2]=c; |
---|
242 | } |
---|
243 | for(i=0;i<2;i++) { |
---|
244 | t=((u8 *)d)[i+12]; |
---|
245 | c=t&15; |
---|
246 | if(c>9) c+='A'-10; else c+='0'; |
---|
247 | buffer[29+i*2]=c; |
---|
248 | c=(t>>4)&15; |
---|
249 | if(c>9) c+='A'-10; else c+='0'; |
---|
250 | buffer[28+i*2]=c; |
---|
251 | } |
---|
252 | SGIP_DEBUG_MESSAGE((buffer)); |
---|
253 | } |
---|
254 | |
---|
255 | |
---|
256 | |
---|
257 | |
---|
258 | Wifi_MainStruct Wifi_Data_Struct; |
---|
259 | |
---|
260 | volatile Wifi_MainStruct * WifiData = 0; |
---|
261 | |
---|
262 | WifiPacketHandler packethandler = 0; |
---|
263 | WifiSyncHandler synchandler = 0; |
---|
264 | |
---|
265 | void erasemem(void * mem, int length) { |
---|
266 | int i; |
---|
267 | char * m = (char *)mem; |
---|
268 | for(i=0;i<length;i++) |
---|
269 | m[i]=0; |
---|
270 | } |
---|
271 | |
---|
272 | void Wifi_CopyMacAddr(volatile void * dest, volatile void * src) { |
---|
273 | ((u16 *)dest)[0]=((u16 *)src)[0]; |
---|
274 | ((u16 *)dest)[1]=((u16 *)src)[1]; |
---|
275 | ((u16 *)dest)[2]=((u16 *)src)[2]; |
---|
276 | } |
---|
277 | |
---|
278 | int Wifi_CmpMacAddr(volatile void * mac1,volatile void * mac2) { |
---|
279 | return (((u16 *)mac1)[0]==((u16 *)mac2)[0]) && (((u16 *)mac1)[1]==((u16 *)mac2)[1]) && (((u16 *)mac1)[2]==((u16 *)mac2)[2]); |
---|
280 | } |
---|
281 | |
---|
282 | |
---|
283 | |
---|
284 | u32 Wifi_TxBufferWordsAvailable(void) { |
---|
285 | s32 size=WifiData->txbufIn-WifiData->txbufOut-1; |
---|
286 | if(size<0) size += WIFI_TXBUFFER_SIZE/2; |
---|
287 | return size; |
---|
288 | } |
---|
289 | void Wifi_TxBufferWrite(s32 start, s32 len, u16 * data) { |
---|
290 | int writelen; |
---|
291 | while(len>0) { |
---|
292 | writelen=len; |
---|
293 | if(writelen>(WIFI_TXBUFFER_SIZE/2)-start) writelen=(WIFI_TXBUFFER_SIZE/2)-start; |
---|
294 | len-=writelen; |
---|
295 | while(writelen) { |
---|
296 | WifiData->txbufData[start++]=*(data++); |
---|
297 | writelen--; |
---|
298 | } |
---|
299 | start=0; |
---|
300 | } |
---|
301 | } |
---|
302 | |
---|
303 | int Wifi_RxRawReadPacket(s32 packetID, s32 readlength, u16 * data) { |
---|
304 | int readlen,read_data; |
---|
305 | readlength= (readlength+1)/2; |
---|
306 | read_data=0; |
---|
307 | while(readlength>0) { |
---|
308 | readlen=readlength; |
---|
309 | if(readlen>(WIFI_RXBUFFER_SIZE/2)-packetID) readlen=(WIFI_RXBUFFER_SIZE/2)-packetID; |
---|
310 | readlength-=readlen; |
---|
311 | read_data+=readlen; |
---|
312 | while(readlen>0) { |
---|
313 | *(data++) = WifiData->rxbufData[packetID++]; |
---|
314 | readlen--; |
---|
315 | } |
---|
316 | packetID=0; |
---|
317 | } |
---|
318 | return read_data; |
---|
319 | } |
---|
320 | |
---|
321 | u16 Wifi_RxReadOffset(s32 base, s32 offset) { |
---|
322 | base+=offset; |
---|
323 | if(base>=(WIFI_RXBUFFER_SIZE/2)) base -= (WIFI_RXBUFFER_SIZE/2); |
---|
324 | return WifiData->rxbufData[base]; |
---|
325 | } |
---|
326 | |
---|
327 | // datalen = size of packet from beginning of 802.11 header to end, but not including CRC. |
---|
328 | int Wifi_RawTxFrame(u16 datalen, u16 rate, u16 * data) { |
---|
329 | Wifi_TxHeader txh; |
---|
330 | int sizeneeded; |
---|
331 | int base; |
---|
332 | sizeneeded=((datalen+12+4+3)/4)*2; |
---|
333 | if(sizeneeded>Wifi_TxBufferWordsAvailable()) {WifiData->stats[WSTAT_TXQUEUEDREJECTED]++; return -1; } |
---|
334 | txh.tx_rate=rate; |
---|
335 | txh.tx_length=datalen+4; |
---|
336 | base = WifiData->txbufOut; |
---|
337 | Wifi_TxBufferWrite(base,6,(u16 *)&txh); |
---|
338 | base += 6; |
---|
339 | if(base>=(WIFI_TXBUFFER_SIZE/2)) base -= WIFI_TXBUFFER_SIZE/2; |
---|
340 | Wifi_TxBufferWrite(base,((datalen+3)/4)*2,data); |
---|
341 | base += ((datalen+3)/4)*2; |
---|
342 | if(base>=(WIFI_TXBUFFER_SIZE/2)) base -= WIFI_TXBUFFER_SIZE/2; |
---|
343 | WifiData->txbufOut=base; |
---|
344 | WifiData->stats[WSTAT_TXQUEUEDPACKETS]++; |
---|
345 | WifiData->stats[WSTAT_TXQUEUEDBYTES]+=sizeneeded; |
---|
346 | if(synchandler) synchandler(); |
---|
347 | return 0; |
---|
348 | } |
---|
349 | |
---|
350 | |
---|
351 | void Wifi_RawSetPacketHandler(WifiPacketHandler wphfunc) { |
---|
352 | packethandler=wphfunc; |
---|
353 | } |
---|
354 | void Wifi_SetSyncHandler(WifiSyncHandler wshfunc) { |
---|
355 | synchandler=wshfunc; |
---|
356 | } |
---|
357 | |
---|
358 | void Wifi_DisableWifi() { |
---|
359 | WifiData->reqMode=WIFIMODE_DISABLED; |
---|
360 | WifiData->reqReqFlags &= ~WFLAG_REQ_APCONNECT; |
---|
361 | } |
---|
362 | void Wifi_EnableWifi() { |
---|
363 | WifiData->reqMode=WIFIMODE_NORMAL; |
---|
364 | WifiData->reqReqFlags &= ~WFLAG_REQ_APCONNECT; |
---|
365 | } |
---|
366 | void Wifi_SetPromiscuousMode(int enable) { |
---|
367 | if(enable) WifiData->reqReqFlags |= WFLAG_REQ_PROMISC; |
---|
368 | else WifiData->reqReqFlags &= ~WFLAG_REQ_PROMISC; |
---|
369 | } |
---|
370 | |
---|
371 | void Wifi_ScanMode() { |
---|
372 | WifiData->reqMode=WIFIMODE_SCAN; |
---|
373 | WifiData->reqReqFlags &= ~WFLAG_REQ_APCONNECT; |
---|
374 | } |
---|
375 | void Wifi_SetChannel(int channel) { |
---|
376 | if(channel<1 || channel>13) return; |
---|
377 | if(WifiData->reqMode==WIFIMODE_NORMAL || WifiData->reqMode==WIFIMODE_SCAN) { |
---|
378 | WifiData->reqChannel=channel; |
---|
379 | } |
---|
380 | } |
---|
381 | |
---|
382 | |
---|
383 | int Wifi_GetNumAP() { |
---|
384 | int i,j; |
---|
385 | j=0; |
---|
386 | for(i=0;i<WIFI_MAX_AP;i++) if(WifiData->aplist[i].flags&WFLAG_APDATA_ACTIVE) j++; |
---|
387 | return j; |
---|
388 | } |
---|
389 | |
---|
390 | int Wifi_GetAPData(int apnum, Wifi_AccessPoint * apdata) { |
---|
391 | int i,j; |
---|
392 | if(!apdata) return WIFI_RETURN_PARAMERROR; |
---|
393 | j=0; |
---|
394 | for(i=0;i<WIFI_MAX_AP;i++){ |
---|
395 | if(WifiData->aplist[i].flags&WFLAG_APDATA_ACTIVE) { |
---|
396 | if(j==apnum) { |
---|
397 | while(Spinlock_Acquire(WifiData->aplist[i])!=SPINLOCK_OK); |
---|
398 | { |
---|
399 | // additionally calculate average RSSI here |
---|
400 | WifiData->aplist[i].rssi=0; |
---|
401 | for(j=0;j<8;j++) { |
---|
402 | WifiData->aplist[i].rssi+=WifiData->aplist[i].rssi_past[j]; |
---|
403 | } |
---|
404 | WifiData->aplist[i].rssi = WifiData->aplist[i].rssi >> 3; |
---|
405 | *apdata = WifiData->aplist[i]; // yay for struct copy! |
---|
406 | Spinlock_Release(WifiData->aplist[i]); |
---|
407 | return WIFI_RETURN_OK; |
---|
408 | } |
---|
409 | } |
---|
410 | j++; |
---|
411 | } |
---|
412 | } |
---|
413 | return WIFI_RETURN_ERROR; |
---|
414 | } |
---|
415 | |
---|
416 | int Wifi_FindMatchingAP(int numaps, Wifi_AccessPoint * apdata, Wifi_AccessPoint * match_dest) { |
---|
417 | int ap_match,i,j,n; |
---|
418 | Wifi_AccessPoint ap; |
---|
419 | u16 macaddrzero[3] = {0,0,0}; // check for empty mac addr |
---|
420 | ap_match=-1; |
---|
421 | for(i=0;i<Wifi_GetNumAP();i++){ |
---|
422 | Wifi_GetAPData(i,&ap); |
---|
423 | for(j=0;j<numaps;j++) { |
---|
424 | if(apdata[j].ssid_len>32 || ((signed char)apdata[j].ssid_len)<0) continue; |
---|
425 | if(apdata[j].ssid_len>0) { // compare SSIDs |
---|
426 | if(apdata[j].ssid_len!=ap.ssid_len) continue; |
---|
427 | for(n=0;n<apdata[j].ssid_len;n++) { |
---|
428 | if(apdata[j].ssid[n]!=ap.ssid[n]) break; |
---|
429 | } |
---|
430 | if(n!=apdata[j].ssid_len) continue; |
---|
431 | } |
---|
432 | if(!Wifi_CmpMacAddr(apdata[j].macaddr,macaddrzero)) { // compare mac addr |
---|
433 | if(!Wifi_CmpMacAddr(apdata[j].macaddr,ap.macaddr)) continue; |
---|
434 | } |
---|
435 | if(apdata[j].channel!=0) { // compare channels |
---|
436 | if(apdata[j].channel!=ap.channel) continue; |
---|
437 | } |
---|
438 | if(j<ap_match || ap_match==-1) { |
---|
439 | ap_match=j; |
---|
440 | if(match_dest) *match_dest = ap; |
---|
441 | } |
---|
442 | if(ap_match==0) return ap_match; |
---|
443 | } |
---|
444 | } |
---|
445 | return ap_match; |
---|
446 | } |
---|
447 | |
---|
448 | int wifi_connect_state = 0; // -1==error, 0==searching, 1==associating, 2==dhcp'ing, 3==done, 4=searching wfc data |
---|
449 | Wifi_AccessPoint wifi_connect_point; |
---|
450 | int Wifi_ConnectAP(Wifi_AccessPoint * apdata, int wepmode, int wepkeyid, u8 * wepkey) { |
---|
451 | int i; |
---|
452 | Wifi_AccessPoint ap; |
---|
453 | wifi_connect_state=-1; |
---|
454 | if(!apdata) return -1; |
---|
455 | if(((signed char)apdata->ssid_len)<0 || apdata->ssid_len>32) return -1; |
---|
456 | |
---|
457 | Wifi_DisconnectAP(); |
---|
458 | |
---|
459 | wifi_connect_state=0; |
---|
460 | WifiData->wepmode9=wepmode; // copy data |
---|
461 | WifiData->wepkeyid9=wepkeyid; |
---|
462 | for(i=0;i<20;i++) { |
---|
463 | WifiData->wepkey9[i]=wepkey[i]; |
---|
464 | } |
---|
465 | |
---|
466 | |
---|
467 | i=Wifi_FindMatchingAP(1,apdata,&ap); |
---|
468 | if(i==0) { |
---|
469 | Wifi_CopyMacAddr(WifiData->bssid9, ap.bssid); |
---|
470 | Wifi_CopyMacAddr(WifiData->apmac9, ap.bssid); |
---|
471 | WifiData->ssid9[0]=ap.ssid_len; |
---|
472 | for(i=0;i<32;i++) { |
---|
473 | WifiData->ssid9[i+1]=ap.ssid[i]; |
---|
474 | } |
---|
475 | WifiData->apchannel9=ap.channel; |
---|
476 | for(i=0;i<16;i++) WifiData->baserates9[i]=ap.base_rates[i]; |
---|
477 | WifiData->reqMode=WIFIMODE_NORMAL; |
---|
478 | WifiData->reqReqFlags |= WFLAG_REQ_APCONNECT | WFLAG_REQ_APCOPYVALUES; |
---|
479 | wifi_connect_state=1; |
---|
480 | } else { |
---|
481 | WifiData->reqMode=WIFIMODE_SCAN; |
---|
482 | wifi_connect_point = *apdata; |
---|
483 | } |
---|
484 | return 0; |
---|
485 | } |
---|
486 | void Wifi_AutoConnect(void) { |
---|
487 | if(!(WifiData->wfc_enable[0]&0x80)) { |
---|
488 | wifi_connect_state=ASSOCSTATUS_CANNOTCONNECT; |
---|
489 | } else { |
---|
490 | wifi_connect_state=4; |
---|
491 | WifiData->reqMode=WIFIMODE_SCAN; |
---|
492 | } |
---|
493 | } |
---|
494 | |
---|
495 | static |
---|
496 | void sgIP_DNS_Record_Localhost(void) |
---|
497 | { |
---|
498 | sgIP_DNS_Record *rec; |
---|
499 | const unsigned char * resdata_c = (unsigned char *)&(wifi_hw->ipaddr); |
---|
500 | rec = sgIP_DNS_GetUnusedRecord(); |
---|
501 | rec->flags=SGIP_DNS_FLAG_ACTIVE | SGIP_DNS_FLAG_BUSY; |
---|
502 | |
---|
503 | rec->addrlen = 4; |
---|
504 | rec->numalias = 1; |
---|
505 | gethostname(rec->aliases[0], 256); |
---|
506 | gethostname(rec->name, 256); |
---|
507 | rec->numaddr = 1; |
---|
508 | rec->addrdata[0] = resdata_c[0]; |
---|
509 | rec->addrdata[1] = resdata_c[1]; |
---|
510 | rec->addrdata[2] = resdata_c[2]; |
---|
511 | rec->addrdata[3] = resdata_c[3]; |
---|
512 | rec->addrclass = AF_INET; |
---|
513 | rec->TTL = 0; |
---|
514 | |
---|
515 | rec->flags=SGIP_DNS_FLAG_ACTIVE | SGIP_DNS_FLAG_BUSY|SGIP_DNS_FLAG_RESOLVED; |
---|
516 | } |
---|
517 | |
---|
518 | int Wifi_AssocStatus() { |
---|
519 | switch(wifi_connect_state) { |
---|
520 | case -1: // error |
---|
521 | return ASSOCSTATUS_CANNOTCONNECT; |
---|
522 | case 0: // searching |
---|
523 | { |
---|
524 | int i; |
---|
525 | Wifi_AccessPoint ap; |
---|
526 | i=Wifi_FindMatchingAP(1,&wifi_connect_point,&ap); |
---|
527 | if(i==0) { |
---|
528 | Wifi_CopyMacAddr(WifiData->bssid9, ap.bssid); |
---|
529 | Wifi_CopyMacAddr(WifiData->apmac9, ap.bssid); |
---|
530 | WifiData->ssid9[0]=ap.ssid_len; |
---|
531 | for(i=0;i<32;i++) { |
---|
532 | WifiData->ssid9[i+1]=ap.ssid[i]; |
---|
533 | } |
---|
534 | WifiData->apchannel9=ap.channel; |
---|
535 | for(i=0;i<16;i++) WifiData->baserates9[i]=ap.base_rates[i]; |
---|
536 | WifiData->reqMode=WIFIMODE_NORMAL; |
---|
537 | WifiData->reqReqFlags |= WFLAG_REQ_APCONNECT | WFLAG_REQ_APCOPYVALUES; |
---|
538 | wifi_connect_state=1; |
---|
539 | } |
---|
540 | } |
---|
541 | return ASSOCSTATUS_SEARCHING; |
---|
542 | case 1: // associating |
---|
543 | switch(WifiData->curMode) { |
---|
544 | case WIFIMODE_DISABLED: |
---|
545 | case WIFIMODE_NORMAL: |
---|
546 | case WIFIMODE_DISASSOCIATE: |
---|
547 | return ASSOCSTATUS_DISCONNECTED; |
---|
548 | case WIFIMODE_SCAN: |
---|
549 | if(WifiData->reqReqFlags&WFLAG_REQ_APCONNECT) return ASSOCSTATUS_AUTHENTICATING; |
---|
550 | return ASSOCSTATUS_DISCONNECTED; |
---|
551 | case WIFIMODE_ASSOCIATE: |
---|
552 | switch(WifiData->authlevel) { |
---|
553 | case WIFI_AUTHLEVEL_DISCONNECTED: |
---|
554 | return ASSOCSTATUS_AUTHENTICATING; |
---|
555 | case WIFI_AUTHLEVEL_AUTHENTICATED: |
---|
556 | case WIFI_AUTHLEVEL_DEASSOCIATED: |
---|
557 | return ASSOCSTATUS_ASSOCIATING; |
---|
558 | case WIFI_AUTHLEVEL_ASSOCIATED: |
---|
559 | #ifdef WIFI_USE_TCP_SGIP |
---|
560 | if(wifi_hw) { |
---|
561 | if(!(wifi_hw->ipaddr)) { |
---|
562 | sgIP_DHCP_Start(wifi_hw,wifi_hw->dns[0]==0); |
---|
563 | wifi_connect_state=2; |
---|
564 | return ASSOCSTATUS_ACQUIRINGDHCP; |
---|
565 | } |
---|
566 | } |
---|
567 | sgIP_ARP_SendGratARP(wifi_hw); |
---|
568 | #endif |
---|
569 | wifi_connect_state=3; |
---|
570 | WifiData->flags9|=WFLAG_ARM9_NETREADY; |
---|
571 | return ASSOCSTATUS_ASSOCIATED; |
---|
572 | } |
---|
573 | break; |
---|
574 | case WIFIMODE_ASSOCIATED: |
---|
575 | #ifdef WIFI_USE_TCP_SGIP |
---|
576 | if(wifi_hw) { |
---|
577 | if(!(wifi_hw->ipaddr)) { |
---|
578 | sgIP_DHCP_Start(wifi_hw,wifi_hw->dns[0]==0); |
---|
579 | wifi_connect_state=2; |
---|
580 | return ASSOCSTATUS_ACQUIRINGDHCP; |
---|
581 | } |
---|
582 | } |
---|
583 | sgIP_ARP_SendGratARP(wifi_hw); |
---|
584 | #endif |
---|
585 | wifi_connect_state=3; |
---|
586 | WifiData->flags9|=WFLAG_ARM9_NETREADY; |
---|
587 | return ASSOCSTATUS_ASSOCIATED; |
---|
588 | case WIFIMODE_CANNOTASSOCIATE: |
---|
589 | return ASSOCSTATUS_CANNOTCONNECT; |
---|
590 | } |
---|
591 | return ASSOCSTATUS_DISCONNECTED; |
---|
592 | case 2: // dhcp'ing |
---|
593 | #ifdef WIFI_USE_TCP_SGIP |
---|
594 | { |
---|
595 | int i; |
---|
596 | i=sgIP_DHCP_Update(); |
---|
597 | if(i!=SGIP_DHCP_STATUS_WORKING) { |
---|
598 | switch(i) { |
---|
599 | case SGIP_DHCP_STATUS_SUCCESS: |
---|
600 | wifi_connect_state=3; |
---|
601 | WifiData->flags9|=WFLAG_ARM9_NETREADY; |
---|
602 | sgIP_ARP_SendGratARP(wifi_hw); |
---|
603 | sgIP_DNS_Record_Localhost(); |
---|
604 | return ASSOCSTATUS_ASSOCIATED; |
---|
605 | default: |
---|
606 | case SGIP_DHCP_STATUS_IDLE: |
---|
607 | case SGIP_DHCP_STATUS_FAILED: |
---|
608 | Wifi_DisconnectAP(); |
---|
609 | wifi_connect_state=-1; |
---|
610 | return ASSOCSTATUS_CANNOTCONNECT; |
---|
611 | |
---|
612 | } |
---|
613 | } |
---|
614 | } |
---|
615 | #else |
---|
616 | // should never get here (dhcp state) without sgIP! |
---|
617 | Wifi_DisconnectAP(); |
---|
618 | wifi_connect_state=-1; |
---|
619 | return ASSOCSTATUS_CANNOTCONNECT; |
---|
620 | #endif |
---|
621 | return ASSOCSTATUS_ACQUIRINGDHCP; |
---|
622 | case 3: // connected! |
---|
623 | return ASSOCSTATUS_ASSOCIATED; |
---|
624 | case 4: // search nintendo WFC data for a suitable AP |
---|
625 | { |
---|
626 | int n,i; |
---|
627 | for(n=0;n<3;n++) if(!(WifiData->wfc_enable[n]&0x80)) break; |
---|
628 | Wifi_AccessPoint ap; |
---|
629 | n=Wifi_FindMatchingAP(n,WifiData->wfc_ap,&ap); |
---|
630 | if(n!=-1) { |
---|
631 | #ifdef WIFI_USE_TCP_SGIP |
---|
632 | Wifi_SetIP(WifiData->wfc_config[n][0],WifiData->wfc_config[n][1],WifiData->wfc_config[n][2],WifiData->wfc_config[n][3],WifiData->wfc_config[n][4]); |
---|
633 | #endif |
---|
634 | WifiData->wepmode9=WifiData->wfc_enable[n]&0x03; // copy data |
---|
635 | WifiData->wepkeyid9=(WifiData->wfc_enable[n]>>4)&7; |
---|
636 | for(i=0;i<16;i++) { |
---|
637 | WifiData->wepkey9[i]=WifiData->wfc_wepkey[n][i]; |
---|
638 | } |
---|
639 | |
---|
640 | Wifi_CopyMacAddr(WifiData->bssid9, ap.bssid); |
---|
641 | Wifi_CopyMacAddr(WifiData->apmac9, ap.bssid); |
---|
642 | WifiData->ssid9[0]=ap.ssid_len; |
---|
643 | for(i=0;i<32;i++) { |
---|
644 | WifiData->ssid9[i+1]=ap.ssid[i]; |
---|
645 | } |
---|
646 | WifiData->apchannel9=ap.channel; |
---|
647 | for(i=0;i<16;i++) WifiData->baserates9[i]=ap.base_rates[i]; |
---|
648 | WifiData->reqMode=WIFIMODE_NORMAL; |
---|
649 | WifiData->reqReqFlags |= WFLAG_REQ_APCONNECT | WFLAG_REQ_APCOPYVALUES; |
---|
650 | wifi_connect_state=1; |
---|
651 | return ASSOCSTATUS_SEARCHING; |
---|
652 | |
---|
653 | } |
---|
654 | |
---|
655 | } |
---|
656 | return ASSOCSTATUS_SEARCHING; |
---|
657 | } |
---|
658 | return ASSOCSTATUS_CANNOTCONNECT; |
---|
659 | } |
---|
660 | |
---|
661 | |
---|
662 | int Wifi_DisconnectAP() { |
---|
663 | WifiData->reqMode=WIFIMODE_NORMAL; |
---|
664 | WifiData->reqReqFlags &= ~WFLAG_REQ_APCONNECT; |
---|
665 | WifiData->flags9&=~WFLAG_ARM9_NETREADY; |
---|
666 | |
---|
667 | wifi_connect_state=-1; |
---|
668 | return 0; |
---|
669 | } |
---|
670 | |
---|
671 | |
---|
672 | #ifdef WIFI_USE_TCP_SGIP |
---|
673 | |
---|
674 | |
---|
675 | |
---|
676 | int Wifi_TransmitFunction(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb) { |
---|
677 | // convert ethernet frame into wireless frame and output. |
---|
678 | // ethernet header: 6byte dest, 6byte src, 2byte protocol_id |
---|
679 | // assumes individual pbuf len is >=14 bytes, it's pretty likely ;) - also hopes pbuf len is a multiple of 2 :| |
---|
680 | int base,framelen, hdrlen, writelen; |
---|
681 | int copytotal, copyexpect; |
---|
682 | u16 framehdr[6+12+2]; |
---|
683 | sgIP_memblock * t; |
---|
684 | framelen=mb->totallength-14+8 + (WifiData->wepmode7?4:0); |
---|
685 | |
---|
686 | if(!(WifiData->flags9&WFLAG_ARM9_NETUP)) { |
---|
687 | SGIP_DEBUG_MESSAGE(("Transmit:err_netdown")); |
---|
688 | sgIP_memblock_free(mb); |
---|
689 | return 0; //? |
---|
690 | } |
---|
691 | if(framelen+40>Wifi_TxBufferWordsAvailable()*2) { // error, can't send this much! |
---|
692 | SGIP_DEBUG_MESSAGE(("Transmit:err_space")); |
---|
693 | sgIP_memblock_free(mb); |
---|
694 | return 0; //? |
---|
695 | } |
---|
696 | |
---|
697 | ethhdr_print('T',mb->datastart); |
---|
698 | framehdr[0]=0; |
---|
699 | framehdr[1]=0; |
---|
700 | framehdr[2]=0; |
---|
701 | framehdr[3]=0; |
---|
702 | framehdr[4]=0; // rate, will be filled in by the arm7. |
---|
703 | hdrlen=18; |
---|
704 | framehdr[7]=0; |
---|
705 | |
---|
706 | if(WifiData->curReqFlags&WFLAG_REQ_APADHOC) { // adhoc mode |
---|
707 | framehdr[6]=0x0008; |
---|
708 | Wifi_CopyMacAddr(framehdr+14,WifiData->bssid7); |
---|
709 | Wifi_CopyMacAddr(framehdr+11,WifiData->MacAddr); |
---|
710 | Wifi_CopyMacAddr(framehdr+8,((u8 *)mb->datastart)); |
---|
711 | } else { |
---|
712 | framehdr[6]=0x0108; |
---|
713 | Wifi_CopyMacAddr(framehdr+8,WifiData->bssid7); |
---|
714 | Wifi_CopyMacAddr(framehdr+11,WifiData->MacAddr); |
---|
715 | Wifi_CopyMacAddr(framehdr+14,((u8 *)mb->datastart)); |
---|
716 | } |
---|
717 | if(WifiData->wepmode7) { framehdr[6] |=0x4000; hdrlen=20; } |
---|
718 | framehdr[17] = 0; |
---|
719 | framehdr[18] = 0; // wep IV, will be filled in if needed on the arm7 side. |
---|
720 | framehdr[19] = 0; |
---|
721 | |
---|
722 | framehdr[5]=framelen+hdrlen*2-12+4; |
---|
723 | copyexpect= ((framelen+hdrlen*2-12+4) +12 -4 +1)/2; |
---|
724 | copytotal=0; |
---|
725 | |
---|
726 | WifiData->stats[WSTAT_TXQUEUEDPACKETS]++; |
---|
727 | WifiData->stats[WSTAT_TXQUEUEDBYTES]+=framelen+hdrlen*2; |
---|
728 | |
---|
729 | base = WifiData->txbufOut; |
---|
730 | Wifi_TxBufferWrite(base,hdrlen,framehdr); |
---|
731 | base += hdrlen; |
---|
732 | copytotal+=hdrlen; |
---|
733 | if(base>=(WIFI_TXBUFFER_SIZE/2)) base -= WIFI_TXBUFFER_SIZE/2; |
---|
734 | |
---|
735 | // add LLC header |
---|
736 | framehdr[0]=0xAAAA; |
---|
737 | framehdr[1]=0x0003; |
---|
738 | framehdr[2]=0x0000; |
---|
739 | framehdr[3]=((u16 *)mb->datastart)[6]; // frame type |
---|
740 | |
---|
741 | Wifi_TxBufferWrite(base,4,framehdr); |
---|
742 | base += 4; |
---|
743 | copytotal+=4; |
---|
744 | if(base>=(WIFI_TXBUFFER_SIZE/2)) base -= WIFI_TXBUFFER_SIZE/2; |
---|
745 | |
---|
746 | t=mb; |
---|
747 | writelen=(mb->thislength-14); |
---|
748 | if(writelen) { |
---|
749 | Wifi_TxBufferWrite(base,(writelen+1)/2,((u16 *)mb->datastart)+7); |
---|
750 | base+=(writelen+1)/2; |
---|
751 | copytotal+=(writelen+1)/2; |
---|
752 | if(base>=(WIFI_TXBUFFER_SIZE/2)) base -= WIFI_TXBUFFER_SIZE/2; |
---|
753 | } |
---|
754 | while(mb->next) { |
---|
755 | mb=mb->next; |
---|
756 | writelen=mb->thislength; |
---|
757 | Wifi_TxBufferWrite(base,(writelen+1)/2,((u16 *)mb->datastart)); |
---|
758 | base+=(writelen+1)/2; |
---|
759 | copytotal+=(writelen+1)/2; |
---|
760 | if(base>=(WIFI_TXBUFFER_SIZE/2)) base -= WIFI_TXBUFFER_SIZE/2; |
---|
761 | } |
---|
762 | if(WifiData->wepmode7) { // add required extra bytes |
---|
763 | base+=2; |
---|
764 | copytotal+=2; |
---|
765 | if(base>=(WIFI_TXBUFFER_SIZE/2)) base -= WIFI_TXBUFFER_SIZE/2; |
---|
766 | } |
---|
767 | WifiData->txbufOut=base; // update fifo out pos, done sending packet. |
---|
768 | |
---|
769 | sgIP_memblock_free(t); // free packet, as we're the last stop on this chain. |
---|
770 | |
---|
771 | if(copytotal!=copyexpect) { |
---|
772 | SGIP_DEBUG_MESSAGE(("Tx exp:%i que:%i",copyexpect,copytotal)); |
---|
773 | } |
---|
774 | if(synchandler) synchandler(); |
---|
775 | return 0; |
---|
776 | } |
---|
777 | |
---|
778 | int Wifi_Interface_Init(sgIP_Hub_HWInterface * hw) { |
---|
779 | hw->MTU=2300; |
---|
780 | hw->ipaddr=(192)|(168<<8)|(1<<16)|(151<<24); |
---|
781 | hw->snmask=0x00FFFFFF; |
---|
782 | hw->gateway=(192)|(168<<8)|(1<<16)|(1<<24); |
---|
783 | hw->dns[0]=(192)|(168<<8)|(1<<16)|(1<<24); |
---|
784 | hw->hwaddrlen=6; |
---|
785 | Wifi_CopyMacAddr(hw->hwaddr,WifiData->MacAddr); |
---|
786 | hw->userdata=0; |
---|
787 | return 0; |
---|
788 | } |
---|
789 | |
---|
790 | void Wifi_Timer(int num_ms) { |
---|
791 | Wifi_Update(); |
---|
792 | sgIP_Timer(num_ms); |
---|
793 | } |
---|
794 | |
---|
795 | #endif |
---|
796 | |
---|
797 | unsigned long Wifi_Init(int initflags) { |
---|
798 | erasemem(&Wifi_Data_Struct,sizeof(Wifi_Data_Struct)); |
---|
799 | DC_FlushAll(); |
---|
800 | WifiData = (Wifi_MainStruct *) (((u32)&Wifi_Data_Struct)| 0x00400000); // should prevent the cache from eating us alive. |
---|
801 | |
---|
802 | #ifdef WIFI_USE_TCP_SGIP |
---|
803 | switch(initflags & WIFIINIT_OPTION_HEAPMASK) { |
---|
804 | case WIFIINIT_OPTION_USEHEAP_128: |
---|
805 | wHeapAllocInit(128*1024); |
---|
806 | break; |
---|
807 | case WIFIINIT_OPTION_USEHEAP_64: |
---|
808 | wHeapAllocInit(64*1024); |
---|
809 | break; |
---|
810 | case WIFIINIT_OPTION_USEHEAP_256: |
---|
811 | wHeapAllocInit(256*1024); |
---|
812 | break; |
---|
813 | case WIFIINIT_OPTION_USEHEAP_512: |
---|
814 | wHeapAllocInit(512*1024); |
---|
815 | break; |
---|
816 | case WIFIINIT_OPTION_USECUSTOMALLOC: |
---|
817 | break; |
---|
818 | } |
---|
819 | sgIP_Init(); |
---|
820 | |
---|
821 | #endif |
---|
822 | |
---|
823 | WifiData->flags9 = WFLAG_ARM9_ACTIVE | (initflags & WFLAG_ARM9_INITFLAGMASK) ; |
---|
824 | return (u32) &Wifi_Data_Struct; |
---|
825 | } |
---|
826 | |
---|
827 | int Wifi_CheckInit() { |
---|
828 | if(!WifiData) return 0; |
---|
829 | return ((WifiData->flags7 & WFLAG_ARM7_ACTIVE) && (WifiData->flags9 & WFLAG_ARM9_ARM7READY)); |
---|
830 | } |
---|
831 | |
---|
832 | |
---|
833 | void Wifi_Update() { |
---|
834 | int cnt; |
---|
835 | int base, base2, len, fulllen; |
---|
836 | if(!WifiData) return; |
---|
837 | |
---|
838 | #ifdef WIFI_USE_TCP_SGIP |
---|
839 | |
---|
840 | if(!(WifiData->flags9&WFLAG_ARM9_ARM7READY)) { |
---|
841 | if(WifiData->flags7 & WFLAG_ARM7_ACTIVE) { |
---|
842 | WifiData->flags9 |=WFLAG_ARM9_ARM7READY; |
---|
843 | // add network interface. |
---|
844 | wifi_hw = sgIP_Hub_AddHardwareInterface(&Wifi_TransmitFunction,&Wifi_Interface_Init); |
---|
845 | sgIP_timems=WifiData->random; //hacky! but it should work just fine :) |
---|
846 | } |
---|
847 | } |
---|
848 | if(WifiData->authlevel!=WIFI_AUTHLEVEL_ASSOCIATED && WifiData->flags9&WFLAG_ARM9_NETUP) { |
---|
849 | WifiData->flags9 &= ~(WFLAG_ARM9_NETUP); |
---|
850 | } else if(WifiData->authlevel==WIFI_AUTHLEVEL_ASSOCIATED && !(WifiData->flags9&WFLAG_ARM9_NETUP)) { |
---|
851 | WifiData->flags9 |= (WFLAG_ARM9_NETUP); |
---|
852 | } |
---|
853 | |
---|
854 | #endif |
---|
855 | |
---|
856 | // check for received packets, forward to whatever wants them. |
---|
857 | cnt=0; |
---|
858 | while(WifiData->rxbufIn!=WifiData->rxbufOut) { |
---|
859 | base = WifiData->rxbufIn; |
---|
860 | len=Wifi_RxReadOffset(base,4); |
---|
861 | fulllen=((len+3)&(~3))+12; |
---|
862 | #ifdef WIFI_USE_TCP_SGIP |
---|
863 | // Do lwIP interfacing for rx here |
---|
864 | if((Wifi_RxReadOffset(base,6)&0x01CF)==0x0008) // if it is a non-null data packet coming from the AP (toDS==0) |
---|
865 | { |
---|
866 | u16 framehdr[6+12+2+4]; |
---|
867 | sgIP_memblock * mb; |
---|
868 | int hdrlen; |
---|
869 | base2=base; |
---|
870 | Wifi_RxRawReadPacket(base,22*2,framehdr); |
---|
871 | |
---|
872 | // ethhdr_print('!',framehdr+8); |
---|
873 | if((framehdr[8]==((u16 *)WifiData->MacAddr)[0] && framehdr[9]==((u16 *)WifiData->MacAddr)[1] && framehdr[10]==((u16 *)WifiData->MacAddr)[2]) || |
---|
874 | (framehdr[8]==0xFFFF && framehdr[9]==0xFFFF && framehdr[10]==0xFFFF)) { |
---|
875 | // destination matches our mac address, or the broadcast address. |
---|
876 | //if(framehdr[6]&0x4000) { // wep enabled (when receiving WEP packets, the IV is stripped for us! how nice :| |
---|
877 | // base2+=24; hdrlen=28; // base2+=[wifi hdr 12byte]+[802 header hdrlen]+[slip hdr 8byte] |
---|
878 | //} else { |
---|
879 | base2+=22; hdrlen=24; |
---|
880 | //} |
---|
881 | // SGIP_DEBUG_MESSAGE(("%04X %04X %04X %04X %04X",Wifi_RxReadOffset(base2-8,0),Wifi_RxReadOffset(base2-7,0),Wifi_RxReadOffset(base2-6,0),Wifi_RxReadOffset(base2-5,0),Wifi_RxReadOffset(base2-4,0))); |
---|
882 | // check for LLC/SLIP header... |
---|
883 | if(Wifi_RxReadOffset(base2-4,0)==0xAAAA && Wifi_RxReadOffset(base2-4,1)==0x0003 && Wifi_RxReadOffset(base2-4,2)==0) { |
---|
884 | mb = sgIP_memblock_allocHW(14,len-8-hdrlen); |
---|
885 | if(mb) { |
---|
886 | if(base2>=(WIFI_RXBUFFER_SIZE/2)) base2-=(WIFI_RXBUFFER_SIZE/2); |
---|
887 | Wifi_RxRawReadPacket(base2,(len-8-hdrlen)&(~1),((u16 *)mb->datastart)+7); |
---|
888 | if(len&1) ((u8 *)mb->datastart)[len+14-1-8-hdrlen]=Wifi_RxReadOffset(base2,((len-8-hdrlen)/2))&255; |
---|
889 | Wifi_CopyMacAddr(mb->datastart,framehdr+8); // copy dest |
---|
890 | if(Wifi_RxReadOffset(base,6)&0x0200) { // from DS set? |
---|
891 | Wifi_CopyMacAddr(((u8 *)mb->datastart)+6,framehdr+14); // copy src from adrs3 |
---|
892 | } else { |
---|
893 | Wifi_CopyMacAddr(((u8 *)mb->datastart)+6,framehdr+11); // copy src from adrs2 |
---|
894 | } |
---|
895 | ((u16 *)mb->datastart)[6]=framehdr[(hdrlen/2)+6+3]; // assume LLC exists and is 8 bytes. |
---|
896 | |
---|
897 | ethhdr_print('R',mb->datastart); |
---|
898 | |
---|
899 | // Done generating recieved data packet... now distribute it. |
---|
900 | sgIP_Hub_ReceiveHardwarePacket(wifi_hw,mb); |
---|
901 | |
---|
902 | } |
---|
903 | } |
---|
904 | } |
---|
905 | } |
---|
906 | |
---|
907 | #endif |
---|
908 | |
---|
909 | // check if we have a handler |
---|
910 | if(packethandler) { |
---|
911 | base2=base+6; |
---|
912 | if(base2>=(WIFI_RXBUFFER_SIZE/2)) base2-=(WIFI_RXBUFFER_SIZE/2); |
---|
913 | (*packethandler)(base2,len); |
---|
914 | } |
---|
915 | |
---|
916 | base+=fulllen/2; |
---|
917 | if(base>=(WIFI_RXBUFFER_SIZE/2)) base-=(WIFI_RXBUFFER_SIZE/2); |
---|
918 | WifiData->rxbufIn=base; |
---|
919 | |
---|
920 | if(cnt++>80) break; |
---|
921 | } |
---|
922 | } |
---|
923 | |
---|
924 | |
---|
925 | ////////////////////////////////////////////////////////////////////////// |
---|
926 | // Ip addr get/set functions |
---|
927 | #ifdef WIFI_USE_TCP_SGIP |
---|
928 | |
---|
929 | u32 Wifi_GetIP() { |
---|
930 | if(wifi_hw) return wifi_hw->ipaddr; |
---|
931 | return 0; |
---|
932 | } |
---|
933 | |
---|
934 | unsigned long Wifi_GetIPInfo(unsigned long * pGateway,unsigned long * pSnmask,unsigned long * pDns1,unsigned long * pDns2) { |
---|
935 | if(wifi_hw) { |
---|
936 | if(pGateway) *pGateway=wifi_hw->gateway; |
---|
937 | if(pSnmask) *pSnmask=wifi_hw->snmask; |
---|
938 | if(pDns1) *pDns1=wifi_hw->dns[0]; |
---|
939 | if(pDns2) *pDns2=wifi_hw->dns[1]; |
---|
940 | return wifi_hw->ipaddr; |
---|
941 | } |
---|
942 | return 0; |
---|
943 | } |
---|
944 | |
---|
945 | |
---|
946 | void Wifi_SetIP(u32 IPaddr, u32 gateway, u32 subnetmask, u32 dns1, u32 dns2) { |
---|
947 | if(wifi_hw) { |
---|
948 | SGIP_DEBUG_MESSAGE(("SetIP%08X %08X %08X",IPaddr,gateway,subnetmask)); |
---|
949 | wifi_hw->ipaddr=IPaddr; |
---|
950 | wifi_hw->gateway=gateway; |
---|
951 | wifi_hw->snmask=subnetmask; |
---|
952 | wifi_hw->dns[0]=dns1; |
---|
953 | wifi_hw->dns[1]=dns2; |
---|
954 | // reset arp cache... |
---|
955 | sgIP_ARP_FlushInterface(wifi_hw); |
---|
956 | } |
---|
957 | } |
---|
958 | |
---|
959 | void Wifi_SetDHCP(void) { |
---|
960 | |
---|
961 | |
---|
962 | } |
---|
963 | |
---|
964 | #endif |
---|
965 | |
---|
966 | |
---|
967 | int Wifi_GetData(int datatype, int bufferlen, unsigned char * buffer) { |
---|
968 | int i; |
---|
969 | if(datatype<0 || datatype>=MAX_WIFIGETDATA) return -1; |
---|
970 | switch(datatype) { |
---|
971 | case WIFIGETDATA_MACADDRESS: |
---|
972 | if(bufferlen<6 || !buffer) return -1; |
---|
973 | for(i=0;i<6;i++) { |
---|
974 | buffer[i]=WifiData->MacAddr[i]; |
---|
975 | } |
---|
976 | return 6; |
---|
977 | case WIFIGETDATA_NUMWFCAPS: |
---|
978 | for(i=0;i<3;i++) if(!(WifiData->wfc_enable[i]&0x80)) break; |
---|
979 | return i; |
---|
980 | } |
---|
981 | return -1; |
---|
982 | } |
---|
983 | |
---|
984 | u32 Wifi_GetStats(int statnum) { |
---|
985 | if(statnum<0 || statnum>=NUM_WIFI_STATS) return 0; |
---|
986 | return WifiData->stats[statnum]; |
---|
987 | } |
---|
988 | |
---|
989 | |
---|
990 | ////////////////////////////////////////////////////////////////////////// |
---|
991 | // sync functions |
---|
992 | |
---|
993 | void Wifi_Sync(void) { |
---|
994 | Wifi_Update(); |
---|
995 | } |
---|
996 | |
---|