-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathip65.h
410 lines (368 loc) · 16 KB
/
ip65.h
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
#ifndef _IP65_H
#define _IP65_H
#include <stdint.h>
#include <stdbool.h>
// Ethernet driver initialization parameter values
//
#if defined(__APPLE2__)
#define ETH_INIT_DEFAULT 3 // Apple II slot number
#else
#define ETH_INIT_DEFAULT 0 // Unused
#endif
// Initialize the IP stack
//
// This calls the individual protocol & driver initializations, so this is
// the only *_init routine that must be called by a user application,
// except for dhcp_init which must also be called if the application
// is using DHCP rather than hardcoded IP configuration.
//
// Inputs: eth_init: Ethernet driver initialization parameter
// Output: true if there was an error, false otherwise
//
bool __fastcall__ ip65_init(uint8_t eth_init);
// Access to Ethernet configuration
//
// Access to the two items below is only valid after ip65_init returned false.
//
extern uint8_t cfg_mac[6]; // MAC address of local machine
extern char eth_name[]; // Zero terminated string containing Ethernet driver name
// Error codes
//
#define IP65_ERROR_PORT_IN_USE 0x80
#define IP65_ERROR_TIMEOUT_ON_RECEIVE 0x81
#define IP65_ERROR_TRANSMIT_FAILED 0x82
#define IP65_ERROR_TRANSMISSION_REJECTED_BY_PEER 0x83
#define IP65_ERROR_NAME_TOO_LONG 0x84
#define IP65_ERROR_DEVICE_FAILURE 0x85
#define IP65_ERROR_ABORTED_BY_USER 0x86
#define IP65_ERROR_LISTENER_NOT_AVAILABLE 0x87
#define IP65_ERROR_CONNECTION_RESET_BY_PEER 0x89
#define IP65_ERROR_CONNECTION_CLOSED 0x8A
#define IP65_ERROR_MALFORMED_URL 0xA0
#define IP65_ERROR_DNS_LOOKUP_FAILED 0xA1
// Last error code
//
extern uint8_t ip65_error;
// Convert error code into a string describing the error
//
// The pointer returned is a static string, which mustn't be modified.
//
// Inputs: err_code: Error code
// Output: Zero terminated string describing the error
//
char* __fastcall__ ip65_strerror(uint8_t err_code);
// Main IP polling loop
//
// This routine should be periodically called by an application at any time
// that an inbound packet needs to be handled.
// It is 'non-blocking', i.e. it will return if there is no packet waiting to be
// handled. Any inbound packet will be handed off to the appropriate handler.
//
// Inputs: None
// Output: true if no packet was waiting or packet handling caused error, false otherwise
//
bool ip65_process(void);
// Generate a 'random' 16 bit word
//
// Entropy comes from the last ethernet frame, counters, and timer.
//
// Inputs: None
// Output: Pseudo-random 16 bit number
//
uint16_t ip65_random_word(void);
// Convert 4 octets (IP address, netmask) into a string representing a dotted quad
//
// The string is returned in a statically allocated buffer, which subsequent calls
// will overwrite.
//
// Inputs: quad: IP address
// Output: Zero terminated string containing dotted quad (e.g. "192.168.1.0")
//
char* __fastcall__ dotted_quad(uint32_t quad);
// Convert a string representing a dotted quad (IP address, netmask) into 4 octets
//
// Inputs: quad: Zero terminated string containing dotted quad (e.g. "192.168.1.0"),
// to simplify URL parsing, a ':' or '/' can also terminate the string.
// Output: IP address, 0 on error
//
uint32_t __fastcall__ parse_dotted_quad(char* quad);
// Minimal DHCP client implementation
//
// IP addresses are requested from a DHCP server (aka 'leased') but are not renewed
// or released. Although this is not correct behaviour according to the DHCP RFC,
// this works fine in practice in a typical home network environment.
//
// Inputs: None (although ip65_init should be called first)
// Output: false if IP config has been sucesfully obtained and cfg_ip, cfg_netmask,
// cfg_gateway and cfg_dns will be set per response from dhcp server.
// dhcp_server will be set to address of server that provided configuration.
// true if there was an error
//
bool dhcp_init(void);
// Access to IP configuration
//
// The five items below will be overwritten if dhcp_init is called.
//
extern uint32_t cfg_ip; // IP address of local machine
extern uint32_t cfg_netmask; // Netmask of local network
extern uint32_t cfg_gateway; // IP address of router on local network
extern uint32_t cfg_dns; // IP address of DNS server to use
extern uint32_t dhcp_server; // Address of DHCP server that config was obtained from
// Resolve a string containing a hostname (or a dotted quad) to an IP address
//
// Inputs: hostname: Zero terminated string containing either a DNS hostname
// (e.g. "host.example.com") or an address in "dotted quad"
// format (e.g. "192.168.1.0")
// Output: IP address of the hostname, 0 on error
//
uint32_t __fastcall__ dns_resolve(const char* hostname);
// Send a ping (ICMP echo request) to a remote host, and wait for a response
//
// Inputs: dest: Destination IP address
// Output: 0 if no response, otherwise time (in miliseconds) for host to respond
//
uint16_t __fastcall__ icmp_ping(uint32_t dest);
// Add a UDP listener
//
// Inputs: port: UDP port to listen on
// callback: Vector to call when UDP packet arrives on specified port
// Output: true if too may listeners already installed, false otherwise
//
bool __fastcall__ udp_add_listener(uint16_t port, void (*callback)(void));
// Remove a UDP listener
//
// Inputs: port: UDP port to stop listening on
// Output: false if handler found and removed,
// true if handler for specified port not found
//
bool __fastcall__ udp_remove_listener(uint16_t port);
// Access to received UDP packet
//
// Access to the four items below is only valid in the context of a callback
// added with udp_add_listener.
//
extern uint8_t udp_recv_buf[1476]; // Buffer with data received
uint16_t udp_recv_len(void); // Length of data received
uint32_t udp_recv_src(void); // Source IP address
uint16_t udp_recv_src_port(void); // Source port
// Send a UDP packet
//
// If the correct MAC address can't be found in the ARP cache then
// an ARP request is sent - and the UDP packet is NOT sent. The caller
// should wait a while calling ip65_process (to allow time for an ARP
// response to arrive) and then call upd_send again. This behavior
// makes sense as a UDP packet may get lost in transit at any time
// so the caller should to be prepared to resend it after a while
// anyway.
//
// Inputs: buf: Pointer to buffer containing data to be sent
// len: Length of data to send (exclusive of any headers)
// dest: Destination IP address
// dest_port: Destination port
// src_port: Source port
// Output: true if an error occured, false otherwise
//
bool __fastcall__ udp_send(const uint8_t* buf, uint16_t len, uint32_t dest,
uint16_t dest_port, uint16_t src_port);
// Listen for an inbound TCP connection
//
// This is a 'blocking' call, i.e. it will not return until a connection has been made.
//
// Inputs: port: TCP port to listen on
// callback: Vector to call when data arrives on this connection
// buf: Pointer to buffer with data received
// len: -1 on close, otherwise length of data received
// Output: IP address of the connected client, 0 on error
//
uint32_t __fastcall__ tcp_listen(uint16_t port,
void __fastcall__ (*callback)(const uint8_t* buf,
int16_t len));
// Make outbound TCP connection
//
// Inputs: dest: Destination IP address
// dest_port: Destination port
// callback: Vector to call when data arrives on this connection
// buf: Pointer to buffer with data received
// len: -1 on close, otherwise length of data received
// Output: true if an error occured, false otherwise
//
bool __fastcall__ tcp_connect(uint32_t dest, uint16_t dest_port,
void __fastcall__ (*callback)(const uint8_t* buf,
int16_t len));
// Close the current TCP connection
//
// Inputs: None
// Output: true if an error occured, false otherwise
//
bool tcp_close(void);
// Send data on the current TCP connection
//
// Inputs: buf: Pointer to buffer containing data to be sent
// len: Length of data to send (up to 1460 bytes)
// Output: true if an error occured, false otherwise
//
bool __fastcall__ tcp_send(const uint8_t* buf, uint16_t len);
// Send an empty ACK packet on the current TCP connection
//
// Inputs: None
// Output: true if an error occured, false otherwise
//
bool tcp_send_keep_alive(void);
// Query an SNTP server for current UTC time
//
// Inputs: SNTP server IP address
// Output: The number of seconds since 00:00 on Jan 1 1900 (UTC), 0 on error
//
uint32_t __fastcall__ sntp_get_time(uint32_t server);
// Download a file from a TFTP server and provide data to user supplied vector
//
// Inputs: server: IP address of server to receive file from
// name: Zero terminated string containing the name of file to download
// callback: Vector to call once for each 512 byte packet received
// buf: Pointer to buffer containing data received
// len: 512 if buffer is full, otherwise number of bytes
// in the buffer
// Output: true if an error occured, false otherwise
//
bool __fastcall__ tftp_download(uint32_t server, const char* name,
void __fastcall__ (*callback)(const uint8_t* buf,
uint16_t len));
// Download a file from a TFTP server and provide data to specified memory location
//
// Inputs: server: IP address of server to receive file from
// name: Zero terminated string containing the name of file to download
// buf: Pointer to buffer containing data received
// Output: Length of data received, 0 on error
//
uint16_t __fastcall__ tftp_download_to_memory(uint32_t server, const char* name,
const uint8_t* buf);
// Upload a file to a TFTP server with data retrieved from user supplied vector
//
// Inputs: server: IP address of server to send file to
// name: Zero terminated string containing the name of file to upload
// callback: Vector to call once for each 512 byte packet to be sent
// buf: Pointer to buffer containing data to be sent
// Output: 512 if buffer is full, otherwise number of bytes
// in the buffer
// Output: true if an error occured, false otherwise
//
bool __fastcall__ tftp_upload(uint32_t server, const char* name,
uint16_t __fastcall__ (*callback)(const uint8_t* buf));
// Upload a file to a TFTP server with data retrieved from specified memory location
//
// Inputs: server: IP address of server to send file to
// name: Zero terminated string containing the name of file to upload
// buf: Pointer to buffer containing data to be sent
// len: Length of data to be sent
// Output: true if an error occured, false otherwise
//
bool __fastcall__ tftp_upload_from_memory(uint32_t server, const char* name,
const uint8_t* buf, uint16_t len);
// Parse an HTTP URL into a form that makes it easy to retrieve the specified resource
//
// On success the variables url_ip, url_port and url_selector (see below) are valid.
//
// Inputs: url: Zero (or ctrl char) terminated string containing the URL
// resolve: Resolve host in URL
// Output: true if an error occured, false otherwise
//
bool __fastcall__ url_parse(const char* url, bool resolve);
// Access to parsed HTTP URL
//
// Access to the four items below is only valid after url_parse returned false.
//
extern char* url_host; // Zero terminated string containing host in URL + "\r\n\r\n"
extern uint32_t url_ip; // IP address of host in URL (only if 'resolve' is true)
extern uint16_t url_port; // Port number of URL
extern char* url_selector; // Zero terminated string containing selector part of URL
// Download a resource specified by an HTTP URL
//
// The URL mustn't be longer than 1400 chars. The buffer is temporarily used to hold the
// generated HTTP request so it should have a length of at least 1460 bytes. On success
// the resource is zero terminated.
//
// Inputs: url: Zero (or ctrl char) terminated string containing the URL
// buf: Pointer to a buffer that the resource will be downloaded into
// len: Length of buffer
// Output: Length of resource downloaded, 0 on error
//
uint16_t __fastcall__ url_download(const char* url, const uint8_t* buf, uint16_t len);
// Start an HTTP server
//
// This routine will stay in an endless loop that is broken only if user press the abort key.
//
// Inputs: port: TCP port to listen on
// callback: Vector to call for each inbound HTTP request
// client: IP address of the client that sent the request
// method: Zero terminated string containing the HTTP method
// path: Zero terminated string containing the HTTP path
// Output: None
//
void __fastcall__ httpd_start(uint16_t port,
void __fastcall__ (*callback)(uint32_t client,
const char* method,
const char* path));
// HTTP response types
//
#define HTTPD_RESPONSE_NOHEADER 0 // No HTTP response header
#define HTTPD_RESPONSE_200_TEXT 1 // HTTP Code: 200 OK, Content Type: 'text/text'
#define HTTPD_RESPONSE_200_HTML 2 // HTTP Code: 200 OK, Content Type: 'text/html'
#define HTTPD_RESPONSE_200_DATA 3 // HTTP Code: 200 OK, Content Type: 'application/octet-stream'
#define HTTPD_RESPONSE_404 4 // HTTP Code: 404 Not Found
#define HTTPD_RESPONSE_500 5 // HTTP Code: 500 System Error
// Send HTTP response
//
// Calling httpd_send_response is only valid in the context of a httpd_start callback.
// For the response types HTTPD_RESPONSE_404 and HTTPD_RESPONSE_500 'buf' is ignored.
// With the response type HTTPD_RESPONSE_NOHEADER it's possible to add more content to
// an already sent HTTP response.
//
// Inputs: response_type: Value describing HTTP code and content type in response header
// buf: Pointer to buffer with HTTP response content
// len: Length of buffer with HTTP response content
// Output: None
//
void __fastcall__ httpd_send_response(uint8_t response_type,
const uint8_t* buf, uint16_t len);
// Retrieve the value of a variable defined in the previously received HTTP request
//
// Calling http_get_value is only valid in the context of a httpd_start callback.
// Only the first letter in a variable name is significant. E.g. if a querystring contains
// the variables 'a','alpha' and 'alabama', then only the first one will be retrievable.
//
// Inputs: name: Variable to retrieve
// Output: Variable value (zero terminated string) if variable exists, null otherwise.
//
char* __fastcall__ http_get_value(char name);
// Get number of milliseconds since initialization
//
// Inputs: None
// Output: Current number of milliseconds
//
uint16_t timer_read(void);
// Check if specified period of time has passed yet
//
// Inputs: time: Number of milliseconds we are willing to wait for
// Output: true if timeout occured, false otherwise
//
bool __fastcall__ timer_timeout(uint16_t time);
// Check whether the abort key is being pressed
//
// Inputs: None
// Output: true if abort key pressed, false otherwise
//
bool input_check_for_abort_key(void);
// Control abort key
//
// Control if the user can abort blocking functions with the abort key
// (making them return IP65_ERROR_ABORTED_BY_USER). Initially the abort
// key is enabled.
//
// Inputs: enable: false to disable the key, true to enable the key
// Output: None
//
void __fastcall__ input_set_abort_key(bool enable);
// Access to actual abort key code
//
extern uint8_t abort_key;
#endif