text: 
  #include <esp8266.h>
  #include "cgi.h"
  #include "espfs.h"
  #include "config.h"
  #include "serled.h"
  #include "status.h"
  #include "serbridge.h"
  
  #if 0
  static char *map_names[] = {
    "esp-bridge", "jn-esp-v2", "esp-01(AVR)", "esp-01(ARM)", "esp-br-rev", "wifi-link-12",
  };
  static char* map_func[] = { "reset", "isp", "conn_led", "ser_led", "swap_uart" };
  static int8_t map_asn[][5] = {
    { 12, 13,  0, 14, 0 },  // esp-bridge
    { 12, 13,  0,  2, 0 },  // jn-esp-v2
    {  0, -1,  2, -1, 0 },  // esp-01(AVR)
    {  0,  2, -1, -1, 0 },  // esp-01(ARM)
    { 13, 12, 14,  0, 0 },  // esp-br-rev -- for test purposes
    {  1,  3,  0,  2, 1 },  // esp-link-12
  };
  static const int num_map_names = sizeof(map_names)/sizeof(char*);
  static const int num_map_func = sizeof(map_func)/sizeof(char*);
  #endif
  
  // Cgi to return choice of pin assignments
  int ICACHE_FLASH_ATTR cgiPinsGet(HttpdConnData *connData) {
    if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted
  
    char buff[1024];
    int len;
  
    len = os_sprintf(buff,
        "{ \"reset\":%d, \"isp\":%d, \"conn\":%d, \"ser\":%d, \"swap\":%d, \"rxpup\":%d }",
        flashConfig.reset_pin, flashConfig.isp_pin, flashConfig.conn_led_pin,
        flashConfig.ser_led_pin, !!flashConfig.swap_uart, !!flashConfig.rx_pullup);
  
    jsonHeader(connData, 200);
    httpdSend(connData, buff, len);
    return HTTPD_CGI_DONE;
  }
  
  // Cgi to change choice of pin assignments
  int ICACHE_FLASH_ATTR cgiPinsSet(HttpdConnData *connData) {
    if (connData->conn==NULL) {
      return HTTPD_CGI_DONE; // Connection aborted
    }
  
    int8_t ok = 0;
    int8_t reset, isp, conn, ser;
    uint8_t swap, rxpup;
    ok |= getInt8Arg(connData, "reset", &reset);
    ok |= getInt8Arg(connData, "isp", &isp);
    ok |= getInt8Arg(connData, "conn", &conn);
    ok |= getInt8Arg(connData, "ser", &ser);
    ok |= getBoolArg(connData, "swap", &swap);
    ok |= getBoolArg(connData, "rxpup", &rxpup);
    if (ok < 0) return HTTPD_CGI_DONE;
  
    char *coll;
    if (ok > 0) {
      // check whether two pins collide
      uint16_t pins = 0;
      if (reset >= 0) pins = 1 << reset;
      if (isp >= 0) {
        if (pins & (1<<isp)) { coll = "ISP/Flash"; goto collision; }
        pins |= 1 << isp;
      }
      if (conn >= 0) {
        if (pins & (1<<conn)) { coll = "Conn LED"; goto collision; }
        pins |= 1 << conn;
      }
      if (ser >= 0) {
        if (pins & (1<<ser)) { coll = "Serial LED"; goto collision; }
        pins |= 1 << ser;
      }
      if (swap) {
        if (pins & (1<<15)) { coll = "Uart TX"; goto collision; }
        if (pins & (1<<13)) { coll = "Uart RX"; goto collision; }
      } else {
        if (pins & (1<<1)) { coll = "Uart TX"; goto collision; }
        if (pins & (1<<3)) { coll = "Uart RX"; goto collision; }
      }
  
      // we're good, set flashconfig
      flashConfig.reset_pin = reset;
      flashConfig.isp_pin = isp;
      flashConfig.conn_led_pin = conn;
      flashConfig.ser_led_pin = ser;
      flashConfig.swap_uart = swap;
      flashConfig.rx_pullup = rxpup;
      os_printf("Pins changed: reset=%d isp=%d conn=%d ser=%d swap=%d rx-pup=%d\n",
  	reset, isp, conn, ser, swap, rxpup);
  
      // apply the changes
      serbridgeInitPins();
      serledInit();
      statusInit();
  
      // save to flash
      if (configSave()) {
        httpdStartResponse(connData, 204);
        httpdEndHeaders(connData);
      } else {
        httpdStartResponse(connData, 500);
        httpdEndHeaders(connData);
        httpdSend(connData, "Failed to save config", -1);
      }
    }
    return HTTPD_CGI_DONE;
  
  collision: {
      char buff[128];
      os_sprintf(buff, "Pin assignment for %s collides with another assignment", coll);
      errorResponse(connData, 400, buff);
      return HTTPD_CGI_DONE;
    }
  }
  
  int ICACHE_FLASH_ATTR cgiPins(HttpdConnData *connData) {
    if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up.
    if (connData->requestType == HTTPD_METHOD_GET) {
      return cgiPinsGet(connData);
    } else if (connData->requestType == HTTPD_METHOD_POST) {
      return cgiPinsSet(connData);
    } else {
      jsonHeader(connData, 404);
      return HTTPD_CGI_DONE;
    }
  }
  