/** * Queue a character for transmission. */ void jshTransmit( IOEventFlags device, //!< The device to be used for transmission. unsigned char data //!< The character to transmit. ) { if (device==EV_LOOPBACKA || device==EV_LOOPBACKB) { jshPushIOCharEvent(device==EV_LOOPBACKB ? EV_LOOPBACKA : EV_LOOPBACKB, (char)data); return; } #ifndef LINUX #ifdef USB if (device==EV_USBSERIAL && !jshIsUSBSERIALConnected()) { jshTransmitClearDevice(EV_USBSERIAL); // clear out stuff already waiting return; } #endif #else // if PC, just put to stdout if (device==DEFAULT_CONSOLE_DEVICE) { fputc(data, stdout); fflush(stdout); return; } #endif // If the device is EV_NONE then there is nowhere to send the data. if (device==EV_NONE) return; // The txHead global points to the current item in the txBuffer. Since we are adding a new // character, we increment the head pointer. If it has caught up with the tail, then that means // we have filled the array backing the list. What we do next is to wait for space to free up. unsigned char txHeadNext = (unsigned char)((txHead+1)&TXBUFFERMASK); if (txHeadNext==txTail) { jsiSetBusy(BUSY_TRANSMIT, true); bool wasConsoleLimbo = device==EV_LIMBO && jsiGetConsoleDevice()==EV_LIMBO; while (txHeadNext==txTail) { // wait for send to finish as buffer is about to overflow #ifdef USB // just in case USB was unplugged while we were waiting! if (!jshIsUSBSERIALConnected()) jshTransmitClearDevice(EV_USBSERIAL); #endif } if (wasConsoleLimbo && jsiGetConsoleDevice()!=EV_LIMBO) { /* It was 'Limbo', but now it's not - see jsiOneSecondAfterStartup. Basically we must have printed a bunch of stuff to LIMBO and blocked with our output buffer full. But then jsiOneSecondAfterStartup switches to the right console device and swaps everything we wrote over to that device too. Only we're now here, still writing to the old device when really we should be writing to the new one. */ device = jsiGetConsoleDevice(); } jsiSetBusy(BUSY_TRANSMIT, false); } // Save the device and data for the new character to be transmitted. txBuffer[txHead].flags = device; txBuffer[txHead].data = data; txHead = txHeadNext; jshUSARTKick(device); // set up interrupts if required }
/** * The event handler for ESP8266 tasks as created by system_os_post() on the TASK_APP_QUEUE. */ static void eventHandler( os_event_t *pEvent //!< ) { switch (pEvent->sig) { // Handle the main loop event. case TASK_APP_MAINLOOP: mainLoop(); break; // Handle the event to process received data. case TASK_APP_RX_DATA: { // Get the data from the UART RX buffer. If the size of the returned data is // not zero, then push it onto the Espruino processing queue for characters. char pBuffer[100]; int size = getRXBuffer(pBuffer, sizeof(pBuffer)); if (size > 0) { jshPushIOCharEvents(jsiGetConsoleDevice(), pBuffer, size); } } break; // Handle the unknown event type. default: os_printf("user_main: eventHandler: Unknown task type: %ld", pEvent->sig); break; } }
/*JSON{ "type" : "staticproperty", "class" : "process", "name" : "env", "generate" : "jswrap_process_env", "return" : ["JsVar","An object"] } Returns an Object containing various pre-defined variables. standard ones are BOARD, VERSION */ JsVar *jswrap_process_env() { JsVar *obj = jsvNewWithFlags(JSV_OBJECT); jsvObjectSetChildAndUnLock(obj, "VERSION", jsvNewFromString(JS_VERSION)); jsvObjectSetChildAndUnLock(obj, "BUILD_DATE", jsvNewFromString(__DATE__)); jsvObjectSetChildAndUnLock(obj, "BUILD_TIME", jsvNewFromString(__TIME__)); #ifdef GIT_COMMIT jsvObjectSetChildAndUnLock(obj, "GIT_COMMIT", jsvNewFromString(STRINGIFY(GIT_COMMIT))); #endif jsvObjectSetChildAndUnLock(obj, "BOARD", jsvNewFromString(PC_BOARD_ID)); jsvObjectSetChildAndUnLock(obj, "CHIP", jsvNewFromString(PC_BOARD_CHIP)); jsvObjectSetChildAndUnLock(obj, "CHIP_FAMILY", jsvNewFromString(PC_BOARD_CHIP_FAMILY)); jsvObjectSetChildAndUnLock(obj, "FLASH", jsvNewFromInteger(FLASH_TOTAL)); jsvObjectSetChildAndUnLock(obj, "RAM", jsvNewFromInteger(RAM_TOTAL)); jsvObjectSetChildAndUnLock(obj, "SERIAL", jswrap_interface_getSerial()); jsvObjectSetChildAndUnLock(obj, "CONSOLE", jsvNewFromString(jshGetDeviceString(jsiGetConsoleDevice()))); JsVar *arr = jsvNewWithFlags(JSV_OBJECT); if (arr) { const char *s = exportNames; void **p = (void**)exportPtrs; while (*s) { jsvObjectSetChildAndUnLock(arr, s, jsvNewFromInteger((JsVarInt)(size_t)*p)); p++; while (*s) s++; // skip until 0 s++; // skip over 0 } jsvObjectSetChildAndUnLock(obj, "EXPORTS", arr); } return obj; }
/** * A callback function to be invoked when a line has been entered on the telnet client. * Here we want to pass that line to the JS parser for processing. */ static void telnetLineCB(char *line) { jsiConsolePrintf("LineCB: %s", line); // Pass the line to the interactive module ... jshPushIOCharEvents(jsiGetConsoleDevice(), line, strlen(line)); //jspEvaluate(line); //jsiDumpState(); telnet_send("JS> "); } // End of lineCB
// Close the connection and release the console device void telnetRelease(JsNetwork *net) { if (!(tnSrv.sock && tnSrv.cliSock)) return; printf("tnSrv: released console from sock %d\n", tnSrv.cliSock-1); netCloseSocket(net, tnSrv.cliSock-1); tnSrv.cliSock = 0; IOEventFlags console = jsiGetConsoleDevice(); // only switch away from telnet if the current console is TELNET, this allows the current // console to be set to something else while connected via telnet and then not have it // switched again when disconnecting from telnet if (console == EV_TELNET && !jsiIsConsoleDeviceForced()) jsiSetConsoleDevice(tnSrv.oldConsole, false); }
/*JSON{ "type":"staticproperty", "class" : "process", "name" : "env", "description" : "Returns an Object containing various pre-defined variables. standard ones are BOARD, VERSION", "generate" : "jswrap_process_env", "return" : ["JsVar", "An object"] }*/ JsVar *jswrap_process_env() { JsVar *obj = jsvNewWithFlags(JSV_OBJECT); jsvUnLock(jsvObjectSetChild(obj, "VERSION", jsvNewFromString(JS_VERSION))); jsvUnLock(jsvObjectSetChild(obj, "BUILD_DATE", jsvNewFromString(__DATE__))); jsvUnLock(jsvObjectSetChild(obj, "BUILD_TIME", jsvNewFromString(__TIME__))); #ifdef GIT_COMMIT jsvUnLock(jsvObjectSetChild(obj, "GIT_COMMIT", jsvNewFromString(STRINGIFY(GIT_COMMIT)))); #endif jsvUnLock(jsvObjectSetChild(obj, "BOARD", jsvNewFromString(PC_BOARD_ID))); jsvUnLock(jsvObjectSetChild(obj, "CHIP", jsvNewFromString(PC_BOARD_CHIP))); jsvUnLock(jsvObjectSetChild(obj, "CHIP_FAMILY", jsvNewFromString(PC_BOARD_CHIP_FAMILY))); jsvUnLock(jsvObjectSetChild(obj, "FLASH", jsvNewFromInteger(FLASH_TOTAL))); jsvUnLock(jsvObjectSetChild(obj, "RAM", jsvNewFromInteger(RAM_TOTAL))); jsvUnLock(jsvObjectSetChild(obj, "SERIAL", jswrap_interface_getSerial())); jsvUnLock(jsvObjectSetChild(obj, "CONSOLE", jsvNewFromString(jshGetDeviceString(jsiGetConsoleDevice())))); return obj; }
/*JSON{ "type" : "staticproperty", "class" : "process", "name" : "env", "generate" : "jswrap_process_env", "return" : ["JsVar","An object"] } Returns an Object containing various pre-defined variables. standard ones are BOARD, VERSION, FLASH, RAM, MODULES. For example, to get a list of built-in modules, you can use `process.env.MODULES.split(',')` */ JsVar *jswrap_process_env() { JsVar *obj = jsvNewObject(); jsvObjectSetChildAndUnLock(obj, "VERSION", jsvNewFromString(JS_VERSION)); #ifdef GIT_COMMIT jsvObjectSetChildAndUnLock(obj, "GIT_COMMIT", jsvNewFromString(STRINGIFY(GIT_COMMIT))); #endif jsvObjectSetChildAndUnLock(obj, "BOARD", jsvNewFromString(PC_BOARD_ID)); jsvObjectSetChildAndUnLock(obj, "FLASH", jsvNewFromInteger(FLASH_TOTAL)); jsvObjectSetChildAndUnLock(obj, "RAM", jsvNewFromInteger(RAM_TOTAL)); jsvObjectSetChildAndUnLock(obj, "SERIAL", jswrap_interface_getSerial()); jsvObjectSetChildAndUnLock(obj, "CONSOLE", jsvNewFromString(jshGetDeviceString(jsiGetConsoleDevice()))); jsvObjectSetChildAndUnLock(obj, "MODULES", jsvNewFromString(jswGetBuiltInLibraryNames())); #ifndef SAVE_ON_FLASH // Pointer to a list of predefined exports - eventually we'll get rid of the array above jsvObjectSetChildAndUnLock(obj, "EXPTR", jsvNewFromInteger((JsVarInt)(size_t)exportPtrs)); #endif return obj; }
// Attempt to accept a connection, returns true if it did something bool telnetAccept(JsNetwork *net) { // we're gonna do a single accept per idle iteration for now if (tnSrv.sock == 0) return false; int sock = netAccept(net, tnSrv.sock); if (sock < 0) return false; // nothing // if we already have a client, then disconnect it if (tnSrv.cliSock != 0) { netCloseSocket(net, tnSrv.cliSock); } // if the console is not already telnet, then change it IOEventFlags console = jsiGetConsoleDevice(); if (console != EV_TELNET) { tnSrv.oldConsole = console; if (!jsiIsConsoleDeviceForced()) jsiSetConsoleDevice(EV_TELNET, false); } tnSrv.cliSock = sock; printf("tnSrv: accepted console on sock=%d\n", sock); return true; }