diff --git a/libs/network/js/jswrap_jsnetwork.c b/libs/network/js/jswrap_jsnetwork.c index 43badf7c8..0c352337c 100644 --- a/libs/network/js/jswrap_jsnetwork.c +++ b/libs/network/js/jswrap_jsnetwork.c @@ -38,13 +38,44 @@ Library that initialises a network device that calls into JavaScript ], "return" : ["JsVar","The object passed in"] } -Initialise the WIZnet module and return an Ethernet object +Initialise the WIZnet module and return an Ethernet object. For instance: + +``` +require("NetworkJS").create({ + create : function(host,port) { + // Create a socket and return its index, host is a string, port is an integer. + // If host isn't defined, create a server socket + console.log("Create",host,port); + return 1; + }, + close : function(sckt) { + // Close the socket. returns nothing + }, + accept : function(sckt) { + // Accept the connection on the server socket. Returns socket number or -1 if no connection + return -1; + }, + recv : function(sckt, maxLen) { + // Receive data. Returns a string (even if empty). + // If non-string returned, socket is then closed + return null;//or ""; + }, + send : function(sckt, data) { + // Send data (as string). Returns the number of bytes sent - 0 is ok. + // Less than 0 + return data.length; + } +}); +``` */ JsVar *jswrap_networkjs_create(JsVar *obj) { JsNetwork net; networkCreate(&net, JSNETWORKTYPE_JS); networkSet(&net); + networkFree(&net); + + net_js_setObj(obj); networkState = NETWORKSTATE_ONLINE; - return obj; + return jsvLockAgain(obj); } diff --git a/libs/network/js/network_js.c b/libs/network/js/network_js.c index ec80d8441..779e201a2 100644 --- a/libs/network/js/network_js.c +++ b/libs/network/js/network_js.c @@ -19,6 +19,28 @@ #define JSNET_NAME "JSN" #define JSNET_DNS_NAME "DNS" +// Set the built-in object for network access +void net_js_setObj(JsVar *obj) { + jsvObjectSetChild(execInfo.hiddenRoot, JSNET_NAME, obj); +} + +/// Call the named function on the object - whether it's built in, or predefined. Returns the return value of the function. +JsVar *callFn(char* name, int argCount, JsVar **argPtr) { + JsVar *netObj = jsvObjectGetChild(execInfo.hiddenRoot, JSNET_NAME, 0); + JsVar *child = jspGetNamedField(netObj, name, false); + + JsVar *r = 0; + if (jsvIsFunction(child)) { + JsExecInfo oldExecInfo = execInfo; + execInfo.execute = EXEC_YES; + r = jspeFunctionCall(child, 0, netObj, false, argCount, argPtr); + execInfo = oldExecInfo; + } + jsvUnLock(child); + jsvUnLock(netObj); + return r; +} + // ------------------------------------------------------------------------------------------------------------------------ /// Get an IP address from a name. Sets out_ip_addr to 0 on failure @@ -49,27 +71,23 @@ int net_js_createsocket(JsNetwork *net, uint32_t host, unsigned short port) { hostVar = networkGetAddressAsString((unsigned char *)&host, 4,10,'.'); } // else server, hostVar=0 - JsVar *netObj = jsvObjectGetChild(execInfo.hiddenRoot, JSNET_NAME, 0); JsVar *args[2] = { hostVar, jsvNewFromInteger(port) }; - int sckt = jsvGetIntegerAndUnLock(jspCallNamedFunction(net, "create", 2, args)); + int sckt = jsvGetIntegerAndUnLock(callFn("create", 2, args)); jsvUnLock(args[0]); jsvUnLock(args[1]); - jsvUnLock(netObj); return sckt; } /// destroys the given socket void net_js_closesocket(JsNetwork *net, int sckt) { - JsVar *netObj = jsvObjectGetChild(execInfo.hiddenRoot, JSNET_NAME, 0); JsVar *args[1] = { jsvNewFromInteger(sckt) }; - jspCallNamedFunction(net, "recv", 2, args); + jsvUnLock(callFn("close", 1, args)); jsvUnLock(args[0]); - jsvUnLock(netObj); } /// If the given server socket can accept a connection, return it (or return < 0) @@ -78,7 +96,8 @@ int net_js_accept(JsNetwork *net, int serverSckt) { JsVar *args[1] = { jsvNewFromInteger(serverSckt) }; - int sckt = jsvGetIntegerAndUnLock(jspCallNamedFunction(net, "accept", 1, args)); + + int sckt = jsvGetIntegerAndUnLock(callFn("accept", 1, args)); jsvUnLock(args[0]); jsvUnLock(netObj); return sckt; @@ -86,28 +105,33 @@ int net_js_accept(JsNetwork *net, int serverSckt) { /// Receive data if possible. returns nBytes on success, 0 on no data, or -1 on failure int net_js_recv(JsNetwork *net, int sckt, void *buf, size_t len) { - JsVar *netObj = jsvObjectGetChild(execInfo.hiddenRoot, JSNET_NAME, 0); - JsVar *args[1] = { - jsvNewFromInteger(sckt) + JsVar *args[2] = { + jsvNewFromInteger(sckt), + jsvNewFromInteger(len), }; - int r = jsvGetIntegerAndUnLock(jspCallNamedFunction(net, "recv", 1, args)); + JsVar *res = callFn( "recv", 2, args); jsvUnLock(args[0]); - jsvUnLock(netObj); + jsvUnLock(args[1]); + int r = -1; // fail + if (jsvIsString(res)) { + r = jsvGetStringLength(res); + if (r>len) r=len; + jsvGetStringChars(res, 0, buf, r); + } + jsvUnLock(res); return r; } /// Send data if possible. returns nBytes on success, 0 on no data, or -1 on failure int net_js_send(JsNetwork *net, int sckt, const void *buf, size_t len) { - JsVar *netObj = jsvObjectGetChild(execInfo.hiddenRoot, JSNET_NAME, 0); JsVar *args[2] = { jsvNewFromInteger(sckt), jsvNewFromEmptyString() }; jsvAppendStringBuf(args[1], buf, len); - int r = jsvGetIntegerAndUnLock(jspCallNamedFunction(net, "send", 2, args)); + int r = jsvGetIntegerAndUnLock(callFn( "send", 2, args)); jsvUnLock(args[0]); jsvUnLock(args[1]); - jsvUnLock(netObj); return r; } diff --git a/libs/network/js/network_js.h b/libs/network/js/network_js.h index fd4e7aed2..2b7e92966 100644 --- a/libs/network/js/network_js.h +++ b/libs/network/js/network_js.h @@ -13,4 +13,7 @@ */ #include "network.h" +// Set the built-in object for network access +void net_js_setObj(JsVar *obj); + void netSetCallbacks_js(JsNetwork *net);