mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
Initial migration of docs from the original ESP8266 port repository.
This commit is contained in:
parent
44628b19e5
commit
75a9a3ca19
346
targets/esp8266/docs/05-User_Guide.md
Normal file
346
targets/esp8266/docs/05-User_Guide.md
Normal file
@ -0,0 +1,346 @@
|
||||
This is the page where the User Guide for using the Espruino ESP8266 will be documented. It is **vital** that you realize that this is still a work in progress and hence if you start coding to this guide be prepared to make changes to your own code should the APIs and semantics change before the project completes and becomes part of Espruino as whole.
|
||||
|
||||
By completion, this documentation will be polished and placed in the code itself so that automated
|
||||
documentation generation will work.
|
||||
|
||||
|
||||
|
||||
##Listing access points
|
||||
An access point is a potential WiFi device that an ESP8266 can connect to as a client. In order to connect, you will need to know the identity of the network (the SSID) and the password (if needed). To list access points, we can use the function called `ESP8266WiFi.getAccessPoints()`. The syntax of the function is:
|
||||
|
||||
`ESP8266WiFi.getAccessPoints(callback)`
|
||||
|
||||
Where callback is a function that takes a single parameter that is an array of objects. Each object in the array corresponds to an available access point and contains the following properties:
|
||||
|
||||
* `ssid` - The network id
|
||||
* `authMode` - The authentication mode
|
||||
* `rssi` - The signal strength
|
||||
* `channel` - The network channel
|
||||
* `isHidden` - Is hidden from discovery
|
||||
|
||||
Here is an example of use:
|
||||
|
||||
ESP8266WiFi.getAccessPoints(function(arrayOfAcessPoints) {
|
||||
for (var i=0; i<arrayOfAcessPoints.length; i++) {
|
||||
print("Access point: " + i + " = " + JSON.stringify(arrayOfAcessPoints[i]));
|
||||
}
|
||||
});
|
||||
|
||||
with a resulting output of:
|
||||
|
||||
Access point: 0 = {"rssi":-48,"channel":7,"authMode":3,"isHidden":false,"ssid":"mySsid"}
|
||||
Access point: 1 = {"rssi":-84,"channel":9,"authMode":4,"isHidden":false,"ssid":"2WIRE874"}
|
||||
|
||||
##Connect to an access point
|
||||
We can connect to an access point using `ESP8266WiFi.connect()`. This function takes an SSID and password of the access point to which we wish to connect. We can also supply an optional callback function that will be invoked when we have been assigned an IP address and are ready for work.
|
||||
|
||||
##Determining your own IP address
|
||||
To determine the ESP8266's current IP address, we can use the `ESP8266WiFi.getIPInfo()` function.
|
||||
|
||||
var ipInfo = ESP8266WiFi.getIPInfo();
|
||||
print("Current IP address is: " + ESP8266WiFi.getAddressAsString(ipInfo.ip));
|
||||
|
||||
##Disconnect from the access point
|
||||
When connected to an access point, you can disconnect from it with a call to `ESP8266WiFi.disconnect()`.
|
||||
|
||||
##Forming a TCP connection
|
||||
Assuming that the ESP8266 is now connected to the network, we can form a TCP connection to a partner. To do this, we need to know the IP address and port
|
||||
number on which the partner is listening. From there, we can use the Espruino supplied library called "net". We gain access to this library using:
|
||||
|
||||
var net = require("net");
|
||||
|
||||
From this, we can now start calling the functions available within that library. For example, to connect to a partner using TCP we can issue:
|
||||
|
||||
net.connect(<connectionDetails>, function(conn) {
|
||||
// Work with connection here
|
||||
});
|
||||
|
||||
The connection details can either be a URL of the form `http://<IP Address>:<port>` or an object with the properties:
|
||||
|
||||
* `host` - The IP address of the target
|
||||
* `port` - The target IP address
|
||||
|
||||
We can close the socket with a call to `end()`.
|
||||
|
||||
##Becoming an HTTP server
|
||||
We can use the Espruino libraries to become an HTTP server. Our first step is to load the appropriate library using:
|
||||
|
||||
var http = require("http");
|
||||
|
||||
From here, we can call createServer() to create an instance of an HTTP server. Note that once created
|
||||
we are not yet listening for incomming connections. That comes later.
|
||||
|
||||
var httpSrv = http.createServer(callbackFunction);
|
||||
|
||||
The `callbackFunction` is a function that will be called when an HTTP client request is received.
|
||||
The function takes two parameters:
|
||||
|
||||
* `request` - An instance of a
|
||||
* `response`
|
||||
|
||||
##Being an HTTP client
|
||||
We can use the Espruino libraries to be an HTTP client. Our first step is to load
|
||||
the appropriate library using:
|
||||
|
||||
var http = require("http");
|
||||
|
||||
From here, we can call `get()` to send an HTTP get request and get the response.
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
http.get({
|
||||
host: "184.168.192.49",
|
||||
port: 80,
|
||||
path: "/"
|
||||
}, function(response) {
|
||||
print("get callback!");
|
||||
});
|
||||
|
||||
This will send a request to the IP address specified by host and, when a response is received,
|
||||
the callback function will be invoked. The `response` data object contains details
|
||||
of the response.
|
||||
|
||||
From the response object, we can register callbacks to be informed when new data is available and also when the connection is closed. For example:
|
||||
|
||||
response.on("data", function(data) {
|
||||
// Data available here.
|
||||
});
|
||||
|
||||
and
|
||||
|
||||
response.on("close", function() {
|
||||
// Connection was closed.
|
||||
});
|
||||
|
||||
----
|
||||
|
||||
#Reference
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.init
|
||||
|
||||
`ESP8266WiFi.init()`
|
||||
|
||||
Initialize the ESP8266 WiFi and TCP subsystems. This is undoubtedly NOT going to be in the final releases
|
||||
however until we understand more about the architecture, this is needed as scafolding (if nothing else).
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.getAccessPoints
|
||||
|
||||
Get a list of the access points and pass them as an array into the callback.
|
||||
|
||||
`ESP8266WiFi.getAccessPoints(callback)`
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.connect
|
||||
|
||||
Connect to a named access point.
|
||||
|
||||
`ESP8266WiFi.connect(ssid, password, [callback])`
|
||||
|
||||
When called, this function places the ESP8266 in station mode. This means that we will not be an access point.
|
||||
Once done, we then connect to the named access point using the network and password parameters supplied by `ssid` and `password`. The optional callback is a function that is invoked when an IP address has been assigned to us meaning that we are now ready for TCP/IP based work.
|
||||
|
||||
* `ssid` - The network id of the access point.
|
||||
* `password` - The password to use to connect to the access point.
|
||||
* `callback` - An optional JavaScript function that is called when we are ready for TCP/IP based work.
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.disconnect
|
||||
Disconnect the ESP8266 from the access point.
|
||||
|
||||
`ESP8266WiFi.disconnect()`
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.restart
|
||||
|
||||
Restart the ESP8266. Purely for debug and will be removed.
|
||||
|
||||
`ESP8266WiFi.restart()`
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.getRstInfo
|
||||
|
||||
`ESP8266WiFi.getRstInfo()`
|
||||
|
||||
|
||||
Returns an object that contains the details of the last ESP8266 restart.
|
||||
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.getIPInfo
|
||||
|
||||
`ESP8266WiFi.getIPInfo()`
|
||||
|
||||
Returns an object that contains the details of the current IP address. The object contains:
|
||||
|
||||
* `ip` - The current IP address
|
||||
* `gw` - The current Gateway address
|
||||
* `netmask` - The current Netmask value
|
||||
|
||||
Each of these properties are 32 bit integers (4 bytes corresponding to the IP address). To convert these
|
||||
into string dotted decimal format one can use the `ESP8266WiFi.getAddressAsString` function.
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.getAutoConnect
|
||||
|
||||
Get the current value of the auto connect mode.
|
||||
|
||||
`ESP8266WiFi.getAutoConnect()`
|
||||
|
||||
Returns `true` if we are going to auto connect on next restart.
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.setAutoConnect
|
||||
|
||||
Set the auto connect mode on **next** restart.
|
||||
|
||||
`ESP8266WiFi.setAutoConnect(autoconnect)`
|
||||
|
||||
* `autoconnect` - A value of `true` to perform an autoconnect and false otherwise.
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.getStationConfig
|
||||
|
||||
Get the station configuration settings.
|
||||
|
||||
`ESP8266WiFi.getStationConfig()`
|
||||
|
||||
The return is an object containing:
|
||||
|
||||
* `ssid` - The network name of the access point.
|
||||
* `password` - The password used to connect to the access point.
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.onWiFiEvent
|
||||
|
||||
Set the WiFi event handler.
|
||||
|
||||
`ESP8266WiFi.onWiFiEvent(callback)`
|
||||
|
||||
* `callback` - A callback function that is invoked with the details of the WiFi event.
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.getAddressAsString
|
||||
|
||||
Get a string representation of an IP address.
|
||||
|
||||
`ESP8266WiFi.getAddressAsString(address)`
|
||||
|
||||
* `address` - An integer representation of a string.
|
||||
|
||||
The return is a JS string that represents our IP address.
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.getConnectStatus
|
||||
|
||||
Get the current connection status.
|
||||
|
||||
`ESP8266WiFi.getConnectStatus()`
|
||||
|
||||
Retrieve the connection status. The return is an object that contains:
|
||||
|
||||
* status - The status code from ESP8266
|
||||
* statusMsg - The description of the code
|
||||
|
||||
The status is a JS integer that describes the current connection status which will be one of:
|
||||
|
||||
* 0 - `STATION_IDLE`
|
||||
* 1 - `STATION_CONNECTING`
|
||||
* 2 - `STATION_WRONG_PASSWORD`
|
||||
* 3 - `STATION_NO_AP_FOUND`
|
||||
* 4 - `STATION_CONNECT_FAIL`
|
||||
* 5 - `STATION_GOT_IP`
|
||||
* 255 - Not in station mode
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.beAccessPoint
|
||||
|
||||
Become an access point.
|
||||
|
||||
`ESP8266WiFi.beAccessPoint(ssid, password)`
|
||||
|
||||
Become an access point for the network supplied by `ssid` with a password of `password`.
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.getConnectedStations
|
||||
|
||||
List the WiFi stations connected to the ESP8266 assuming it is being
|
||||
an access point.
|
||||
|
||||
`ESP8266WiFI.getConnectedStations()`
|
||||
|
||||
The return is an array of objects where each object contains:
|
||||
|
||||
* `ip` - The IP address of the connected station.
|
||||
|
||||
If no stations are connected then the return is an array with zero elements.
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.getRSSI
|
||||
|
||||
Get the RSSI (signal strength) of the WiFi signal.
|
||||
|
||||
`ESP8266WiFi.getRSSI()`
|
||||
|
||||
The return is an integer representing the signal strength of the connected WiFi
|
||||
network.
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.ping
|
||||
|
||||
Ping an IP address.
|
||||
|
||||
`ESP8266WiFi.ping(ipAddress, callback)`
|
||||
|
||||
Ping the TCP/IP device given by the address. The address can be either a dotted
|
||||
decimal string or a 32bit numeric. A callback function can be supplied which is invoked for each ping response. A parameter is supplied to the callback which is a JS object that contains the following fields:
|
||||
|
||||
* totalCount
|
||||
* totalBytes
|
||||
* totalTime
|
||||
* respTime
|
||||
* seqNo
|
||||
* timeoutCount
|
||||
* bytes
|
||||
* error
|
||||
|
||||
|
||||
An example of calling this function would be:
|
||||
|
||||
|
||||
ESP8266WiFi.ping("192.168.1.31", function(resp) {
|
||||
print("Ping response: " + JSON.stringify(resp));
|
||||
});
|
||||
|
||||
----
|
||||
|
||||
##ESP8266WiFi.getState
|
||||
|
||||
Return an object that represents the state and details of the ESP8266 device.
|
||||
|
||||
`ESP8266WiFi.getState()`
|
||||
|
||||
The returned object contains the following fields:
|
||||
|
||||
* `sdkVersion` - The version of the ESP8266 SDK used to build this release.
|
||||
* `cpuFrequency` - The CPU operating frequency in MHz.
|
||||
* `freeHeap` - The amount of free heap in bytes.
|
||||
44
targets/esp8266/docs/07-Samples.md
Normal file
44
targets/esp8266/docs/07-Samples.md
Normal file
@ -0,0 +1,44 @@
|
||||
This file will contain tested and richer samples of using Espruino on the ESP8266.
|
||||
|
||||
##An HTTP responder
|
||||
The following script will setup the device to be an HTTP listener. Connect a browser to:
|
||||
|
||||
1. `http://<ESP_IP>/hello`
|
||||
2. `http://<ESP_IP>/goodbye`
|
||||
3. `http://<ESP_IP>/nothing`
|
||||
|
||||
Here is the script to run.
|
||||
|
||||
ESP8266WiFi.init();
|
||||
var http = require("http");
|
||||
var httpSrv = http.createServer(function(request, response) {
|
||||
response.write("<html><body>");
|
||||
if (request.url == "/hello") {
|
||||
response.write("<b>Welcome</b> to the ESP8266 test.");
|
||||
} else if (request.url == "/goodbye") {
|
||||
response.write("<b>Please</b> come back again soon.");
|
||||
} else {
|
||||
response.write("Sorry ... I didn't understand!");
|
||||
}
|
||||
response.end("</body></html>");
|
||||
});
|
||||
httpSrv.listen(80);
|
||||
|
||||
##An HTTP GET request
|
||||
The following is a simple HTTP GET request:
|
||||
|
||||
ESP8266WiFi.init();
|
||||
var http = require("http");
|
||||
http.get({
|
||||
host: "184.168.192.49",
|
||||
port: 80,
|
||||
path: "/"
|
||||
}, function(response) {
|
||||
print("get callback!");
|
||||
response.on('data', function(data) {
|
||||
print("We got data: " + data);
|
||||
});
|
||||
response.on('close', function() {
|
||||
print("The response connection closed");
|
||||
});
|
||||
});
|
||||
70
targets/esp8266/docs/10-The-Build-System.md
Normal file
70
targets/esp8266/docs/10-The-Build-System.md
Normal file
@ -0,0 +1,70 @@
|
||||
The Make system has the following targets:
|
||||
|
||||
* `clean` - Clean the build
|
||||
* `all` - Compile the build culminating in the ELF executable used for flashing the firmware
|
||||
* `flash` - Generate the firmware files and flash. Calls `all` as needed.
|
||||
|
||||
In order to compile the ESP8266/Espruino project, changes were required to the Espruino Makefile. Here is a record of those changes.
|
||||
|
||||
1. A new board type called "ESP8266_ESP12" was added. There will be a board type for each of the ESP modules such as ESP-1, ESP-12, NodeMCU etc. It is important to note that there is already a variable called ESP8266 which is about piggybacking an ESP8266 onto an Espruino board.
|
||||
2. A new ESP8266_ESP12.py file was created under boards.
|
||||
3. The `CCPREFIX` used in the Makefile was added if we are building an ESP8266. The prefix is `xtensa-lx106-elf-`.
|
||||
4. The compiler flags we want are:
|
||||
|
||||
* -Os
|
||||
* -std=gnu99
|
||||
* -fno-builtin
|
||||
* -Wpointer-arith
|
||||
* -Wundef
|
||||
* -Werror
|
||||
* -Wl,-EL
|
||||
* -fno-inline-functions
|
||||
* -nostdlib
|
||||
* -mlongcalls
|
||||
* -mtext-section-literals
|
||||
* -D__ets__
|
||||
* -DICACHE_FLASH
|
||||
* -I directories
|
||||
|
||||
5. The linker flags we want are:
|
||||
* -LC:\Espressif\ESP8266_SDK/lib
|
||||
* -T./ld2/eagle.app.v6.ld
|
||||
* -nostdlib
|
||||
* -Wl,--no-check-sections
|
||||
* -u call_user_start
|
||||
* -Wl,-static
|
||||
* -Wl,--start-group -lc -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lmain build/espruino_app.a -Wl,--end-group
|
||||
|
||||
##Linker configuration
|
||||
The linker uses a file called `eagle.app.v6.ld` to map the address spaces. By default, the Espressif supplied version maps text code to the second half of a 512K flash chip. This means that only 256K appears available. Since our project will need more than 300K of flash for storage, this won't work. To solve the problem we need to create a copy of the file and edit it (leave the original alone). Find the line which reads:
|
||||
|
||||
irom0_0_seg : org = 0x40240000, len = 0x3C000
|
||||
|
||||
and change it to
|
||||
|
||||
irom0_0_seg : org = 0x40210000, len = 0x60000
|
||||
|
||||
This changes the start address of the firmware from `0x4 0000` to `0x1 0000`. The Makefile assumes that the name of the new template is `0x10000_eagle.app.v6.ld`.
|
||||
|
||||
##ESP8266 Specific files
|
||||
The rules are that one should not modify any of the Espruino supplied files. Rather, the items that are specific to an ESP8266 go into their own hardware specific files. The architecture of Espruino allows for just this by providing a folder called `targets/<boardname>`. For this project, here is where we define ESP8266 specific items. Specifically, we have:
|
||||
|
||||
* `esp8266_board_utils.c`
|
||||
* `esp8266_board_utils.h`
|
||||
* `ESP8266_board.h`
|
||||
* `jshardware.c` - The primary mapping from logical Espruino functions to ESP8266 specific.
|
||||
* `user_main.c` - The entry point into ESP8266 execution.
|
||||
* `user_config.h` - The mandatory, but empty, header file (see ESP8266 docs).
|
||||
* `uart.c` - The Espressif supplied UART code.
|
||||
* `driver/uart.h` - The Espressif supplied UART code.
|
||||
* `driver/uart_register.h` - The Espressif supplied UART code.
|
||||
* `telnet_client.c` - Experimental Telnet server.
|
||||
* `telnet.h` - Experimental Telnet server.
|
||||
|
||||
In addition, we have the ESP8266 networking files located in the folder called `libs/network/esp8266`. The files there
|
||||
include:
|
||||
|
||||
* `jswrap_esp8266.c` - Description and implementation JS exposed functions.
|
||||
* `jswrap_esp8266.h` - Header files for JS exposed functions.
|
||||
* `network_esp8266.c` - Implementation of JSNetwork service for ESP8266.
|
||||
* `network_esp8266.h` - Definition of JSNetwork service for ESP8266.
|
||||
28
targets/esp8266/docs/20-Development-environment.md
Normal file
28
targets/esp8266/docs/20-Development-environment.md
Normal file
@ -0,0 +1,28 @@
|
||||
In order to build this project, you will need a development environment. We recommend the [Eclipse Mars](http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/marsr) release with the C Developer Tools (CDT) perspective. In addition to the base Eclipse, the following plugins are recommended (but not required):
|
||||
|
||||
* [Log Viewer](https://marketplace.eclipse.org/content/logviewer) - Tail tool inside Eclipse. Good for watching the CDT build logs.
|
||||
* [Path Tools](https://marketplace.eclipse.org/content/path-tools) - Working with file paths within the Eclipse environment.
|
||||
|
||||
The project can also be built from the command line but we recommend Eclipse because of its integrated tooling allow us to run makes, see the output of the makes and see the C source files annotated with the errors produced during a build (assuming that there are any).
|
||||
|
||||
We need an Xtensa version of GCC. The version that has been tested is Xtensa GCC v.5.10. This was obtained here:
|
||||
|
||||
[http://www.esp8266.com/viewtopic.php?f=9&t=820](http://www.esp8266.com/viewtopic.php?f=9&t=820)
|
||||
|
||||
We will also need a copy of python. This can be obtained here:
|
||||
|
||||
[https://www.python.org/downloads/](https://www.python.org/downloads/)
|
||||
|
||||
We can download the [Python](https://www.python.org/downloads/) 3.4.3 (or better). This will create a `C:\Python34` folder structure.
|
||||
|
||||
We also need the [MinGW](http://www.mingw.org/) package and also include some Unix commands including:
|
||||
|
||||
* grep
|
||||
* wc
|
||||
|
||||
We also need the [Espressif SDK](http://bbs.espressif.com/viewtopic.php?f=46&t=850).
|
||||
|
||||
We also need the [esptool-ck](https://github.com/igrr/esptool-ck) utility.
|
||||
|
||||
##Source files
|
||||
The source files for the ESP8266 project should terminate with Unix style line delimiters (LF). When working on Eclipse on Windows, you need to specify this explicitly. Open up `Preferences > General > Workspace` and change "New text file line delimiter" to "Unix".
|
||||
18
targets/esp8266/docs/30-Validating-a-build.md
Normal file
18
targets/esp8266/docs/30-Validating-a-build.md
Normal file
@ -0,0 +1,18 @@
|
||||
When we build the project, we likely want to validate that what we have is correct. Before we actually flash, there are some tests we can perform to check the integrity of the results.
|
||||
|
||||
First, if we find the ELF binary that was build for us, we can run objdump --headers over it. This will produce results similar to the following:
|
||||
|
||||
Sections:
|
||||
Idx Name Size VMA LMA File off Algn
|
||||
0 .data 0000034c 3ffe8000 3ffe8000 000000e0 2**4
|
||||
CONTENTS, ALLOC, LOAD, DATA
|
||||
1 .rodata 00000060 3ffe8350 3ffe8350 00000430 2**3
|
||||
CONTENTS, ALLOC, LOAD, READONLY, DATA
|
||||
2 .bss 00006928 3ffe83b0 3ffe83b0 00000490 2**4
|
||||
ALLOC
|
||||
3 .text 000061be 40100000 40100000 00000490 2**2
|
||||
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
||||
4 .irom0.text 00029536 40210000 40210000 00006650 2**4
|
||||
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
||||
|
||||
Note specifically the location of the `.irom0.text` address location which places it at the correct address space.
|
||||
@ -0,0 +1,9 @@
|
||||
The following items have been learned about the Espruino code base that need addressed:
|
||||
|
||||
* The python code contains `print <value>` where we seem to need `print(<value>)`. Change made.
|
||||
* the __WORDSIZE is not defined but is attempted to be checked for equality to 64.
|
||||
* The scripts/build_platform_config.py needed changed to add a family check for ESP8266.
|
||||
* jsnative.c - Addition of matching XTENSA architecture to ARM architecture. Change made.
|
||||
* Addition of `JSNETWORKTYPE_ESP8266_BOARD` into `network.h`.
|
||||
* Within `jsutils.h` there is a definition for `ALWAYS_INLINE`. For the ESP8266 this needs to be set to
|
||||
defined but with no value.
|
||||
36
targets/esp8266/docs/50-The-ESP8266-jshardware.c-file.md
Normal file
36
targets/esp8266/docs/50-The-ESP8266-jshardware.c-file.md
Normal file
@ -0,0 +1,36 @@
|
||||
The Espruino environment requires a board to provide a file called `jshardware.c` that contains within it the functions that are expected to be hardware specific. This page describes the ESP8266 implementation of these functions.
|
||||
|
||||
----
|
||||
|
||||
######jshUARTKick
|
||||
|
||||
This function is called to inform the UART that it has some work to do. In the ESP8266 implementation, it asks Espruino for each character to write and keeps looping over them until the buffer is drained.
|
||||
|
||||
----
|
||||
|
||||
######jshGetSystemTime
|
||||
|
||||
Return the system time in microseconds.
|
||||
|
||||
`JsSysTime jshGetSystemTime()`
|
||||
|
||||
For the ESP8266 we can leverage the SDK supplied `system_get_time()`.
|
||||
|
||||
----
|
||||
|
||||
######jshDelayMicroseconds
|
||||
|
||||
Delay for a period of microseconds.
|
||||
|
||||
`void jshDelayMicroseconds(int microsec)`
|
||||
|
||||
For the ESP8266, we might think that we can use a simple mapping to the SDK supplied `os_delay_us()` function however, the rules of ESP8266 say to try not sleep for more than 10 milliseconds and nothing in this spec for the function says that it couldn't
|
||||
sleep for much longer. As such we need special work to make sure we keep yielding often enough to satisfy everyone.
|
||||
|
||||
----
|
||||
|
||||
######jshInit
|
||||
|
||||
This function is called by the user application to initialize hardware however it is architected to be part of the `jshardware.c` file. The rules say that it must call `jshInitDevices` which is a provided function. This is also where we would do any ESP8266 hardware initialization.
|
||||
|
||||
`void jshInit()`
|
||||
1635
targets/esp8266/docs/60-The-Espruino-API.md
Normal file
1635
targets/esp8266/docs/60-The-Espruino-API.md
Normal file
File diff suppressed because it is too large
Load Diff
776
targets/esp8266/docs/65-Espruino-networking.md
Normal file
776
targets/esp8266/docs/65-Espruino-networking.md
Normal file
@ -0,0 +1,776 @@
|
||||
The Espruino networking has an architecture model that appears to be implemented in `network.c`. Various network support types can be compiled into the core code including:
|
||||
|
||||
* `JSNETWORKTYPE_CC3000` - The CC3000 device.
|
||||
* `JSNETWORKTYPE_W5500` - The W5500 device.
|
||||
* `JSNETWORKTYPE_ESP8266` - A piggybacked ESP8266 attached to the MCU.
|
||||
* `JSNETWORKTYPE_LINUX` - The Linux OS
|
||||
* `JSNETWORKTYPE_JS` - Unknown
|
||||
|
||||
For the ESP8266 board project, we will create a new type called `JSNETWORKTYPE_ESP8266_BOARD`.
|
||||
|
||||
Among the core functions exposed we seem to have:
|
||||
|
||||
* networkCreate() - create the network object (ONLY to be used by network drivers)
|
||||
* networkWasCreated()
|
||||
* networkGetFromVar()
|
||||
* networkGetFromVarIfOnline()
|
||||
* networkSet()
|
||||
* networkFree()
|
||||
* networkGetCurrent() - Get the currently active network structure. can be 0!
|
||||
* networkParseIPAddress()
|
||||
* networkParseMACAddress()
|
||||
* networkGetAddressAsString() - Get an address as a string.
|
||||
* networkPutAddressAsString()
|
||||
* networkFlipIPAddress()
|
||||
* networkGetHostByName() - Use this for getting the hostname, as it parses the name to see if it is an IP address first.
|
||||
|
||||
|
||||
A logical data type called `JsNetwork` contains the entry points for many of the functions.
|
||||
|
||||
This includes:
|
||||
|
||||
* `createsocket` - if host=0, creates a server socket otherwise creates a client socket (and automatically connects). Returns >=0 on success.
|
||||
* `closesocket` - destroys the given socket.
|
||||
* `accept` - If the given server socket can accept a connection, return it (or return < -1).
|
||||
* `gethostbyname` - Get an IP address from a name.
|
||||
* `recv` - Receive data if possible. returns nBytes on success, 0 on no data, or -1 on failure.
|
||||
* `send` - Send data if possible. returns nBytes on success, 0 on no data, or -1 on failure.
|
||||
* `idle` - Called on idle. Do any checks required for this device.
|
||||
* `checkError` - Call just before returning to idle loop. This checks for errors and tries to recover. Returns true if no errors.
|
||||
|
||||
Each of these functions **must** be implemented by a network provider.
|
||||
|
||||
##createsocket
|
||||
|
||||
`int net_<board>_createSocket(JsNetwork *net, uint32_t ipAddress, unsigned short port)`
|
||||
|
||||
If host=0, creates a server otherwise creates a client (and automatically connects).
|
||||
|
||||
* `net` - The Network we are going to use to create the socket.
|
||||
* `ipAddress` - The address of the partner of the socket.
|
||||
* `port` - The port number that the partner is listening upon.
|
||||
|
||||
Returns >=0 on success and -1 on an error. The return is the new socket id.
|
||||
|
||||
##closesocket
|
||||
|
||||
Destroys the given socket.
|
||||
|
||||
`void net_<board>_closeSocket(JsNetwork *net, int sckt)`
|
||||
|
||||
* `net` - The Network we are going to use to create the socket.
|
||||
* `sckt` - The socket to be closed.
|
||||
|
||||
##accept
|
||||
|
||||
If the given server socket can accept a connection, return it (or return < 0).
|
||||
|
||||
`int net_<board>_accept(JsNetwork *net, int serverSckt)`
|
||||
|
||||
* `net` - The Network we are going to use to create the socket.
|
||||
* `serverSckt` - The socket that we are now going to start accepting requests upon.
|
||||
|
||||
Returns a new conversation socket or -1 on an error.
|
||||
|
||||
##gethostbyname
|
||||
|
||||
Get an IP address from a name. Sets `outIp` to 0 on failure.
|
||||
|
||||
`void net_<board>_gethostbyname(JsNetwork *net, char *hostName, uint32_t *outIp)`
|
||||
|
||||
* `net` - The Network we are going to use to create the socket.
|
||||
* `hostName` - The string representing the hostname we wish to lookup.
|
||||
* `outIp` - The address into which the resolved IP address will be stored.
|
||||
|
||||
##recv
|
||||
|
||||
`int net_<board>_recv(JsNetwork *net, int sckt, void *buf, size_t len)`
|
||||
|
||||
* `net` - The Network we are going to use to create the socket.
|
||||
* `recv` - The socket from which we are to receive data.
|
||||
* `buf` - The storage buffer into which we will receive data.
|
||||
* `len` - The length of the buffer.
|
||||
|
||||
Returns the number of bytes received which may be 0 and -1 if there was an error.
|
||||
|
||||
##send
|
||||
Send data if possible.
|
||||
|
||||
`int net_<board>_send(JsNetwork *net, int sckt, const void *buf, size_t len)`
|
||||
|
||||
* `net` - The Network we are going to use to create the socket.
|
||||
* `sckt` - The socket over which we will send data.
|
||||
* `buf` - The buffer containing the data to be sent.
|
||||
* `len` - The length of data in the buffer to send.
|
||||
|
||||
Returns number of bytes sent on success, 0 on no data, or -1 on failure
|
||||
|
||||
##idle
|
||||
|
||||
`void net_<board>_idle(JsNetwork *net)`
|
||||
|
||||
* `net` - The Network we are going to use to create the socket.
|
||||
|
||||
##checkError
|
||||
|
||||
`bool net_<board>_checkError(JsNetwork *net)`
|
||||
|
||||
* `net` - The Network we are going to use to create the socket.
|
||||
|
||||
This function returns `true` if there are **no** errors.
|
||||
|
||||
----
|
||||
|
||||
#The Socket Server library
|
||||
|
||||
The socket server library is a suite of components used to provide a sockets like abstraction within
|
||||
the Espruino environment. In addition to pure communication, there is much function in here for being
|
||||
either an HTTP client or an HTTP server. To ensure that we understand what that later part means ...
|
||||
an HTTP client is playing the part of a browser and will send HTTP requests **to** and HTTP server such
|
||||
as a Web Server.
|
||||
|
||||
The HTTP server part of this library plays the part of **being** an HTTP server that responds to client
|
||||
requests from browsers (or other HTTP clients).
|
||||
|
||||
To make this technology work, the library created __hidden__ variables in the JS variable root. These are
|
||||
real JS variables but they are not visible or available to normal JS programs. However, from an internals
|
||||
perspective, they can be worked with just fine. These JS variables (and there are a couple) are actually
|
||||
instances of JS arrays where each element of the array is an object that represents a connection to
|
||||
a partner over the network. When working with the arrays, there is a method called `socketGetArray()`
|
||||
that returns (and creates) the array for us so we don't have to work with the raw arrays ourselves
|
||||
as a consumer of the library.
|
||||
|
||||
The `Socket` class has the following additions to it:
|
||||
|
||||
* `data` - Event
|
||||
* `close` - Event
|
||||
* `drain` - event
|
||||
* `available` - method - `jswrap_stream_available`
|
||||
* `read` - method - `jswrap_stream_end`
|
||||
* `write` - method - `jswrap_jswrap_net_socket_write`
|
||||
* `pipe` - method - `jswrap_pipe`
|
||||
|
||||
----
|
||||
|
||||
###httpAppendHeaders
|
||||
Add the HTTP headers object to the string.
|
||||
|
||||
`static void httpAppendHeaders(JsVar *string, JsVar *headerObject)`
|
||||
|
||||
The `headersObject` is a JS object with name/value properties. Here we walk through each of those properties
|
||||
and append them to the string supplied as `string` and add each one as an HTTP header of the form
|
||||
`<name>: <value>`.
|
||||
|
||||
----
|
||||
|
||||
###httpParseHeaders
|
||||
Parse out the HTTP headers from the data.
|
||||
|
||||
`bool httpParseHeaders(JsVar **receiveData, JsVar *objectForData, bool isServer)`
|
||||
|
||||
The `receiveData` is the address of a JS variable that contains the string received from the partner. It
|
||||
is parsed to look for headers. These are added as new property of the object passed in as `objectForData`. The
|
||||
name of the new property that is added is called `headers`. Special treatment is given for HTTP client vs server requests.
|
||||
If we are a server, then `method` and `url` are especially parsed and added and if we are a client then
|
||||
`httpVersion`, `statusCode` and `statusMessage` are pulled out.
|
||||
|
||||
----
|
||||
|
||||
###httpStringGet
|
||||
Get a C string from a JS Var.
|
||||
|
||||
`size_t httpStringGet(JsVar *v, char *str, size_t len)`
|
||||
|
||||
Retrieve a string from the variable `v` and store it at the buffer pointed to by `str` for a
|
||||
maximum size of `len`. It appears that there is no null terminator and that the return is confusing.
|
||||
|
||||
----
|
||||
|
||||
###socketGetArray
|
||||
Return the hidden variable array.
|
||||
|
||||
`static JsVar *socketGetArray(const char *name, bool create)`
|
||||
|
||||
A JS array is returned called `name` where it is a hidden root variable. If it doesn't exist then it
|
||||
can be optionally created.
|
||||
|
||||
----
|
||||
|
||||
###socketGetType
|
||||
Retrieve the type of the socket variable.
|
||||
|
||||
`static SocketType socketGetType(JsVar *var)`
|
||||
|
||||
Given a socket variable, retrieve its type. The property in the socket variable is currently `type` and is an
|
||||
integer encoded as:
|
||||
|
||||
* 0 - ST_NORMAL
|
||||
* 1 - ST_HTTP
|
||||
|
||||
----
|
||||
|
||||
###socketSetType
|
||||
|
||||
Set the type of the socket variable.
|
||||
|
||||
`static void socketSetType(JsVar *var, SocketType socketType)`
|
||||
|
||||
Given a socket variable and its type, set the type on that socket variable. This sets a property that is currently
|
||||
called `type` and is an integer encoded as:
|
||||
|
||||
* 0 - ST_NORMAL
|
||||
* 1 - ST_HTTP
|
||||
|
||||
----
|
||||
|
||||
###_socketConnectionKill
|
||||
Close (kill) the socket for a specific socket variable.
|
||||
|
||||
`void _socketConnectionKill(JsNetwork *net, JsVar *connection)`
|
||||
|
||||
Kill a socket connection that is the socket contained within `connection`.
|
||||
|
||||
----
|
||||
|
||||
###_socketCloseAllConnectionsFor
|
||||
|
||||
Close ALL the sockets associated with __something__.
|
||||
|
||||
`static void _socketCloseAllConnectionsFor(JsNetwork *net, char *name)`
|
||||
|
||||
Close all the sockets associated with a named hidden variable.
|
||||
|
||||
----
|
||||
|
||||
###_socketCloseAllConnections
|
||||
Close all the sockets associated with some socket sets.
|
||||
|
||||
`static void _socketCloseAllConnections(JsNetwork *net)`
|
||||
|
||||
Close all the sockets associated with the socket sets called `HttpSC`, `HttpCC` and `HttpS`.
|
||||
|
||||
----
|
||||
|
||||
###socketSendData
|
||||
Send data through the socket.
|
||||
|
||||
`bool socketSendData(JsNetwork *net, JsVar *connection, int sckt, JsVar **sendData)`
|
||||
|
||||
The implementation of this one is tricky. It appears that `sendData` must be a string as we perform
|
||||
string lengths against it. Can it hold binary? We also appear to pass in a `connection` which I thought
|
||||
would know its own socket ... but yet it takes a socket integer as a parameter as well.
|
||||
|
||||
The `sendData` is shrunk on return having pruned off what was actually sent. However, this rountine
|
||||
does **not** assure to send all the data ... just __some__ data ... so a caller should not assume that
|
||||
once it is called, the data has been sent.
|
||||
|
||||
|
||||
----
|
||||
|
||||
###socketInit
|
||||
Initialize the socket server environment.
|
||||
|
||||
`void socketInit()`
|
||||
|
||||
Only seems to do something on windows.()
|
||||
|
||||
----
|
||||
|
||||
###socketKill
|
||||
Shutdown the socket subsystem.
|
||||
|
||||
`void socketKill(JsNetwork *net)`
|
||||
|
||||
----
|
||||
|
||||
###socketServerConnectionsIdle
|
||||
Do idle processing on server connections.
|
||||
|
||||
`bool socketServerConnectionsIdle(JsNetwork *net)`
|
||||
|
||||
Walk through each of the socket connections for servers `HTTP_ARRAY_HTTP_SERVER_CONNECTIONS (HttpSC)` and look for
|
||||
properties on them that are interpreted as instructions.
|
||||
|
||||
Instructions that are processed include:
|
||||
|
||||
* `HTTP_NAME_CLOSENOW (closeNow)` - Close a socket.
|
||||
* `HTTP_NAME_SEND_DATA (dSnd)` - Send data.
|
||||
* `HTTP_NAME_CLOSE (close)` - Close a socket when done.
|
||||
|
||||
----
|
||||
|
||||
###socketClientPushReceiveData
|
||||
Push received data into a stream.
|
||||
|
||||
`void socketClientPushReceiveData(JsVar *connection, JsVar *socket, JsVar **receiveData)`
|
||||
|
||||
----
|
||||
|
||||
###socketClientConnectionsIdle
|
||||
Do idle processing on HTTP client connections.
|
||||
|
||||
`bool socketClientConnectionsIdle(JsNetwork *net)`
|
||||
|
||||
Walk through each of the socket connections for HTTP clients `HTTP_ARRAY_HTTP_CLIENT_CONNECTIONS (HttpCC)` and look
|
||||
for properties on them that are interpreted as instructions.
|
||||
|
||||
* `HTTP_NAME_CLOSENOW (closeNow)` - Close a socket.
|
||||
* `HTTP_NAME_RECEIVE_DATA (dRcv)` - Receive data.
|
||||
* `HTTP_NAME_CLOSE (close)` - Close a socket when done.
|
||||
|
||||
This function also polls the receive from the board.
|
||||
|
||||
----
|
||||
|
||||
###socketIdle
|
||||
Do idle processing on ??? connections.
|
||||
|
||||
`bool socketIdle(JsNetwork *net)`
|
||||
|
||||
Walk through each of the socket connections for ??? `HTTP_ARRAY_HTTP_SERVERS (HttpS)`.
|
||||
|
||||
We examine the socket to see if there is a pending connection upon it.
|
||||
|
||||
----
|
||||
|
||||
###serverNew
|
||||
Create a new server socket.
|
||||
|
||||
`JsVar *serverNew(SocketType socketType, JsVar *callback)`
|
||||
|
||||
Create a new server socket of the given socketType (one of `ST_NORMAL` or `ST_HTTP`). Add the
|
||||
callback function as a property of the new socket variable. The property is `HTTP_NAME_ON_CONNECT (#onconnect)`.
|
||||
Return the new socket variable. Note that this does NO network work other than create the socket JS var.
|
||||
|
||||
The variable returned is of class type `httpSrv` or `Server` depending on the socket type.
|
||||
|
||||
----
|
||||
|
||||
###serverListen
|
||||
|
||||
Start listening.
|
||||
|
||||
`void serverListen(JsNetwork *net, JsVar *server, int port)`
|
||||
|
||||
Create a real network connection for the socket JS variable supplied in `server` and cause it to start listening
|
||||
on the given port. The new socket is added to the list of server sockets `HTTP_ARRAY_HTTP_SERVERS (HttpS)`.
|
||||
|
||||
----
|
||||
|
||||
###serverClose
|
||||
Close the server socket.
|
||||
|
||||
`void serverClose(JsNetwork *net, JsVar *server)`
|
||||
|
||||
Close the server socket given by the socket JS variable supplied in `server`.
|
||||
|
||||
----
|
||||
|
||||
###clientRequestNew
|
||||
|
||||
Create a new client socket.
|
||||
|
||||
`JsVar *clientRequestNew(SocketType socketType, JsVar *options, JsVar *callback)`
|
||||
|
||||
The new socket is added to the list of client sockets `HTTP_ARRAY_HTTP_CLIENT_CONNECTIONS (HttpCC)`.
|
||||
We register the callback function named in `callback` with the `HTTP_NAME_ON_CONNECT (#onconnect)` method of the
|
||||
new socket variable.
|
||||
|
||||
The returned object is of class type `httpCCRs`, `httpCRq` or `Socket` depending on the socket type.
|
||||
|
||||
----
|
||||
|
||||
###clientRequestWrite
|
||||
Write some data to the client socket.
|
||||
|
||||
`void clientRequestWrite(JsVar *httpClientReqVar, JsVar *data)`
|
||||
|
||||
Write the data supplied by `data` to the client socket. This is implemented by adding the data to the property called `HTTP_NAME_SEND_DATA (dSnd)` property. The data is **not** actually sent by this function but is instead built and made available to be sent later.
|
||||
|
||||
----
|
||||
|
||||
###clientRequestConnect
|
||||
|
||||
Connect a socket to the server.
|
||||
|
||||
`void clientRequestConnect(JsNetwork *net, JsVar *httpClientReqVar)`
|
||||
|
||||
Connect a socket to the server. The variable supplies as a socket variable is expected to have a property on it called
|
||||
`HTTP_NAME_OPTIONS_VAR (opt)` which has a property called `port` which is the port number to connect with. In addition
|
||||
it should have a property called `host` that is the target host.
|
||||
|
||||
----
|
||||
|
||||
###clientRequestEnd
|
||||
|
||||
Signal the end of the socket.
|
||||
|
||||
`void clientRequestEnd(JsNetwork *net, JsVar *httpClientReqVar)`
|
||||
|
||||
Things get strange here based on the type of socket with which we are working. If the type is
|
||||
`ST_HTTP` we actually perform a connect request!!! For normal sockets, we register that we are
|
||||
ready to close after all the data has been sent. This is done by setting the `HTTP_NAME_CLOSE (close)` flag.
|
||||
|
||||
----
|
||||
|
||||
###serverResponseWriteHead
|
||||
|
||||
Set the HTTP response code and headers.
|
||||
|
||||
`void serverResponseWriteHead(JsVar *httpServerResponseVar, int statusCode, JsVar *headers)`
|
||||
|
||||
Record the HTTP response code and headers to be sent back to the partner.
|
||||
|
||||
----
|
||||
|
||||
###serverResponseWrite
|
||||
|
||||
Set the data to be sent back to the partner.
|
||||
|
||||
`void serverResponseWrite(JsVar *httpServerResponseVar, JsVar *data)`
|
||||
|
||||
Set the data to be sent back to the partner.
|
||||
|
||||
----
|
||||
|
||||
###serverResponseEnd
|
||||
|
||||
Write the data and flag the close of the connection.
|
||||
|
||||
`void serverResponseEnd(JsVar *httpServerResponseVar)`
|
||||
|
||||
Write the data and flag the close of the connection.
|
||||
|
||||
----
|
||||
|
||||
#ESP8266 Implementation Notes
|
||||
|
||||
It looks like we are going to have a problem with `gethostbyname()`. This appears to be a blocking call in Espruino while in the ESP8266 it is a callback function.
|
||||
The equivalent ESP8266 API is `espconn_gethostbyname()` which takes a callback that will be invoked when the host name is resolved.
|
||||
|
||||
----
|
||||
|
||||
#The net library
|
||||
|
||||
The net library brings together the network routines and the socket routines into a
|
||||
high level composed form.
|
||||
|
||||
* jswrap\_net\_idle - Type: idle
|
||||
* jswrap\_net\_init - Type: init
|
||||
* jswrap\_net\_kill - Type: kill
|
||||
* jswrap\_url\_parse - Type: staticmethod, class: url
|
||||
* jswrap\_net\_createServer - Type: staticmethod, class: net, return: Server
|
||||
* jswrap\_net\_connect - Type: staticmethod, class: net, return: Socket
|
||||
* jswrap\_net\_server_listen - Type: method, class: Server
|
||||
* jswrap\_net\_server_close - Type: method, Class: Server
|
||||
* jswrap\_net\_socket_write - Type: method, Class: Socket
|
||||
* jswrap\_net\_socket_end - Type: method, Class: Socket
|
||||
* jswrap\_stream\_available - Type: method, Class: Socket
|
||||
* jswrap\_stream\_read - Type: method, Class: Socket
|
||||
|
||||
----
|
||||
##jswrap\_net\_idle
|
||||
|
||||
Perform the idle processing.
|
||||
|
||||
`bool jswrap_net_idle()`
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_net\_init
|
||||
|
||||
Initialize the network stuff.
|
||||
|
||||
`void jswrap_net_init()`
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_net\_kill
|
||||
|
||||
Destory the network.
|
||||
|
||||
`void jswrap_net_kill()`
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_url\_parse
|
||||
|
||||
Parse a URL string.
|
||||
|
||||
`JsVar *jswrap_url_parse(JsVar *url, bool parseQuery)`
|
||||
|
||||
The `url` variable is a String that is to be parsed. If `parseQuery` is true, we also parse
|
||||
any query data passed in. The object that is returned contains:
|
||||
|
||||
* method
|
||||
* host
|
||||
* path
|
||||
* pathname
|
||||
* port
|
||||
* search
|
||||
* query
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_net\_createServer
|
||||
|
||||
Create a new ST_NORMAL type server.
|
||||
|
||||
`JsVar *jswrap_net_createServer(JsVar *callback)`
|
||||
|
||||
Mostly a pass through to `serverNew`. The return type is a JS object of type `Server`.
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_net\_connect
|
||||
|
||||
Form a connection to a client connection to a partner.
|
||||
|
||||
`JsVar *jswrap_net_connect(JsVar *options, JsVar *callback, SocketType socketType)`
|
||||
|
||||
If `options` is a string, then we parse it as a URL string otherwise it should be
|
||||
an object such as that returned by `jswrap_url_parse`.
|
||||
|
||||
The socket type is one of:
|
||||
|
||||
* `ST_NORMAL` - 0
|
||||
* `ST_HTTP` - 1
|
||||
|
||||
The variable returned is a socket object. The logic in this function calls
|
||||
`clientRequestNew` and if we are **not** an ST_HTTP socket, then we call
|
||||
`clientRequestConnect`. The return is the object returned from `clientRequestNew` which means it
|
||||
is an instance of class type `httpCCRs`, `httpCRq` or `Socket` depending on the socket type.
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_net\_server\_listen
|
||||
|
||||
Start a server listening.
|
||||
|
||||
`void jswrap_net_server_listen(JsVar *parent, int port)`
|
||||
|
||||
Set the server listening. The port on which it will listen is supplied by `port`. This is
|
||||
mostly a pass through to `serverListen`.
|
||||
|
||||
This function is mapped to the following JavaScript methods:
|
||||
|
||||
* `httpSrv.listen()`
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_net\_server\_close
|
||||
|
||||
`void jswrap_net_server_close(JsVar *parent)`
|
||||
|
||||
Close the server. This is mostly a pass through to `serverClose`.
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_net\_socket\_write
|
||||
|
||||
Write data through the socket.
|
||||
|
||||
`bool jswrap_net_socket_write(JsVar *socketVar, JsVar *data)`
|
||||
|
||||
The `data` is the new data to write. This is a pass through to `clientRequestWrite`.
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_net\_socket\_end
|
||||
|
||||
Close the socket with optional data.
|
||||
|
||||
`void jswrap_net_socket_end(JsVar *parent, JsVar *data)`
|
||||
|
||||
This is a pass through to `clientRequestEnd`.
|
||||
|
||||
----
|
||||
|
||||
#The HTTP Subsystem
|
||||
A library is provided that allows Espruino to perform HTTP services. There are two flavors to this. The first is that the Espruino can behave as an HTTP client (i.e. a browser or REST caller) and transmit and receive HTTP request.
|
||||
|
||||
Secondly, the Espruino can become an HTTP server and listen for incoming requests from browsers or REST clients.
|
||||
|
||||
To be a server, one would use:
|
||||
|
||||
var http = require("http");
|
||||
var httpSrv = http.createServer(function(request, response) {
|
||||
// We have a new request here!!
|
||||
});
|
||||
httpSrv.listen(80);
|
||||
|
||||
Should we wish the server to stop listening for new incomming connections we can call `httpSrv.close()`.
|
||||
|
||||
On the other side of the coin, we may wish the ESP8266 to be an HTTP client making HTTP requests in the same fashion as a browser or as a REST client.
|
||||
|
||||
We can perform a
|
||||
|
||||
http.get({
|
||||
host: "ipAddress",
|
||||
port: <portNumber>
|
||||
}, function(response) {
|
||||
// Handle response
|
||||
});
|
||||
|
||||
The HTTP subsystem is implemented in `jswrap_http.c`.
|
||||
|
||||
* `jswrap_http_createServer`
|
||||
* `jswrap_http_get`
|
||||
* `jswrap_httpSRs_write`
|
||||
* `jswrap_httpSRs_end`
|
||||
* `jswrap_httpSRs_writeHead`
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_http\_createServer
|
||||
|
||||
|
||||
`JsVar *jswrap_http_createServer(JsVar *callback)`
|
||||
|
||||
The callback function supplied in the `callback` parameter is invoked when a new browse connection is received. The callback function
|
||||
has the form:
|
||||
|
||||
|
||||
function(request, response)
|
||||
|
||||
Where request is the connection for the incoming data and response is the connection for the outgoing data. For example, we can write data to the "response" object
|
||||
and read data from the "request" object.
|
||||
|
||||
The return from the `jswrap_http_createServer` function is an instance of an `httpSrv` object.
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_http\_get
|
||||
|
||||
`JsVar *jswrap_http_get(JsVar *options, JsVar *callback)`
|
||||
|
||||
Send an HTTP request to an HTTP server. The `options` variable defines the parameters of the connection and includes properties for `host` and `port`. The `callback` function is a function that will be invoked when a response is received. The signature of that functions is:
|
||||
|
||||
function(response)
|
||||
|
||||
Where response can be used to retrieve data and determine when the response connection is closed.
|
||||
|
||||
The `jswrap_http_get` returns an instance of an `httpCRq` objetct.
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_httpSRs\_write
|
||||
|
||||
`bool jswrap_httpSRs_write(JsVar *parent, JsVar *data)`
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_httpSRs\_end
|
||||
|
||||
`void jswrap_httpSRs_end(JsVar *parent, JsVar *data)`
|
||||
|
||||
----
|
||||
|
||||
##jswrap\_httpSRs\_writeHead
|
||||
|
||||
`void jswrap_httpSRs_writeHead(JsVar *parent, int statusCode, JsVar *headers)`
|
||||
|
||||
----
|
||||
|
||||
#End User network programming
|
||||
From a programmers perspective who is writing JS networking, there is a library exposed called `net`. I has the following exposed methods:
|
||||
|
||||
* `net.connect` - Connect to a partner
|
||||
* `net.createServer` - Become a server
|
||||
|
||||
There also appears to be classes that leverage this library. These classes are `Socket` and `Server`.
|
||||
|
||||
##Socket
|
||||
###Socket.available
|
||||
Socket.available()
|
||||
|
||||
Returns how many bytes are available to be read.
|
||||
|
||||
###Socket.end
|
||||
Close the socket.
|
||||
|
||||
###Socket.pipe
|
||||
Pipe the data to a stream.
|
||||
|
||||
###Socket.read
|
||||
Read some characters from the socket.
|
||||
|
||||
###Socket.write
|
||||
Write some data to the socket.
|
||||
|
||||
###Socket.close
|
||||
Event: Called when the connection closes.
|
||||
|
||||
###Socket.data
|
||||
Event: Called when data has been received and is available to be read.
|
||||
|
||||
###Socket.drain
|
||||
Event: Called when the data has been transmitted and new data can be sent.
|
||||
|
||||
##Server
|
||||
|
||||
----
|
||||
#Adding a new network device
|
||||
To add a new network device, the device must initialize the Espruino environment by calling
|
||||
|
||||
networkCreate and then networkSet. Here is an example piece of code:
|
||||
|
||||
JsNetwork net;
|
||||
networkCreate(&net, JSNETWORKTYPE_ESP8266_BOARD);
|
||||
networkSet(&net);
|
||||
|
||||
In the network.c file there is a bootstrap mechanism in the function called `networkGetFromVar` which switches on the network type and calls a function called `netSetCallbacks_<networkType>`.
|
||||
|
||||
It appears that we have to supply the following functions
|
||||
* `int net_<board>_accept(JsNetwork *net, int serverSckt)`
|
||||
* `int net_<board>_recv(JsNetwork *net, int sckt, void *buf, size_t len)` - Return the number of
|
||||
bytes actually sent.
|
||||
* `int net_<board>_send(JsNetwork *net, int sckt, const void *buf, size_t len)`
|
||||
* `void net_<board>_idle(JsNetwork *net)`
|
||||
* `bool net_<board>_checkError(JsNetwork *net)`
|
||||
* `int net_<board>_createSocket(JsNetwork *net, uint32_t host, unsigned short port)`
|
||||
* `void net_<board>_closeSocket(JsNetwork *net, int sckt)`
|
||||
* `void net_<board>_gethostbyname(JsNetwork *net, char *hostName, uint32_t *outIp)`
|
||||
|
||||
----
|
||||
|
||||
#API Reference
|
||||
|
||||
----
|
||||
|
||||
####networkGetAddressAsString
|
||||
|
||||
#####Call type:
|
||||
`JsVar *networkGetAddressAsString(unsigned char *ip, int nBytes, unsigned int base, char separator)`
|
||||
|
||||
#####Description
|
||||
Return a JS variable that represents the IP address.
|
||||
|
||||
#####Parameters
|
||||
* `ip` - The IP address in memory.
|
||||
* `nBytes` - The size of the IP address (usually 4).
|
||||
* `base` - The base representation (usually 10 for decimal).
|
||||
* `separator` - The separator character (usually '.').
|
||||
|
||||
#####Returns
|
||||
A representation of the IP address.
|
||||
|
||||
----
|
||||
|
||||
####networkParseIPAddress
|
||||
|
||||
#####Call Type:
|
||||
|
||||
`uint32_t networkParseIPAddress(const char *ip)`
|
||||
|
||||
#####Description
|
||||
|
||||
Parse a string representation of an IP address and return an IP address.
|
||||
|
||||
#####Parameters
|
||||
|
||||
A string representation of an IP address.
|
||||
|
||||
#####Returns
|
||||
|
||||
A 4 byte IP address.
|
||||
109
targets/esp8266/docs/68-Espruino-GPIO.md
Normal file
109
targets/esp8266/docs/68-Espruino-GPIO.md
Normal file
@ -0,0 +1,109 @@
|
||||
GPIO is the ability to drive IO through commands. The functions that relate to GPIO are:
|
||||
|
||||
* digitalRead
|
||||
* digitalWrite
|
||||
* digitalPulse
|
||||
* getPinMode
|
||||
* pinMode
|
||||
|
||||
From an Espruino implementation perspective, the contract is implemented in the ESP8266 specific jshardware.c source file. We are responsible
|
||||
for implementing the following functions
|
||||
|
||||
void jshPinSetState(Pin pin, JshPinState state)
|
||||
JshPinState jshPinGetSate(Pin pin)
|
||||
void jshPinSetValue(Pin pin, bool value)
|
||||
bool jshPinGetValue(Pin pin)
|
||||
JsVarFloar jshPinAnalog(Pin pin)
|
||||
int jshPinAnalogFast(Pin pin)
|
||||
JshPinFunction jshPinAnalogOutput(Pin pin,
|
||||
JsVarFloat value,
|
||||
JsVarFloat freq,
|
||||
JshAnalogOutputFlags flags)
|
||||
void jshPinPulse(Pin pin, bool value, JsVarFloat time)
|
||||
bool jshCanWatch(Pin pin)
|
||||
IOEventFlags jshPinWatch(Pin pin, bool shouldWatch)
|
||||
JshPinFunction jshGetCurrentPinFunction(Pin pin)
|
||||
bool jshIsEventForPin(IOEvent *event, Pin pin)
|
||||
IOEventFlags pinToEVEXTI(Pin pin)
|
||||
|
||||
The `Pin` data type is simply an `unsigned char`.
|
||||
|
||||
There is also a Pin Class. This has methods for:
|
||||
|
||||
* constructor
|
||||
* getMode
|
||||
* mode
|
||||
* read
|
||||
* reset - Set the pin to a 0
|
||||
* set - Set the pin to a 1
|
||||
* write
|
||||
* writeAtTime
|
||||
|
||||
For example, to create a definition for a Pin we might code:
|
||||
|
||||
var myGPIO0 = new Pin(0);
|
||||
|
||||
To write a value we might code:
|
||||
|
||||
myGPIO0.write(true);
|
||||
|
||||
or
|
||||
|
||||
digitalWrite(myGPIO0, true);
|
||||
|
||||
The JshPinStates are:
|
||||
|
||||
* `JSHPINSTATE_UNDEFINED` = 0
|
||||
* `JSHPINSTATE_GPIO_OUT` = 1
|
||||
* `JSHPINSTATE_GPIO_OUT_OPENDRAIN` = 2
|
||||
* `JSHPINSTATE_GPIO_IN` = 3
|
||||
* `JSHPINSTATE_GPIO_IN_PULLUP` = 4
|
||||
* `JSHPINSTATE_GPIO_IN_PULLDOWN` = 5
|
||||
* `JSHPINSTATE_ADC_IN` = 6
|
||||
* `JSHPINSTATE_AF_OUT` = 7
|
||||
* `JSHPINSTATE_AF_OUT_OPENDRAIN` = 8
|
||||
* `JSHPINSTATE_USART_IN` = 9
|
||||
* `JSHPINSTATE_USART_OUT` = 10
|
||||
* `JSHPINSTATE_DAC_OUT` = 11
|
||||
* `JSHPINSTATE_I2C` = 12
|
||||
|
||||
In the build environment in the `boards` folder, there is a Python script for each of the board types. Within this script we define a function which describes the pins available for each board. For the ESP8266, we have a script called `ESP8266_BOARD.py` which defines the available pins.
|
||||
|
||||
#####devices
|
||||
|
||||
This is a list of built-in stuff on the board that is made accessible to Espruino. It's parsed and turned into defines `in gen/platform_config.h`.
|
||||
|
||||
Stuff you can use is LED1-8, BTN1-4, USB, LCD (for boards with FSMC LCDs built in), SD (SD card), JTAG (when JTAG pins are defined, but we need to make sure we leave them alone when the board resets).
|
||||
|
||||
A helper script is supplied by the Espruino build system called `pinutils.py`. It contains utility functions:
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
######generate_pins
|
||||
Return a set of pins from `min_pin` to `max_pin` inclusive.
|
||||
|
||||
generate_pins(min_pin, max_pin)
|
||||
|
||||
This is achieved by calling `findpin` for each of the pins in the range with a name of `PD<Num>`.
|
||||
|
||||
The format returned is an array of Pin objects where each of these contains:
|
||||
|
||||
* `name` is the pin name - due to random historical reasons (from ST datasheets) it needs prefixing with `P`.
|
||||
* `sortingname` is the name, but padded so that when it's sorted everything appears in the right order
|
||||
port is the actual port - on ESP8266 this might not be needed and could just default to `D`.
|
||||
* `num` is the pin number - this doesn't have to match `D` - it's what is needed internally to access the hardware. For instance Olimexino has 'logical' pins that actually map all over the place.
|
||||
* `function` is a map of pin functions to their 'alternate functions' (an STM32 chip thing - STM32F4 chips can have different peripherals on each pin, so the alternate function is a number that you shove in that pin's register in order to connect it to that peripheral). The format, for instance I2C1_SDA is important as it's parsed later and is used to build `gen/jspininfo.c`.
|
||||
* `csv` isn't needed afaik, but when using data grabbed from csv files from ST's datasheets like this it contains the raw data for debugging)
|
||||
|
||||
----
|
||||
|
||||
######findpin
|
||||
Find and add a new pin to the list of pins. Returns the new pin.
|
||||
|
||||
findpin(pins, pinname, force)
|
||||
|
||||
Find the pin definition with the name `pinname` and add it to the list of pins supplied by `pins`. If
|
||||
`force` is `true` and the named pin is not known, then an error is generated otherwise a new default pin
|
||||
is created.
|
||||
28
targets/esp8266/docs/70-ESP8266-Native-Functions.md
Normal file
28
targets/esp8266/docs/70-ESP8266-Native-Functions.md
Normal file
@ -0,0 +1,28 @@
|
||||
For the ESP8266 project, we will need native functions. These are functions exposed to the JS programmer that are implemented as native C code as opposed to JS. These functions can then leverage the implementation capabilities provided by the ESP8266 SDK.
|
||||
|
||||
Examples of objects containing such functions will include:
|
||||
|
||||
* `ESP8266WiFi` - Access to native ESP8266 WiFi.
|
||||
|
||||
See also:
|
||||
* [Espruino native functions](https://github.com/espruino/Espruino/tree/master/libs)
|
||||
|
||||
|
||||
To define a new native set of functions, we need to annotate the source code of functions we wish to expose. The format is:
|
||||
|
||||
/*JSON{
|
||||
"type" : "staticmethod",
|
||||
"class" : "ESP8266WiFi",
|
||||
"name" : "setAutoconnect",
|
||||
"generate" : "jswrap_ESP8266WiFi_setAutoconnect",
|
||||
"generate_full": ???,
|
||||
"params" : [
|
||||
["autoconnect","JsVar","True if we wish to autoconnect."]
|
||||
],
|
||||
"return" : ["JsVar","A boolean representing our auto connect status"],
|
||||
"return_object" : "Restart"
|
||||
}*/
|
||||
|
||||
It is not yet known the meanings and values of these nor which are optional vs mandatory nor whether there are additional settings not yet discovered.
|
||||
|
||||
* `type` - Values seen include `class`, `staticmethod`, `method`, `library`, `event`, `idle`, `init`, `kill`.
|
||||
36
targets/esp8266/docs/80-The-platform_config.h.md
Normal file
36
targets/esp8266/docs/80-The-platform_config.h.md
Normal file
@ -0,0 +1,36 @@
|
||||
The Espruino build system generates a header file called `platform_config.h`. This file is a header file with a bunch of configuration settings. Do **not** edit this file directly. It is re-built by the makesystem.
|
||||
|
||||
* `PC_BOARD_ID` - "ESP8266_ESP12"
|
||||
* `PC_BOARD_CHIP` - "ESP8266"
|
||||
* `PC_BOARD_CHIP_FAMILY` - "ESP8266"
|
||||
* `SYSTICK_RANGE` - 0x1000000
|
||||
* `SYSTICKS_BEFORE_USB_DISCONNECT` - 2
|
||||
|
||||
* `DEFAULT_BUSY_PIN_INDICATOR` - (Pin)-1
|
||||
* `DEFAULT_SLEEP_PIN_INDICATOR` - (Pin)-1
|
||||
* `IOBUFFER_XOFF` - ((TXBUFFERMASK)*6/8)
|
||||
* `IOBUFFER_XON` - ((TXBUFFERMASK)*3/8)
|
||||
* `RAM_TOTAL` - (80*1024)
|
||||
* `FLASH_TOTAL` - (512*1024)
|
||||
* `JSVAR_CACHE_SIZE` - 1023
|
||||
* `FLASH_AVAILABLE_FOR_CODE` - 506893.0
|
||||
* `FLASH_PAGE_SIZE` - 1024
|
||||
* `FLASH_START` - 0x8000000
|
||||
* `FLASH_SAVED_CODE_START` - (FLASH_START + FLASH_TOTAL - FLASH_SAVED_CODE_LENGTH)
|
||||
* `FLASH_SAVED_CODE_LENGTH` - 17395.0
|
||||
* `FLASH_MAGIC_LOCATION` - (FLASH_SAVED_CODE_START + FLASH_SAVED_CODE_LENGTH - 4)
|
||||
* `FLASH_MAGIC` ` 0xDEADBEEF
|
||||
* `USARTS` - 1
|
||||
* `SPIS` - 0
|
||||
* `I2CS` - 0
|
||||
* `ADCS` - 0
|
||||
* `DACS` - 0
|
||||
* `DEFAULT_CONSOLE_DEVICE` - EV_SERIAL1
|
||||
* `IOBUFFERMASK` - 127
|
||||
* `TXBUFFERMASK` - 127
|
||||
* `UTILTIMERTASK_TASKS` - (16)
|
||||
* `IS_PIN_USED_INTERNALLY(PIN)` - ((false))
|
||||
* `IS_PIN_A_LED(PIN)` - ((false))
|
||||
* `IS_PIN_A_BUTTON(PIN)` - ((false))
|
||||
|
||||
|
||||
3
targets/esp8266/docs/90-Bug-list.md
Normal file
3
targets/esp8266/docs/90-Bug-list.md
Normal file
@ -0,0 +1,3 @@
|
||||
This page logs bugs/problems/defects/broken code that needs addressed.
|
||||
|
||||
* 2015-09-23 - Calling ESP8266WiFi.setAutoconnect(false) breaks something.
|
||||
6
targets/esp8266/docs/95-Wish-list.md
Normal file
6
targets/esp8266/docs/95-Wish-list.md
Normal file
@ -0,0 +1,6 @@
|
||||
As experience and knowledge grow on the use of the port, there are times when we find items that
|
||||
could be enhanced, added or otherwise improved. This page will log the work items to be performed.
|
||||
|
||||
* 2015-09-23 - Provide a mechanism to redirect UART1 debug to the console.
|
||||
* 2015-09-23 - Make ESP8266 a library rather than a static module.
|
||||
* 2015-09-26 - Have getIPInfo() also return string dotted decimals.
|
||||
83
targets/esp8266/docs/96-Memory-Management.md
Normal file
83
targets/esp8266/docs/96-Memory-Management.md
Normal file
@ -0,0 +1,83 @@
|
||||
# How Javascript Code Affects memory
|
||||
|
||||
## Current Memory Available
|
||||
|
||||
On a NodeMCU, a program that only has the following line:
|
||||
`setTimeout("print(process.memory());", 1);`
|
||||
Yields this memory profile:
|
||||
`{ "free": 992, "usage": 31, "total": 1023, "history": 11 }`
|
||||
|
||||
According to [Espruino Internals](http://www.espruino.com/Internals), each memory unit is 12 bytes, so we start with something like 12k of memory.
|
||||
|
||||
## Variables
|
||||
|
||||
### Setting a global var to a zero sized string:
|
||||
```
|
||||
m='';
|
||||
setTimeout("print(process.memory());", 1);
|
||||
```
|
||||
`{ "free": 991, "usage": 32, "total": 1023, "history": 14 }`
|
||||
|
||||
The data is stored as a linked list in memory, so the variable itself is one block (>4 char var names take more 12 byte blocks).
|
||||
|
||||
Hint: Keep your variable names to a max of 4 characters.
|
||||
|
||||
It is not clear where the language elements `=` and `;` are stored. (needs an answer)
|
||||
|
||||
## Penalty for storing text to a variable.
|
||||
|
||||
```
|
||||
m='012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
|
||||
print(process.memory());
|
||||
```
|
||||
`{ "free": 966, "usage": 57, "total": 1023, "history": 37 }`
|
||||
|
||||
This is 240 char string takes 360 bytes to store. That is a 50% penalty. According to [Espruino Performance](http://www.espruino.com/Performance) It should take Each 12 Bytes should take 16 Bytes
|
||||
|
||||
Hint: Minimize the length of variables holding strings.
|
||||
|
||||
## Literals Apparently Don't Take Any Memory
|
||||
```
|
||||
t='';
|
||||
if (t==='');
|
||||
setTimeout("print(process.memory());", 1);
|
||||
```
|
||||
{ "free": 990, "usage": 33, "total": 1023, "history": 20 }
|
||||
|
||||
now lets see if t is equal to a 240 char literal:
|
||||
|
||||
```
|
||||
t='';
|
||||
if (t==='012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789');
|
||||
setTimeout("print(process.memory());", 1);
|
||||
```
|
||||
{ "free": 990, "usage": 33, "total": 1023, "history": 20 }
|
||||
|
||||
Hint: Literal should be used instead of variables when possible.
|
||||
|
||||
## 12 Bytes per Variable vs 16 Bytes per Variable
|
||||
|
||||
If you create more than 256 variables, then Espruino needs 16 bytes per variable.
|
||||
|
||||
Regular Javascript arrays Take 2 blocks per value element. There are non-Javascript typed arrays that are more efficient if you data fits the pattern (all Integers, etc.). A small Integer can type one Block per element. See
|
||||
[Espruino Performance](http://www.espruino.com/Performance).
|
||||
|
||||
Javascript Objects can be even less memory efficient. Assuming 12 Byte blocks, If your Object index is > 8 bytes, it takes two or more blocks just for the index.
|
||||
|
||||
You can see how much memory an element takes using [E.getSizeOf(...)](http://www.espruino.com/Reference#l_E_getSizeOf):
|
||||
|
||||
Hint: Carefully engineer JSON objects or replace them with typed Arrays.
|
||||
|
||||
## Avoid Long Commands
|
||||
|
||||
`String.fromCharCode()` If you have something like this scattered throughout your program, make a short named function.
|
||||
|
||||
When you create functions, give them short names. This is mitigated (actually rendered unnecessary if you turn on Closure [Simple Optimizations] in the Minification part of the IDE).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
targets/esp8266/docs/images/Socket State Diagram.png
Normal file
BIN
targets/esp8266/docs/images/Socket State Diagram.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
551
targets/esp8266/docs/images/Socket State Diagram.svg
Normal file
551
targets/esp8266/docs/images/Socket State Diagram.svg
Normal file
@ -0,0 +1,551 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="8.5in"
|
||||
height="11in"
|
||||
viewBox="0 0 765 990"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="Socket State Diagram.svg"
|
||||
inkscape:export-filename="P:\ESP8266\Projects\Espruino\Socket State Diagram.png"
|
||||
inkscape:export-xdpi="80.209999"
|
||||
inkscape:export-ydpi="80.209999">
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker4555"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4557"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker4423"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
id="path4425" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker5680"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend">
|
||||
<path
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
id="path5682" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker4236"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path4238"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker4756"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend">
|
||||
<path
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
id="path4758" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker4696"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
id="path4698" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker4642"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend">
|
||||
<path
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
id="path4644" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker4580"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend">
|
||||
<path
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
id="path4582" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker4538"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path4540"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4243"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(1.1) rotate(180) translate(1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Lend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path4225"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.84343435"
|
||||
inkscape:cx="346.66229"
|
||||
inkscape:cy="770.35069"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="in"
|
||||
inkscape:window-width="1707"
|
||||
inkscape:window-height="1004"
|
||||
inkscape:window-x="1699"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-62.362205)">
|
||||
<g
|
||||
id="g4288"
|
||||
transform="translate(-13.041916,-82.994011)">
|
||||
<ellipse
|
||||
ry="35.568863"
|
||||
rx="41.497005"
|
||||
cy="243.7634"
|
||||
cx="150.57484"
|
||||
id="path3336"
|
||||
style="fill:#e5ff80;stroke:#000000;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3338"
|
||||
y="250.87718"
|
||||
x="119.30538"
|
||||
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="250.87718"
|
||||
x="119.30538"
|
||||
id="tspan3340"
|
||||
sodipodi:role="line">UNUSED</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g4262">
|
||||
<ellipse
|
||||
inkscape:connector-avoid="true"
|
||||
style="fill:#e5ff80;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
||||
id="ellipse3342"
|
||||
cx="291.66467"
|
||||
cy="422.79333"
|
||||
rx="67.580833"
|
||||
ry="35.568863" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="238.31137"
|
||||
y="429.90714"
|
||||
id="text3344"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3346"
|
||||
x="238.31137"
|
||||
y="429.90714">CONNECTING</tspan></text>
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="390.02255"
|
||||
y="-97.758171"
|
||||
id="text3356"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="matrix(0.39973232,0.91663192,-0.91663192,0.39973232,0,0)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3358"
|
||||
x="390.02255"
|
||||
y="-97.758171"
|
||||
style="font-size:12.5px;text-align:center;text-anchor:middle">createSocket</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="390.02255"
|
||||
y="-82.133171"
|
||||
style="font-size:12.5px;text-align:center;text-anchor:middle"
|
||||
id="tspan3382">(client - Numeric)</tspan></text>
|
||||
<g
|
||||
id="g4267">
|
||||
<ellipse
|
||||
style="fill:#e5ff80;stroke:#000000;stroke-opacity:1"
|
||||
id="ellipse3360"
|
||||
cx="457.65268"
|
||||
cy="592.33826"
|
||||
rx="41.497005"
|
||||
ry="35.568863" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="442.38324"
|
||||
y="599.45203"
|
||||
id="text3362"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3364"
|
||||
x="442.38324"
|
||||
y="599.45203">IDLE</tspan></text>
|
||||
</g>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3368"
|
||||
y="64.64711"
|
||||
x="592.67859"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.66297083,0.74864522,-0.74864522,0.66297083,0,0)"><tspan
|
||||
style="font-size:12.5px;fill:#0000ff"
|
||||
y="64.64711"
|
||||
x="592.67859"
|
||||
id="tspan3370"
|
||||
sodipodi:role="line">connectCB</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3376"
|
||||
y="67.334503"
|
||||
x="408.59506"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.95957369,0.28145751,-0.28145751,0.95957369,0,0)"><tspan
|
||||
style="font-size:12.5px;text-align:center;text-anchor:middle"
|
||||
y="67.334503"
|
||||
x="408.59506"
|
||||
id="tspan3378"
|
||||
sodipodi:role="line">createSocket</tspan><tspan
|
||||
style="font-size:12.5px;text-align:center;text-anchor:middle"
|
||||
y="82.959496"
|
||||
x="408.59506"
|
||||
sodipodi:role="line"
|
||||
id="tspan3380">(server)</tspan></text>
|
||||
<g
|
||||
id="g4272">
|
||||
<ellipse
|
||||
ry="35.568863"
|
||||
rx="67.580833"
|
||||
cy="697.85925"
|
||||
cx="227.64073"
|
||||
id="ellipse3392"
|
||||
style="fill:#e5ff80;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
||||
inkscape:connector-avoid="true" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3394"
|
||||
y="704.97302"
|
||||
x="166.28743"
|
||||
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="704.97302"
|
||||
x="166.28743"
|
||||
id="tspan3396"
|
||||
sodipodi:role="line">TRANSMITTING</tspan></text>
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 457.65268,592.33826 0,0"
|
||||
id="path3404"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:connection-start="#ellipse3360"
|
||||
inkscape:connection-end="#ellipse3360" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="8.0183506"
|
||||
y="730.32489"
|
||||
id="text3408"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="matrix(0.89147198,-0.45307583,0.45307583,0.89147198,0,0)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3410"
|
||||
x="8.0183506"
|
||||
y="730.32489"
|
||||
style="font-size:12.5px">send</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="368.9581"
|
||||
y="713.78735"
|
||||
id="text3414"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3416"
|
||||
x="368.9581"
|
||||
y="713.78735"
|
||||
style="font-size:12.5px;fill:#0000ff">sendCB</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4538)"
|
||||
d="m 163.61677,188.03884 86.8473,203.33534"
|
||||
id="path4536"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4580)"
|
||||
d="M 329.60479,452.43407 429.1976,562.69754"
|
||||
id="path4572"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
|
||||
d="m 178.04773,153.33303 331.92246,86.19343 -56.4672,314.27885"
|
||||
id="path4620"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4642)"
|
||||
d="m 297.59282,701.4161 118.56287,0 31.12275,-71.73054"
|
||||
id="path4634"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4696)"
|
||||
d="M 419.71257,606.56579 286.92216,677.70353"
|
||||
id="path4688"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
id="g4283">
|
||||
<ellipse
|
||||
ry="35.568863"
|
||||
rx="52.16766"
|
||||
cy="519.18677"
|
||||
cx="162.0984"
|
||||
id="ellipse4222"
|
||||
style="fill:#e5ff80;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
||||
inkscape:connector-avoid="true" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4224"
|
||||
y="526.3006"
|
||||
x="124.15822"
|
||||
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="526.3006"
|
||||
x="124.15822"
|
||||
id="tspan4226"
|
||||
sodipodi:role="line">CLOSING</tspan></text>
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4234"
|
||||
d="M 417.74542,582.33232 214.63319,529.63954"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4236)"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
transform="matrix(0.97456445,0.22410743,-0.22410743,0.97456445,0,0)"
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4654"
|
||||
y="483.02386"
|
||||
x="443.42905"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"
|
||||
inkscape:transform-center-x="1.8783505"
|
||||
inkscape:transform-center-y="3.2543372"><tspan
|
||||
style="font-size:12.5px;text-align:center;text-anchor:middle"
|
||||
y="483.02386"
|
||||
x="443.42905"
|
||||
sodipodi:role="line"
|
||||
id="tspan4656">closeSocket</tspan></text>
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker5680)"
|
||||
d="M 159.52865,482.77634 140.39054,197.05797"
|
||||
id="path5678"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
transform="matrix(0.05815588,0.99830751,-0.99830751,0.05815588,0,0)"
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="358.88785"
|
||||
y="-114.47015"
|
||||
id="text6146"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6148"
|
||||
x="358.88785"
|
||||
y="-114.47015"
|
||||
style="font-size:12.5px;fill:#0000ff">disconnectCB</tspan></text>
|
||||
<g
|
||||
id="g4256"
|
||||
transform="translate(80.02994,130.41916)">
|
||||
<ellipse
|
||||
style="fill:#e5ff80;stroke:#000000;stroke-width:1;stroke-opacity:1"
|
||||
id="ellipse4244"
|
||||
cx="301.14969"
|
||||
cy="160.02687"
|
||||
rx="82.994011"
|
||||
ry="32.011978" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="300.63837"
|
||||
y="166.69754"
|
||||
id="text4246"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
style="text-align:center;text-anchor:middle"
|
||||
id="tspan4250"
|
||||
sodipodi:role="line"
|
||||
x="300.63837"
|
||||
y="166.69754">HOST_RESOLVING</tspan><tspan
|
||||
id="tspan4254"
|
||||
style="text-align:center;text-anchor:middle"
|
||||
sodipodi:role="line"
|
||||
x="300.63837"
|
||||
y="185.44754" /></text>
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4421"
|
||||
d="m 171.91617,179.73945 168.06288,82.994"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4423)" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4555)"
|
||||
d="m 386.51497,322.01489 -55.42814,69.35929"
|
||||
id="path4553"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
transform="matrix(0.89752704,0.44095943,-0.44095943,0.89752704,0,0)"
|
||||
sodipodi:linespacing="125%"
|
||||
id="text5357"
|
||||
y="62.582497"
|
||||
x="336.10559"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:12.5px;text-align:center;text-anchor:middle"
|
||||
y="62.582497"
|
||||
x="336.10559"
|
||||
id="tspan5359"
|
||||
sodipodi:role="line">createSocket</tspan><tspan
|
||||
id="tspan5361"
|
||||
style="font-size:12.5px;text-align:center;text-anchor:middle"
|
||||
y="78.207497"
|
||||
x="336.10559"
|
||||
sodipodi:role="line">(client - hostname)</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text5679"
|
||||
y="520.05176"
|
||||
x="-89.269897"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"
|
||||
transform="matrix(0.617761,-0.78636591,0.78636591,0.617761,0,0)"><tspan
|
||||
style="font-size:12.5px;fill:#0000ff"
|
||||
y="520.05176"
|
||||
x="-89.269897"
|
||||
id="tspan5681"
|
||||
sodipodi:role="line">hostnameCB</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 22 KiB |
Loading…
x
Reference in New Issue
Block a user