melonDS/src/WifiAP.cpp

163 lines
3.8 KiB
C++
Raw Normal View History

2017-12-18 18:53:51 +00:00
/*
Copyright 2016-2017 StapleButter
This file is part of melonDS.
melonDS is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include <string.h>
#include "NDS.h"
2017-12-18 18:53:51 +00:00
#include "Wifi.h"
#include "WifiAP.h"
namespace WifiAP
{
#define AP_MAC 0x00, 0xF0, 0x77, 0x77, 0x77, 0x77
#define AP_NAME "melonAP"
const u8 APMac[6] = {AP_MAC};
#define PWRITE_8(p, v) *p++ = v;
#define PWRITE_16(p, v) *(u16*)p = v; p += 2;
#define PWRITE_32(p, v) *(u32*)p = v; p += 4;
#define PWRITE_64(p, v) *(u64*)p = v; p += 8;
#define PWRITE_MAC(p, a,b,c,d,e,f) \
*p++ = a; *p++ = b; *p++ = c; *p++ = d; *p++ = e; *p++ = f;
#define PWRITE_MAC2(p, m) \
*p++ = m[0]; *p++ = m[1]; *p++ = m[2]; *p++ = m[3]; *p++ = m[4]; *p++ = m[5];
#define PWRITE_SEQNO(p) PWRITE_16(p, SeqNo); SeqNo += 0x10;
#define PWRITE_TXH(p, len, rate) \
PWRITE_16(p, 0); \
PWRITE_16(p, 0); \
PWRITE_16(p, 0); \
PWRITE_16(p, 0); \
PWRITE_8(p, rate); \
PWRITE_8(p, 0); \
PWRITE_16(p, len);
//#define PALIGN_4(p, base) p += ((4 - ((ptrdiff_t)(p-base) & 0x3)) & 0x3);
// no idea what is the ideal padding there
// but in the case of management frames the padding shouldn't be counted as an information element
#define PLEN(p, base) (int)(ptrdiff_t)(p-base)
#define PALIGN_4(p, base) while (PLEN(p,base) & 0x3) *p++ = 0xFF;
u64 USCounter;
u16 SeqNo;
bool BeaconDue;
u8 PacketBuffer[2048];
int PacketLen;
int RXNum;
bool Init()
{
return true;
}
void DeInit()
{
}
void Reset()
{
// random starting point for the counter
USCounter = 0x428888017ULL;
SeqNo = 0x0120;
BeaconDue = false;
memset(PacketBuffer, 0, sizeof(PacketBuffer));
PacketLen = 0;
RXNum = 0;
}
void USTimer()
{
USCounter++;
u32 chk = (u32)USCounter;
if (!(chk & 0x1FFFF))
{
// send beacon every 128ms
BeaconDue = true;
}
}
int SendPacket(u8* data, int len)
{
//
}
int RecvPacket(u8* data)
{
if (BeaconDue)
{
BeaconDue = false;
// craft beacon
u8* base = data + 12;
u8* p = base;
PWRITE_16(p, 0x0080);
PWRITE_16(p, 0x0000); // duration??
PWRITE_MAC(p, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF); // recv
PWRITE_MAC2(p, APMac); // sender
PWRITE_MAC2(p, APMac); // BSSID
PWRITE_SEQNO(p);
PWRITE_64(p, USCounter);
PWRITE_16(p, 128); // beacon interval
PWRITE_16(p, 0x0021); // capability
PWRITE_8(p, 0x01); PWRITE_8(p, 0x02); PWRITE_8(p, 0x82); PWRITE_8(p, 0x84); // rates
PWRITE_8(p, 0x03); PWRITE_8(p, 0x01); PWRITE_8(p, 0x06); // current channel
PWRITE_8(p, 0x05); PWRITE_8(p, 0x04); PWRITE_8(p, 0); PWRITE_8(p, 0); PWRITE_8(p, 0); PWRITE_8(p, 0); // TIM
PWRITE_8(p, 0x00); PWRITE_8(p, strlen(AP_NAME));
memcpy(p, AP_NAME, strlen(AP_NAME)); p += strlen(AP_NAME);
PALIGN_4(p, base);
PWRITE_32(p, 0xDEADBEEF); // checksum. doesn't matter for now
int len = PLEN(p, base);
p = data;
PWRITE_TXH(p, len, 20);
/*static int zorp=0;
zorp++;
char derp[55];
sprintf(derp, "derpo%d.bin", zorp);
FILE* f = fopen(derp, "wb");
fwrite(data, len+12, 1, f);
fclose(f);*/
return len+12;
}
return 0;
}
2017-12-18 18:53:51 +00:00
}