When implementing a new network component for a new board (eg. ESP8266), we have to create a function that is mapped to the JsNetwork send function. This is a function with the following signature:
int send(struct JsNetwork *net, int sckt, const void *buf, size_t len)
What I feel I need to know are the semantics and contract for this function.
What I sense is that, in its simplest mode, it is supposed to send len bytes of data starting at the memory pointer supplied by buf through the socket identified by sckt. It should return the number of bytes actually sent, 0 if no bytes were sent and -1 if there was an error.
Unfortunately for some devices such as the ESP8266, this semantics needs further consideration. In the ESP8266 the correspond function to transmit data is called espconn_send. However, since nothing in ESP8266 is blocking, this call takes a buffer of data and then will eventually transmit it. When the transmission has completed, a registered call-back function is invoked to let us know that the data has been sent.
Now ... let us try and map this to the apparent Espruino architecture. A naive implementation of the Espruino send() would be to simply call espconn_send() however what should we then return? If we return the length of data that send() was provided, then we are semantically declaring that all the data was transmitted which isn't the case. In fact, it appears that immediately following a successful send() using HTTP, we then close the socket.
The next possible design thought is that when send() is called, we do invoke espconn_send() but return 0 ... indicating that NO data has been transmitted. The assumption here is that send() will continue to be invoked over and over. The ESP8266 layer could be watching for the previous send to complete and, when it does, we return that the data was sent. This may work, but makes a broad assumption. It assumes that when send() is called with some data and gets a return of 0 ... it will continually call with the SAME data to be sent over and over again ... it isn't clear in the semantics if this is correct or not.
Another open question is the buffer passed into the send() call. Should the content be copied from the request or can we assume that the memory pointer is "good" and "stable" until the data has actually been transmitted at some time in the future. If we can't assume that, then we have the unfortunate circumstance of having to duplicate the memory buffer to hold a copy while we transmit.
As we see ... we are starting to ask complex semantic questions which weren't immediately obvious from such an innocuous looking function such as send().
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
When implementing a new network component for a new board (eg. ESP8266), we have to create a function that is mapped to the JsNetwork
send
function. This is a function with the following signature:int send(struct JsNetwork *net, int sckt, const void *buf, size_t len)
What I feel I need to know are the semantics and contract for this function.
What I sense is that, in its simplest mode, it is supposed to send
len
bytes of data starting at the memory pointer supplied bybuf
through the socket identified bysckt
. It should return the number of bytes actually sent, 0 if no bytes were sent and -1 if there was an error.Unfortunately for some devices such as the ESP8266, this semantics needs further consideration. In the ESP8266 the correspond function to transmit data is called
espconn_send
. However, since nothing in ESP8266 is blocking, this call takes a buffer of data and then will eventually transmit it. When the transmission has completed, a registered call-back function is invoked to let us know that the data has been sent.Now ... let us try and map this to the apparent Espruino architecture. A naive implementation of the Espruino
send()
would be to simply callespconn_send()
however what should we then return? If we return the length of data thatsend()
was provided, then we are semantically declaring that all the data was transmitted which isn't the case. In fact, it appears that immediately following a successfulsend()
using HTTP, we then close the socket.The next possible design thought is that when
send()
is called, we do invokeespconn_send()
but return 0 ... indicating that NO data has been transmitted. The assumption here is thatsend()
will continue to be invoked over and over. The ESP8266 layer could be watching for the previous send to complete and, when it does, we return that the data was sent. This may work, but makes a broad assumption. It assumes that whensend()
is called with some data and gets a return of 0 ... it will continually call with the SAME data to be sent over and over again ... it isn't clear in the semantics if this is correct or not.Another open question is the buffer passed into the
send()
call. Should the content be copied from the request or can we assume that the memory pointer is "good" and "stable" until the data has actually been transmitted at some time in the future. If we can't assume that, then we have the unfortunate circumstance of having to duplicate the memory buffer to hold a copy while we transmit.As we see ... we are starting to ask complex semantic questions which weren't immediately obvious from such an innocuous looking function such as
send()
.Neil