/
network.h
139 lines (114 loc) · 6.37 KB
/
network.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
/*
* This file is part of Espruino, a JavaScript interpreter for Microcontrollers
*
* Copyright (C) 2013 Gordon Williams <gw@pur3.co.uk>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* ----------------------------------------------------------------------------
* Contains functions for handling JsNetwork and doing common networking tasks
* ----------------------------------------------------------------------------
*/
#ifndef _NETWORK_H
#define _NETWORK_H
#include "jsutils.h"
#include "jsvar.h"
#include "jshardware.h"
#define NETWORK_VAR_NAME "net"
typedef enum {
ST_NORMAL = 0, // standard socket client/server
ST_HTTP = 1, // HTTP client/server
ST_UDP = 2, // UDP socket client/server
// WebSockets?
ST_TYPE_MASK = 3,
ST_TLS = 4, // do the given connection with TLS
} SocketType;
typedef enum {
NETWORKSTATE_OFFLINE,
NETWORKSTATE_CONNECTED, // connected but not online (no DHCP)
NETWORKSTATE_ONLINE, // DHCP (or manual address)
NETWORKSTATE_INVOLUNTARY_DISCONNECT, // just randomly disconnected - maybe try and reconnect
} PACKED_FLAGS JsNetworkState;
extern JsNetworkState networkState; // FIXME put this in JsNetwork
// This is all code for handling multiple types of network access with one binary
typedef enum {
JSNETWORKTYPE_SOCKET, ///< Standard linux socket API
JSNETWORKTYPE_CC3000, ///< TI CC3000 support
JSNETWORKTYPE_W5500, ///< WIZnet W5500 support
JSNETWORKTYPE_JS, ///< JavaScript network type
JSNETWORKTYPE_ESP8266_BOARD, ///< Espressif ESP8266 board support
JSNETWORKTYPE_ESP32 /// < Espressif ESP32 board support
} JsNetworkType;
typedef struct {
JsNetworkType type;
// Info for accessing specific devices
IOEventFlags device;
Pin pinCS, pinIRQ, pinEN;
int recvBufferSize; ///< Amount of memory to allocate for recv (sockopt SO_RCVBUF), by default net->chunkSize
} PACKED_FLAGS JsNetworkData;
// Here we assume that IP addresses are stored IN ORDER - eg. 192.168.1.1 = [192,168,1,1] - CC3000 does it backwards
typedef struct JsNetwork {
JsVar *networkVar; // this won't be locked again - we just know that it is already locked by something else
JsNetworkData data;
unsigned char _blank; ///< this is needed as jsvGetString for 'data' wants to add a trailing zero
int chunkSize; ///< Amount of memory to allocate for chunks of data when using send/recv
/// Called on idle. Do any checks required for this device
void (*idle)(struct JsNetwork *net);
/// Call just before returning to idle loop. This checks for errors and tries to recover. Returns true if no errors.
bool (*checkError)(struct JsNetwork *net);
/// if host=0, creates a server otherwise creates a client (and automatically connects). Returns >=0 on success
int (*createsocket)(struct JsNetwork *net, SocketType socketType, uint32_t host, unsigned short port, JsVar *options);
/// destroys the given socket
void (*closesocket)(struct JsNetwork *net, int sckt);
/// If the given server socket can accept a connection, return it (or return < 0)
int (*accept)(struct JsNetwork *net, int sckt);
/// Get an IP address from a name
void (*gethostbyname)(struct JsNetwork *net, char * hostName, uint32_t* out_ip_addr);
/// Receive data if possible. returns nBytes on success, 0 on no data, or -1 on failure
int (*recv)(struct JsNetwork *net, SocketType socketType, int sckt, void *buf, size_t len);
/// Send data if possible. returns nBytes on success, 0 on no data, or -1 on failure
int (*send)(struct JsNetwork *net, SocketType socketType, int sckt, const void *buf, size_t len);
} PACKED_FLAGS JsNetwork;
/// Header applied to all UDP packets when they are received
typedef struct {
uint8_t host[4]; //< host data sent from
uint16_t port; //< port data sent from
uint16_t length; //< length in bytes of the data
} PACKED_FLAGS JsNetUDPPacketHeader;
// ---------------------------------- these are in network.c
// Get the relevant info for JsNetwork (done from a var in root scope)
void networkCreate(JsNetwork *net, JsNetworkType type); // create the network object (ONLY to be used by network drivers)
bool networkWasCreated();
bool networkGetFromVar(JsNetwork *net);
bool networkGetFromVarIfOnline(JsNetwork *net); // only return true (and network) if we're online, otherwise warn
void networkSet(JsNetwork *net);
void networkFree(JsNetwork *net);
JsNetwork *networkGetCurrent(); ///< Get the currently active network structure. can be 0!
// ---------------------------------------------------------
/// Use this for getting the hostname, as it parses the name to see if it is an IP address first
void networkGetHostByName(JsNetwork *net, char * hostName, uint32_t* out_ip_addr);
uint32_t networkParseIPAddress(const char *ip);
/* given 6 pairs of 8 bit hex numbers separated by ':', parse them into a
* 6 byte array. returns false on failure */
bool networkParseMACAddress(unsigned char *addr, const char *ip);
/// if nBytes<0, addresses are printed out backwards
JsVar *networkGetAddressAsString(unsigned char *ip, int nBytes, unsigned int base, char separator);
/// Given an address (pointed to by ip) put it in a string named 'name', in the given object. if nBytes<0, addresses are printed out backwards
void networkPutAddressAsString(JsVar *object, const char *name, unsigned char *ip, int nBytes, unsigned int base, char separator);
/** Some devices (CC3000) store the IP address with the first element last, so we must flip it */
unsigned long networkFlipIPAddress(unsigned long addr);
/// Check for any errors and try and recover (CC3000 only really)
bool netCheckError(JsNetwork *net);
/// Create a socket (server (host==0) or client)
int netCreateSocket(JsNetwork *net, SocketType socketType, uint32_t host, unsigned short port, JsVar *options);
/// Ask this socket to close - it may not close immediately
void netCloseSocket(JsNetwork *net, SocketType socketType, int sckt);
/** If this is a server socket and we have an incoming connection then
* accept and return the socket number - else return <0 */
int netAccept(JsNetwork *net, int sckt);
void netGetHostByName(JsNetwork *net, char * hostName, uint32_t* out_ip_addr);
int netRecv(JsNetwork *net, SocketType socketType, int sckt, void *buf, size_t len);
int netSend(JsNetwork *net, SocketType socketType, int sckt, const void *buf, size_t len);
#endif // _NETWORK_H