summaryrefslogtreecommitdiffhomepage
path: root/Drivers/Hello/Hello.c
blob: 10feda487628dd264e3564ee30ae1187e2d7d0ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* -------------------------------------------

	Copyright ZKA Technologies

------------------------------------------- */

#include <DDK/KernelString.h>
#include <DDK/KernelPrint.h>
#include <DDK/KernelDev.h>

struct HelloMasterConfigHeader;
struct HelloMasterConfigHeaderInput;

struct HelloMasterConfigHeaderInput
{
	size_t							fSizeOfOutput;
	struct HelloMasterConfigHeader* fOutput;
};

/// @file Hello.c
/// @brief Zero configuration protocol, a much more better protocol for zero configuration.

#define cHMCHMaxDataLength (1024)

typedef struct HelloMasterConfigHeader
{
	int64_t fMagic;
	int64_t fVersion;
	int64_t fSourceAddress;
	size_t	fDataLength;
	wchar_t fUTF16Data[cHMCHMaxDataLength];
} __attribute__((packed)) HelloMasterConfigHeader;

#define cHMCHDeviceLen 255

static kernelDeviceRef			cDev		= nil;
static char*					cDeviceUUID = nil; // 3ed40738-c7d6-4b59-afdf-3c104b05fbf
static HelloMasterConfigHeader* cHeader		= nil;

/// @brief Link to master device to attribute DHCP lease.
static void __hello_link_device(void* a0)
{
	kernelPrintStr("Hello: linking...\r");

	if (!cDev)
	{
		// open raw network device.
		cDev = kernelOpenDevice("BROADCAST:\\");
	}

	cDev->write("+LINK", kernelStringLength("+LINK"));
	cDev->wait();

	cDev->write((void*)cDeviceUUID, kernelStringLength(cDeviceUUID));
	cDev->wait();

	if (cHeader)
	{
		kernelFree(cHeader);
		cHeader = nil;
	}

	cHeader = cDev->read(nil, sizeof(HelloMasterConfigHeader));
}

static void __hello_get_hmch(void* a0)
{
	if (a0 == nil)
		return;

	kernelPrintStr("Hello: returning header...\r");

	struct HelloMasterConfigHeaderInput* in = a0;
	in->fOutput								= cHeader;
	in->fSizeOfOutput						= sizeof(in->fOutput);
}

static void __hello_unlink_device(void* a0)
{
	kernelPrintStr("Hello: unlinking...\r");

	if (cDev)
	{
		cDev->write("+UNLINK", kernelStringLength("+UNLINK"));
		cDev->wait();

		/// here is my uuid and my config header. Please disconnect me.
		cDev->write((void*)cDeviceUUID, kernelStringLength(cDeviceUUID));
		cDev->write(cHeader, sizeof(cHeader));

		cDev->wait();

		kernelCloseDevice(cDev);
		cDev = nil;
	}

	if (cDeviceUUID)
	{
		kernelFree((void*)cDeviceUUID);
		cDeviceUUID = nil;
	}

	cDev = nil;
}

int __at_enter(void)
{
	kernelPrintStr("Hello: starting up Helloconf...\r");

	cDeviceUUID = kernelAlloc(sizeof(char) * cHMCHDeviceLen);

	kernelAddSyscall(0, __hello_link_device);
	kernelAddSyscall(1, __hello_unlink_device);
	kernelAddSyscall(2, __hello_get_hmch);

	return 0;
}

int __at_exit(void)
{
	kernelPrintStr("Hello: starting up Helloconf...\r");

	// first unlink.
	__hello_unlink_device(nil);

	// then unregister syscalls.
	kernelAddSyscall(0, nil);
	kernelAddSyscall(1, nil);

	return 0;
}