Merge pull request #1867 from MikePetullo/lcdgrilo
authorSteven Barth <steven@midlink.org>
Thu, 22 Oct 2015 08:34:31 +0000 (10:34 +0200)
committerSteven Barth <steven@midlink.org>
Thu, 22 Oct 2015 08:34:31 +0000 (10:34 +0200)
lcdgrilo: add new package

56 files changed:
admin/zabbix/Makefile
lang/node-arduino-firmata/Makefile [new file with mode: 0644]
lang/node-arduino-firmata/files/usr/lib/node/arduino-firmata/lib/arduino-firmata.js [new file with mode: 0644]
lang/node-arduino-firmata/patches/000-new-serialport.patch [new file with mode: 0644]
lang/node-cylon/Makefile [new file with mode: 0644]
lang/node-cylon/patches/0001-serialport.patch [new file with mode: 0644]
lang/node-hid/Makefile [new file with mode: 0644]
lang/node-hid/patches/000-compile.patch [new file with mode: 0644]
lang/node-serialport/Makefile [new file with mode: 0644]
lang/node-serialport/patches/package.json.patch [new file with mode: 0644]
lang/node/Makefile [new file with mode: 0644]
lang/node/patches/001-mips-no-fpu.patch [new file with mode: 0644]
lang/node/patches/002-addr_info.patch [new file with mode: 0644]
lang/node/patches/003-path.patch [new file with mode: 0644]
lang/php5/Makefile
libs/gnutls/Makefile
libs/libdmapsharing/Makefile
libs/libmraa/Makefile [new file with mode: 0644]
libs/libmraa/patches/0001-base.patch [new file with mode: 0644]
libs/libmraa/patches/0002-add-mips-support.patch [new file with mode: 0644]
libs/libmraa/patches/0003-uart.patch [new file with mode: 0644]
libs/libmraa/patches/0004-fixes.patch [new file with mode: 0644]
libs/libupm/Makefile [new file with mode: 0644]
libs/libupm/patches/001-version.patch [new file with mode: 0644]
libs/libupm/patches/002-at42qt1070-id.patch [new file with mode: 0644]
libs/libupm/patches/003-lsm303-args.patch [new file with mode: 0644]
multimedia/motion/Makefile
multimedia/motion/patches/100-musl-compat.patch [new file with mode: 0644]
net/chrony/Makefile
net/chrony/files/chrony.conf
net/chrony/files/chrony.hotplug
net/chrony/files/chrony.keys [deleted file]
net/chrony/files/ntpd.config [deleted file]
net/chrony/files/ntpd.hotplug [deleted file]
net/chrony/files/ntpd.init [deleted file]
net/chrony/patches/001-crosscompile.patch [deleted file]
net/chrony/patches/002-ipv6_disabled_fixes.patch [deleted file]
net/freeradius2/files/radiusd.init
net/mwan3/Makefile
net/mwan3/files/etc/hotplug.d/iface/15-mwan3
net/mwan3/files/usr/sbin/mwan3
sound/madplay/Makefile
sound/madplay/patches/0001-switch-to-new-alsa-api.patch [new file with mode: 0644]
utils/gammu/Makefile
utils/open2300/Makefile [new file with mode: 0644]
utils/open2300/files/open2300.conf [new file with mode: 0644]
utils/open2300/patches/001-crosscompile.patch [new file with mode: 0644]
utils/swig/Makefile [new file with mode: 0644]
utils/yunbridge/Makefile [new file with mode: 0644]
utils/yunbridge/files/etc/config/yunbridge [new file with mode: 0644]
utils/yunbridge/files/etc/init.d/yunbridge [new file with mode: 0755]
utils/yunbridge/files/sbin/yunbridge [new file with mode: 0755]
utils/yunbridge/files/usr/bin/pretty-wifi-info.lua [new file with mode: 0755]
utils/yunbridge/files/usr/lib/lua/luci/controller/arduino/index.lua [new file with mode: 0644]
utils/yunbridge/files/usr/lib/lua/luci/sha256.lua [new file with mode: 0644]
utils/yunbridge/patches/000-scripts.patch [new file with mode: 0644]

index 098f3e3414efac3d427b761a021a51f30dadee8c..424779ef987c6f552510fb41923ea6dde4675a9b 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=zabbix
 PKG_VERSION:=2.4.6
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=@SF/zabbix
@@ -107,6 +107,7 @@ CONFIGURE_ARGS+= \
        --enable-agent \
        --enable-server \
        --enable-proxy \
+       $(call autoconf_bool,CONFIG_IPV6,ipv6) \
        --disable-java \
        --with-sqlite3="$(STAGING_DIR)/usr"
 
diff --git a/lang/node-arduino-firmata/Makefile b/lang/node-arduino-firmata/Makefile
new file mode 100644 (file)
index 0000000..aced070
--- /dev/null
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2014 Arduino LLC
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NPM_NAME:=arduino-firmata
+PKG_NAME:=node-$(PKG_NPM_NAME)
+PKG_VERSION:=0.3.3
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/shokai/node-arduino-firmata.git
+PKG_SOURCE_VERSION:=16e76007edf218d72df590adbd711ac6b7432845
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_SOURCE_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
+
+PKG_BUILD_DEPENDS:=node
+PKG_NODE_VERSION:=0.12.7
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILE:=LICENSE.txt
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/node-arduino-firmata
+  DEPENDS:=+node
+  SUBMENU:=Node.js
+  SECTION:=lang
+  CATEGORY:=Languages
+  DEPENDS:=+node +node-serialport
+  TITLE:=Node.js package to access serial ports for reading and writing
+  URL:=https://www.npmjs.org/package/serialport
+endef
+
+define Package/node-arduino-firmata/description
+ Node.js package to access serial ports for reading and writing OR Welcome your robotic JavaScript overlords. Better yet, program them!
+endef
+
+define Build/Prepare
+       /bin/tar xzf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR) --strip-components 1
+       $(Build/Patch)
+endef
+
+EXTRA_LDFLAGS="-L$(TOOLCHAIN_DIR)/lib/ -Wl,-rpath-link $(TOOLCHAIN_DIR)/lib/" \
+
+define Build/Compile
+       $(MAKE_FLAGS) \
+       npm_config_arch=$(CONFIG_ARCH) \
+       npm_config_nodedir=$(BUILD_DIR)/node-v$(PKG_NODE_VERSION)/ \
+       PREFIX="$(PKG_INSTALL_DIR)/usr/" \
+       $(STAGING_DIR_HOST)/bin/npm install -g $(PKG_BUILD_DIR)
+endef
+
+define Package/node-arduino-firmata/install
+       mkdir -p $(1)/usr/lib/node
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/* $(1)/usr/lib/node
+       rm -rf $(1)/usr/lib/node/arduino-firmata/node_modules/serialport/ 
+       $(CP) -r ./files/* $(1)/
+endef
+
+$(eval $(call BuildPackage,node-arduino-firmata))
+
diff --git a/lang/node-arduino-firmata/files/usr/lib/node/arduino-firmata/lib/arduino-firmata.js b/lang/node-arduino-firmata/files/usr/lib/node/arduino-firmata/lib/arduino-firmata.js
new file mode 100644 (file)
index 0000000..578bd40
--- /dev/null
@@ -0,0 +1,306 @@
+(function() {
+  'use strict';
+  var ArduinoFirmata, SerialPort, debug, events, exports, serialport,
+    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
+    hasProp = {}.hasOwnProperty;
+
+  events = require('eventemitter2');
+
+  SerialPort = (serialport = require('serialport')).SerialPort;
+
+  debug = require('debug')('arduino-firmata');
+
+  exports = module.exports = ArduinoFirmata = (function(superClass) {
+    extend(ArduinoFirmata, superClass);
+
+    ArduinoFirmata.Status = {
+      CLOSE: 0,
+      OPEN: 1
+    };
+
+    ArduinoFirmata.INPUT = 0;
+
+    ArduinoFirmata.OUTPUT = 1;
+
+    ArduinoFirmata.ANALOG = 2;
+
+    ArduinoFirmata.PWM = 3;
+
+    ArduinoFirmata.SERVO = 4;
+
+    ArduinoFirmata.SHIFT = 5;
+
+    ArduinoFirmata.I2C = 6;
+
+    ArduinoFirmata.LOW = 0;
+
+    ArduinoFirmata.HIGH = 1;
+
+    ArduinoFirmata.MAX_DATA_BYTES = 32;
+
+    ArduinoFirmata.DIGITAL_MESSAGE = 0x90;
+
+    ArduinoFirmata.ANALOG_MESSAGE = 0xE0;
+
+    ArduinoFirmata.REPORT_ANALOG = 0xC0;
+
+    ArduinoFirmata.REPORT_DIGITAL = 0xD0;
+
+    ArduinoFirmata.SET_PIN_MODE = 0xF4;
+
+    ArduinoFirmata.REPORT_VERSION = 0xF9;
+
+    ArduinoFirmata.SYSTEM_RESET = 0xFF;
+
+    ArduinoFirmata.START_SYSEX = 0xF0;
+
+    ArduinoFirmata.END_SYSEX = 0xF7;
+
+    ArduinoFirmata.list = function(callback) {
+      return serialport.list(function(err, ports) {
+        var devices, j, len, port;
+        if (err) {
+          return callback(err);
+        }
+        devices = [];
+        for (j = 0, len = ports.length; j < len; j++) {
+          port = ports[j];
+          if (/usb|acm|com\d+/i.test(port.comName)) {
+            devices.push(port.comName);
+          }
+        }
+        return callback(null, devices);
+      });
+    };
+
+    function ArduinoFirmata() {
+      this.status = ArduinoFirmata.Status.CLOSE;
+      this.wait_for_data = 0;
+      this.execute_multi_byte_command = 0;
+      this.multi_byte_channel = 0;
+      this.stored_input_data = [];
+      this.parsing_sysex = false;
+      this.sysex_bytes_read = 0;
+      this.digital_output_data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+      this.digital_input_data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+      this.analog_input_data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+      this.boardVersion = null;
+    }
+
+    ArduinoFirmata.prototype.isOldArduinoDevice = function() {
+      return /usbserial|USB/.test(this.serialport_name);
+    };
+
+    ArduinoFirmata.prototype.connect = function(serialport_name, opts) {
+      this.serialport_name = serialport_name;
+      if (opts == null) {
+        opts = {
+          baudrate: 57600
+        };
+      }
+      opts.parser = serialport.parsers.raw;
+      if (!this.serialport_name) {
+        ArduinoFirmata.list((function(_this) {
+          return function(err, devices) {
+            return _this.connect(devices[0], opts);
+          };
+        })(this));
+        return this;
+      }
+      this.once('boardReady', function() {
+        var io_init_wait;
+        debug('boardReady');
+        io_init_wait = this.isOldArduinoDevice() ? (debug("old arduino device found " + this.serialport_name), 3000) : (debug("new arduino device found " + this.serialport_name), 100);
+        debug("wait " + io_init_wait + "(msec)");
+        return setTimeout((function(_this) {
+          return function() {
+            var i, j, k;
+            for (i = j = 0; j < 6; i = ++j) {
+              _this.write([ArduinoFirmata.REPORT_ANALOG | i, 1]);
+            }
+            for (i = k = 0; k < 2; i = ++k) {
+              _this.write([ArduinoFirmata.REPORT_DIGITAL | i, 1]);
+            }
+            debug('init IO ports');
+            return _this.emit('connect');
+          };
+        })(this), io_init_wait);
+      });
+      this.serialport = new SerialPort(this.serialport_name, opts);
+      this.serialport.once('open', (function(_this) {
+        return function() {
+          var cid;
+          cid = setInterval(function() {
+            debug('request REPORT_VERSION');
+            return _this.write([ArduinoFirmata.REPORT_VERSION]);
+          }, 500);
+          _this.once('boardVersion', function(version) {
+            clearInterval(cid);
+            _this.status = ArduinoFirmata.Status.OPEN;
+            return _this.emit('boardReady');
+          });
+          return _this.serialport.on('data', function(data) {
+            var byte, j, len, results;
+            results = [];
+            for (j = 0, len = data.length; j < len; j++) {
+              byte = data[j];
+              results.push(_this.process_input(byte));
+            }
+            return results;
+          });
+        };
+      })(this));
+      return this;
+    };
+
+    ArduinoFirmata.prototype.isOpen = function() {
+      return this.status === ArduinoFirmata.Status.OPEN;
+    };
+
+    ArduinoFirmata.prototype.close = function(callback) {
+      this.status = ArduinoFirmata.Status.CLOSE;
+      return this.serialport.close(callback);
+    };
+
+    ArduinoFirmata.prototype.reset = function(callback) {
+      return this.write([ArduinoFirmata.SYSTEM_RESET], callback);
+    };
+
+    ArduinoFirmata.prototype.write = function(bytes, callback) {
+      return this.serialport.write(bytes, callback);
+    };
+
+    ArduinoFirmata.prototype.sysex = function(command, data, callback) {
+      var write_data;
+      if (data == null) {
+        data = [];
+      }
+      data = data.map(function(i) {
+        return i & 0x7f;
+      });
+      write_data = [ArduinoFirmata.START_SYSEX, command].concat(data, [ArduinoFirmata.END_SYSEX]);
+      return this.write(write_data, callback);
+    };
+
+    ArduinoFirmata.prototype.pinMode = function(pin, mode, callback) {
+      switch (mode) {
+        case true:
+          mode = ArduinoFirmata.OUTPUT;
+          break;
+        case false:
+          mode = ArduinoFirmata.INPUT;
+      }
+      return this.write([ArduinoFirmata.SET_PIN_MODE, pin, mode], callback);
+    };
+
+    ArduinoFirmata.prototype.digitalWrite = function(pin, value, callback) {
+      var port_num;
+      this.pinMode(pin, ArduinoFirmata.OUTPUT);
+      port_num = (pin >>> 3) & 0x0F;
+      if (value === 0 || value === false) {
+        this.digital_output_data[port_num] &= ~(1 << (pin & 0x07));
+      } else {
+        this.digital_output_data[port_num] |= 1 << (pin & 0x07);
+      }
+      return this.write([ArduinoFirmata.DIGITAL_MESSAGE | port_num, this.digital_output_data[port_num] & 0x7F, this.digital_output_data[port_num] >>> 7], callback);
+    };
+
+    ArduinoFirmata.prototype.analogWrite = function(pin, value, callback) {
+      value = Math.floor(value);
+      this.pinMode(pin, ArduinoFirmata.PWM);
+      return this.write([ArduinoFirmata.ANALOG_MESSAGE | (pin & 0x0F), value & 0x7F, value >>> 7], callback);
+    };
+
+    ArduinoFirmata.prototype.servoWrite = function(pin, angle, callback) {
+      this.pinMode(pin, ArduinoFirmata.SERVO);
+      return this.write([ArduinoFirmata.ANALOG_MESSAGE | (pin & 0x0F), angle & 0x7F, angle >>> 7], callback);
+    };
+
+    ArduinoFirmata.prototype.digitalRead = function(pin) {
+      return ((this.digital_input_data[pin >>> 3] >>> (pin & 0x07)) & 0x01) > 0;
+    };
+
+    ArduinoFirmata.prototype.analogRead = function(pin) {
+      return this.analog_input_data[pin];
+    };
+
+    ArduinoFirmata.prototype.process_input = function(input_data) {
+      var analog_value, command, diff, i, j, old_analog_value, results, stat, sysex_command, sysex_data;
+      if (this.parsing_sysex) {
+        if (input_data === ArduinoFirmata.END_SYSEX) {
+          this.parsing_sysex = false;
+          sysex_command = this.stored_input_data[0];
+          sysex_data = this.stored_input_data.slice(1, this.sysex_bytes_read);
+          return this.emit('sysex', {
+            command: sysex_command,
+            data: sysex_data
+          });
+        } else {
+          this.stored_input_data[this.sysex_bytes_read] = input_data;
+          return this.sysex_bytes_read += 1;
+        }
+      } else if (this.wait_for_data > 0 && input_data < 128) {
+        this.wait_for_data -= 1;
+        this.stored_input_data[this.wait_for_data] = input_data;
+        if (this.execute_multi_byte_command !== 0 && this.wait_for_data === 0) {
+          switch (this.execute_multi_byte_command) {
+            case ArduinoFirmata.DIGITAL_MESSAGE:
+              input_data = (this.stored_input_data[0] << 7) + this.stored_input_data[1];
+              diff = this.digital_input_data[this.multi_byte_channel] ^ input_data;
+              this.digital_input_data[this.multi_byte_channel] = input_data;
+              if (this.listeners('digitalChange').length > 0) {
+                results = [];
+                for (i = j = 0; j <= 13; i = ++j) {
+                  if (((0x01 << i) & diff) > 0) {
+                    stat = (input_data & diff) > 0;
+                    results.push(this.emit('digitalChange', {
+                      pin: i + this.multi_byte_channel * 8,
+                      value: stat,
+                      old_value: !stat
+                    }));
+                  } else {
+                    results.push(void 0);
+                  }
+                }
+                return results;
+              }
+              break;
+            case ArduinoFirmata.ANALOG_MESSAGE:
+              analog_value = (this.stored_input_data[0] << 7) + this.stored_input_data[1];
+              old_analog_value = this.analogRead(this.multi_byte_channel);
+              this.analog_input_data[this.multi_byte_channel] = analog_value;
+              if (old_analog_value !== analog_value) {
+                return this.emit('analogChange', {
+                  pin: this.multi_byte_channel,
+                  value: analog_value,
+                  old_value: old_analog_value
+                });
+              }
+              break;
+            case ArduinoFirmata.REPORT_VERSION:
+              this.boardVersion = this.stored_input_data[1] + "." + this.stored_input_data[0];
+              return this.emit('boardVersion', this.boardVersion);
+          }
+        }
+      } else {
+        if (input_data < 0xF0) {
+          command = input_data & 0xF0;
+          this.multi_byte_channel = input_data & 0x0F;
+        } else {
+          command = input_data;
+        }
+        if (command === ArduinoFirmata.START_SYSEX) {
+          this.parsing_sysex = true;
+          return this.sysex_bytes_read = 0;
+        } else if (command === ArduinoFirmata.DIGITAL_MESSAGE || command === ArduinoFirmata.ANALOG_MESSAGE || command === ArduinoFirmata.REPORT_VERSION) {
+          this.wait_for_data = 2;
+          return this.execute_multi_byte_command = command;
+        }
+      }
+    };
+
+    return ArduinoFirmata;
+
+  })(events.EventEmitter2);
+
+}).call(this);
diff --git a/lang/node-arduino-firmata/patches/000-new-serialport.patch b/lang/node-arduino-firmata/patches/000-new-serialport.patch
new file mode 100644 (file)
index 0000000..10eab64
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/package.json
++++ b/package.json
+@@ -30,7 +30,6 @@
+   "author": "Sho Hashimoto <hashimoto@shokai.org>",
+   "license": "MIT",
+   "dependencies": {
+-    "serialport": "*",
+     "eventemitter2": "*",
+     "debug": "*"
+   },
diff --git a/lang/node-cylon/Makefile b/lang/node-cylon/Makefile
new file mode 100644 (file)
index 0000000..753ae23
--- /dev/null
@@ -0,0 +1,98 @@
+#
+# Copyright (C) 2014 Arduino LLC
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NPM_NAME:=cylon
+PKG_NAME:=node-$(PKG_NPM_NAME)
+PKG_VERSION:=0.22.0
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/hybridgroup/cylon-firmata.git
+PKG_SOURCE_VERSION:=0c37da77e48b3e2cc3a8d566822a17689de91b40
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_SOURCE_VERSION)
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
+
+PKG_BUILD_DEPENDS:=node
+PKG_NODE_VERSION:=0.12.7
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILE:=LICENSE
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/node-cylon/default
+  DEPENDS:=+node $(2)
+  SUBMENU:=Node.js
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=CylonJS - $(1)
+  URL:=https://www.npmjs.org/package/cylon
+endef
+
+define Package/node-cylon
+  $(call Package/node-cylon/default,Core)
+endef
+
+define Package/node-cylon-i2c
+  $(call Package/node-cylon/default,I2C,+node-cylon)
+endef
+
+define Package/node-cylon-gpio
+  $(call Package/node-cylon/default,GPIO,+node-cylon)
+endef
+
+define Package/node-cylon-firmata
+  $(call Package/node-cylon/default,Firmata,+node-cylon-gpio +node-cylon-i2c +node-arduino-firmata)
+endef
+
+define Package/node-cylon/description
+       JavaScript Robotics, By Your Command Next generation robotics framework with support for 36 different platforms Get Started
+endef
+
+define Build/Prepare
+       /bin/tar xzf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR) --strip-components 1
+       $(Build/Patch)
+endef
+
+EXTRA_LDFLAGS="-L$(TOOLCHAIN_DIR)/lib/ -Wl,-rpath-link $(TOOLCHAIN_DIR)/lib/" \
+
+define Build/Compile
+       $(MAKE_FLAGS) \
+       npm_config_arch=$(CONFIG_ARCH) \
+       npm_config_nodedir=$(BUILD_DIR)/node-v$(PKG_NODE_VERSION)/ \
+       PREFIX="$(PKG_INSTALL_DIR)/usr/" \
+       $(STAGING_DIR_HOST)/bin/npm install -g $(PKG_BUILD_DIR)
+endef
+
+define Package/node-cylon/install
+       mkdir -p $(1)/usr/lib/node/cylon
+       $(CP) -r $(PKG_INSTALL_DIR)/usr/lib/node_modules/cylon-firmata/node_modules/cylon/* $(1)/usr/lib/node/cylon/
+endef
+
+define Package/node-cylon-i2c/install
+       mkdir -p $(1)/usr/lib/node/cylon-i2c
+       $(CP) -r $(PKG_INSTALL_DIR)/usr/lib/node_modules/cylon-firmata/node_modules/cylon-i2c/* $(1)/usr/lib/node/cylon-i2c/
+endef
+
+define Package/node-cylon-gpio/install
+       mkdir -p $(1)/usr/lib/node/cylon-gpio
+       $(CP) -r $(PKG_INSTALL_DIR)/usr/lib/node_modules/cylon-firmata/node_modules/cylon-gpio/* $(1)/usr/lib/node/cylon-gpio/
+endef
+
+define Package/node-cylon-firmata/install
+       mkdir -p $(1)/usr/lib/node/cylon-firmata
+       $(CP) -r $(PKG_INSTALL_DIR)/usr/lib/node_modules/cylon-firmata/{index.js,lib,LICENSE,package.json,README.md,RELEASES.md,spec} $(1)/usr/lib/node/cylon-firmata/
+endef
+
+$(eval $(call BuildPackage,node-cylon))
+$(eval $(call BuildPackage,node-cylon-i2c))
+$(eval $(call BuildPackage,node-cylon-gpio))
+$(eval $(call BuildPackage,node-cylon-firmata))
+
diff --git a/lang/node-cylon/patches/0001-serialport.patch b/lang/node-cylon/patches/0001-serialport.patch
new file mode 100644 (file)
index 0000000..08d579c
--- /dev/null
@@ -0,0 +1,12 @@
+Index: node-cylon-0.22.0/package.json
+===================================================================
+--- node-cylon-0.22.0.orig/package.json        2015-10-20 20:32:48.000000000 +0200
++++ node-cylon-0.22.0/package.json     2015-10-21 10:42:20.616109122 +0200
+@@ -38,7 +38,6 @@
+   },
+   "dependencies": {
+-    "firmata":    ">= 0.3.2",
+     "cylon":      "1.1.0",
+     "cylon-gpio": "0.26.0",
+     "cylon-i2c":  "0.22.0"
diff --git a/lang/node-hid/Makefile b/lang/node-hid/Makefile
new file mode 100644 (file)
index 0000000..911e2a4
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NPM_NAME:=hid
+PKG_NAME:=node-$(PKG_NPM_NAME)
+PKG_VERSION:=0.4.0
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/node-hid/node-hid.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=c56c8aa5d113c6f2574d1f7e64d41745702965bb
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+
+PKG_BUILD_DEPENDS:=node
+PKG_NODE_VERSION:=0.12.7
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=Custom
+PKG_LICENSE_FILE:=
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/node-hid
+  DEPENDS:=+node
+  SUBMENU:=Node.js
+  SECTION:=lang
+  CATEGORY:=Languages
+  DEPENDS:=+libusb-1.0 +hidapi +libstdcpp
+  TITLE:=Node.js package to access HID devices
+  URL:=https://github.com/node-hid/node-hid
+endef
+
+define Package/node-hid/description
+ Node.js package to access HID devices
+endef
+
+EXTRA_LDFLAGS+="-lhidapi-libusb"
+EXTRA_CFLAGS+="-I$(STAGING_DIR)/usr/include/hidapi/"
+
+define Build/Compile
+       $(MAKE_VARS) \
+       $(MAKE_FLAGS) \
+       npm_config_arch=$(CONFIG_ARCH) \
+       npm_config_nodedir=$(BUILD_DIR)/node-v$(PKG_NODE_VERSION)/ \
+       PREFIX="$(PKG_INSTALL_DIR)/usr/" \
+       $(STAGING_DIR_HOST)/bin/npm install -g $(PKG_BUILD_DIR)
+endef
+
+define Package/node-hid/install
+       mkdir -p $(1)/usr/lib/node/node-hid/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/node-hid/{index.js,package.json,build,node_modules} $(1)/usr/lib/node/node-hid/
+endef
+
+$(eval $(call BuildPackage,node-hid))
+
diff --git a/lang/node-hid/patches/000-compile.patch b/lang/node-hid/patches/000-compile.patch
new file mode 100644 (file)
index 0000000..d44e9b3
--- /dev/null
@@ -0,0 +1,2457 @@
+--- a/package.json
++++ b/package.json
+@@ -14,9 +14,6 @@
+     "type": "git",
+     "url": "git://github.com/hanshuebner/node-hid.git"
+   },
+-  "scripts": {
+-    "prepublish": "git submodule update --init"
+-  },
+   "main": "./index.js",
+   "engines": {
+     "node": ">=0.8.0"
+--- a/src/wscript
++++ b/src/wscript
+@@ -3,10 +3,8 @@
+ import sys;
+ import os;
+-hidapi_home='../hidapi'
+ cflags=["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE", "-Wall", "-fPIC" ]
+-includes=[ hidapi_home + "/hidapi" ]
+ def set_options(opt):
+   opt.tool_options("compiler_cxx")
+@@ -16,24 +14,10 @@
+   conf.check_tool("compiler_cxx")
+   conf.check_tool("node_addon")
+   conf.check_tool("compiler_cc")
+-  if sys.platform == 'darwin':
+-    conf.env.append_value('LINKFLAGS', ['Release/libhidapi.a', '-framework', 'IOKit', '-framework', 'CoreFoundation'])
+-  else:
+-    conf.env.append_value('LINKFLAGS', ['Release/libhidapi.a', '-ludev' ])
+-  
+-def build(bld):
+-    bld.add_group("hidapi")
+-    hidapi = bld.new_task_gen("cc", "staticlib")
+-    hidapi.includes = includes
+-    hidapi.cflags = cflags
+-    if sys.platform == 'darwin':
+-      hidapi.source = "../hidapi/mac/hid.c"
+-    else:
+-      hidapi.source = "../hidapi/linux/hid.c"
+-    hidapi.target = "hidapi"
++def build(bld):
+     bld.add_group("adapter")
+-    adapter = bld.new_task_gen("cxx", "shlib", "node_addon", use = ['hidapi'])
++    adapter = bld.new_task_gen("cxx", "shlib", "node_addon")
+     adapter.includes = includes
+     adapter.cxxflags = cflags
+     adapter.target = "HID"
+--- a/binding.gyp
++++ b/binding.gyp
+@@ -4,61 +4,8 @@
+   },\r
+   'targets': [\r
+     {\r
+-      'target_name': 'hidapi',\r
+-      'type': 'static_library',\r
+-      'conditions': [\r
+-        [ 'OS=="mac"', {\r
+-          'sources': [ 'hidapi/mac/hid.c' ],\r
+-          'include_dirs+': [\r
+-            '/usr/include/libusb-1.0/'\r
+-          ]\r
+-        }],\r
+-        [ 'OS=="linux"', {\r
+-          'conditions': [\r
+-            [ 'driver=="libusb"', {\r
+-              'sources': [ 'hidapi/libusb/hid.c' ],\r
+-              'include_dirs+': [\r
+-                '/usr/include/libusb-1.0/'\r
+-              ]\r
+-            }],\r
+-            [ 'driver=="hidraw"', {\r
+-              'sources': [ 'hidapi/linux/hid.c' ]\r
+-            }]\r
+-          ]\r
+-        }],\r
+-        [ 'OS=="win"', {\r
+-          'sources': [ 'hidapi/windows/hid.c' ],\r
+-          'msvs_settings': {\r
+-            'VCLinkerTool': {\r
+-              'AdditionalDependencies': [\r
+-                'setupapi.lib',\r
+-              ]\r
+-            }\r
+-          }\r
+-        }]\r
+-      ],\r
+-      'direct_dependent_settings': {\r
+-        'include_dirs': [\r
+-          'hidapi/hidapi',\r
+-          "<!(node -e \"require('nan')\")"\r
+-        ]\r
+-      },\r
+-      'include_dirs': [\r
+-        'hidapi/hidapi'\r
+-      ],\r
+-      'defines': [\r
+-        '_LARGEFILE_SOURCE',\r
+-        '_FILE_OFFSET_BITS=64',\r
+-      ],\r
+-      'cflags': ['-g'],\r
+-      'cflags!': [\r
+-        '-ansi'\r
+-      ]\r
+-    },\r
+-    {\r
+       'target_name': 'HID',\r
+       'sources': [ 'src/HID.cc' ],\r
+-      'dependencies': ['hidapi'],\r
+       'defines': [\r
+         '_LARGEFILE_SOURCE',\r
+         '_FILE_OFFSET_BITS=64',\r
+@@ -108,4 +55,4 @@
+       'cflags_cc': ['-g', '-exceptions']\r
+     }\r
+   ]\r
+-}
+\ No newline at end of file
++}\r
+--- /dev/null
++++ b/src/nan.h
+@@ -0,0 +1,2331 @@
++/**********************************************************************************
++ * NAN - Native Abstractions for Node.js
++ *
++ * Copyright (c) 2014 NAN contributors:
++ *   - Rod Vagg <https://github.com/rvagg>
++ *   - Benjamin Byholm <https://github.com/kkoopa>
++ *   - Trevor Norris <https://github.com/trevnorris>
++ *   - Nathan Rajlich <https://github.com/TooTallNate>
++ *   - Brett Lawson <https://github.com/brett19>
++ *   - Ben Noordhuis <https://github.com/bnoordhuis>
++ *
++ * MIT +no-false-attribs License <https://github.com/rvagg/nan/blob/master/LICENSE>
++ *
++ * Version 1.3.0: current Node unstable: 0.11.13, Node stable: 0.10.30
++ *
++ * See https://github.com/rvagg/nan for the latest update to this file
++ **********************************************************************************/
++
++#ifndef NAN_H_
++#define NAN_H_
++
++#include <uv.h>
++#include <node.h>
++#include <node_buffer.h>
++#include <node_version.h>
++#include <node_object_wrap.h>
++#include <string.h>
++#include <limits.h>
++#include <string>
++
++#if defined(__GNUC__) && !defined(DEBUG)
++# define NAN_INLINE inline __attribute__((always_inline))
++#elif defined(_MSC_VER) && !defined(DEBUG)
++# define NAN_INLINE __forceinline
++#else
++# define NAN_INLINE inline
++#endif
++
++#if defined(__GNUC__) && !V8_DISABLE_DEPRECATIONS
++# define NAN_DEPRECATED __attribute__((deprecated))
++#elif defined(_MSC_VER) && !V8_DISABLE_DEPRECATIONS
++# define NAN_DEPRECATED __declspec(deprecated)
++#else
++# define NAN_DEPRECATED
++#endif
++
++// some generic helpers
++
++template<typename T> NAN_INLINE bool NanSetPointerSafe(
++    T *var
++  , T val
++) {
++  if (var) {
++    *var = val;
++    return true;
++  } else {
++    return false;
++  }
++}
++
++template<typename T> NAN_INLINE T NanGetPointerSafe(
++    T *var
++  , T fallback = reinterpret_cast<T>(0)
++) {
++  if (var) {
++    return *var;
++  } else {
++    return fallback;
++  }
++}
++
++NAN_INLINE bool NanBooleanOptionValue(
++    v8::Local<v8::Object> optionsObj
++  , v8::Handle<v8::String> opt, bool def
++) {
++  if (def) {
++    return optionsObj.IsEmpty()
++      || !optionsObj->Has(opt)
++      || optionsObj->Get(opt)->BooleanValue();
++  } else {
++    return !optionsObj.IsEmpty()
++      && optionsObj->Has(opt)
++      && optionsObj->Get(opt)->BooleanValue();
++  }
++}
++
++NAN_INLINE bool NanBooleanOptionValue(
++    v8::Local<v8::Object> optionsObj
++  , v8::Handle<v8::String> opt
++) {
++  return NanBooleanOptionValue(optionsObj, opt, false);
++}
++
++NAN_INLINE uint32_t NanUInt32OptionValue(
++    v8::Local<v8::Object> optionsObj
++  , v8::Handle<v8::String> opt
++  , uint32_t def
++) {
++  return !optionsObj.IsEmpty()
++    && optionsObj->Has(opt)
++    && optionsObj->Get(opt)->IsNumber()
++      ? optionsObj->Get(opt)->Uint32Value()
++      : def;
++}
++
++#if (NODE_MODULE_VERSION > 0x000B)
++// Node 0.11+ (0.11.3 and below won't compile with these)
++
++# define _NAN_METHOD_ARGS_TYPE const v8::FunctionCallbackInfo<v8::Value>&
++# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args
++# define _NAN_METHOD_RETURN_TYPE void
++
++# define _NAN_GETTER_ARGS_TYPE const v8::PropertyCallbackInfo<v8::Value>&
++# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args
++# define _NAN_GETTER_RETURN_TYPE void
++
++# define _NAN_SETTER_ARGS_TYPE const v8::PropertyCallbackInfo<void>&
++# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args
++# define _NAN_SETTER_RETURN_TYPE void
++
++# define _NAN_PROPERTY_GETTER_ARGS_TYPE                                        \
++    const v8::PropertyCallbackInfo<v8::Value>&
++# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args
++# define _NAN_PROPERTY_GETTER_RETURN_TYPE void
++
++# define _NAN_PROPERTY_SETTER_ARGS_TYPE                                        \
++    const v8::PropertyCallbackInfo<v8::Value>&
++# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args
++# define _NAN_PROPERTY_SETTER_RETURN_TYPE void
++
++# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE                                    \
++    const v8::PropertyCallbackInfo<v8::Array>&
++# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args
++# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE void
++
++# define _NAN_PROPERTY_DELETER_ARGS_TYPE                                       \
++    const v8::PropertyCallbackInfo<v8::Boolean>&
++# define _NAN_PROPERTY_DELETER_ARGS                                            \
++    _NAN_PROPERTY_DELETER_ARGS_TYPE args
++# define _NAN_PROPERTY_DELETER_RETURN_TYPE void
++
++# define _NAN_PROPERTY_QUERY_ARGS_TYPE                                         \
++    const v8::PropertyCallbackInfo<v8::Integer>&
++# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args
++# define _NAN_PROPERTY_QUERY_RETURN_TYPE void
++
++# define _NAN_INDEX_GETTER_ARGS_TYPE                                           \
++    const v8::PropertyCallbackInfo<v8::Value>&
++# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args
++# define _NAN_INDEX_GETTER_RETURN_TYPE void
++
++# define _NAN_INDEX_SETTER_ARGS_TYPE                                           \
++    const v8::PropertyCallbackInfo<v8::Value>&
++# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args
++# define _NAN_INDEX_SETTER_RETURN_TYPE void
++
++# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE                                       \
++    const v8::PropertyCallbackInfo<v8::Array>&
++# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args
++# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE void
++
++# define _NAN_INDEX_DELETER_ARGS_TYPE                                          \
++    const v8::PropertyCallbackInfo<v8::Boolean>&
++# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args
++# define _NAN_INDEX_DELETER_RETURN_TYPE void
++
++# define _NAN_INDEX_QUERY_ARGS_TYPE                                            \
++    const v8::PropertyCallbackInfo<v8::Integer>&
++# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args
++# define _NAN_INDEX_QUERY_RETURN_TYPE void
++
++  typedef v8::FunctionCallback NanFunctionCallback;
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> NanNew() {
++    return T::New(v8::Isolate::GetCurrent());
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<T> NanNew(P arg1) {
++    return T::New(v8::Isolate::GetCurrent(), arg1);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::Signature> NanNew(
++      v8::Handle<v8::FunctionTemplate> receiver
++    , int argc
++    , v8::Handle<v8::FunctionTemplate> argv[] = 0) {
++    return v8::Signature::New(v8::Isolate::GetCurrent(), receiver, argc, argv);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::FunctionTemplate> NanNew(
++      NanFunctionCallback callback
++    , v8::Handle<v8::Value> data = v8::Handle<v8::Value>()
++    , v8::Handle<v8::Signature> signature = v8::Handle<v8::Signature>()) {
++    return T::New(v8::Isolate::GetCurrent(), callback, data, signature);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> NanNew(v8::Handle<T> arg1) {
++    return v8::Local<T>::New(v8::Isolate::GetCurrent(), arg1);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> NanNew(const v8::Persistent<T> &arg1) {
++    return v8::Local<T>::New(v8::Isolate::GetCurrent(), arg1);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<T> NanNew(P arg1, int arg2) {
++    return T::New(v8::Isolate::GetCurrent(), arg1, arg2);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Array> NanNew<v8::Array>() {
++    return v8::Array::New(v8::Isolate::GetCurrent());
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Array> NanNew<v8::Array>(int length) {
++    return v8::Array::New(v8::Isolate::GetCurrent(), length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Date> NanNew<v8::Date>(double time) {
++    return v8::Date::New(v8::Isolate::GetCurrent(), time).As<v8::Date>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Date> NanNew<v8::Date>(int time) {
++    return v8::Date::New(v8::Isolate::GetCurrent(), time).As<v8::Date>();
++  }
++
++  typedef v8::UnboundScript NanUnboundScript;
++  typedef v8::Script NanBoundScript;
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<T> NanNew(
++      P s
++    , const v8::ScriptOrigin& origin
++  ) {
++    v8::ScriptCompiler::Source source(s, origin);
++    return v8::ScriptCompiler::CompileUnbound(
++        v8::Isolate::GetCurrent(), &source);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<NanUnboundScript> NanNew<NanUnboundScript>(
++      v8::Local<v8::String> s
++  ) {
++    v8::ScriptCompiler::Source source(s);
++    return v8::ScriptCompiler::CompileUnbound(
++        v8::Isolate::GetCurrent(), &source);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::BooleanObject> NanNew(bool value) {
++    return v8::BooleanObject::New(value).As<v8::BooleanObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::StringObject>
++  NanNew<v8::StringObject, v8::Local<v8::String> >(
++      v8::Local<v8::String> value) {
++    return v8::StringObject::New(value).As<v8::StringObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::StringObject>
++  NanNew<v8::StringObject, v8::Handle<v8::String> >(
++      v8::Handle<v8::String> value) {
++    return v8::StringObject::New(value).As<v8::StringObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::NumberObject> NanNew<v8::NumberObject>(double val) {
++    return v8::NumberObject::New(
++        v8::Isolate::GetCurrent(), val).As<v8::NumberObject>();
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Handle<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Local<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Handle<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Local<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Uint32> NanNew<v8::Uint32, int32_t>(int32_t val) {
++    return v8::Uint32::NewFromUnsigned(
++        v8::Isolate::GetCurrent(), val)->ToUint32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Uint32> NanNew<v8::Uint32, uint32_t>(uint32_t val) {
++    return v8::Uint32::NewFromUnsigned(
++        v8::Isolate::GetCurrent(), val)->ToUint32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Int32> NanNew<v8::Int32, int32_t>(int32_t val) {
++    return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Int32> NanNew<v8::Int32, uint32_t>(uint32_t val) {
++    return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, char *>(
++      char *arg
++    , int length) {
++    return v8::String::NewFromUtf8(
++        v8::Isolate::GetCurrent()
++      , arg
++      , v8::String::kNormalString
++      , length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const char *>(
++      const char *arg
++    , int length) {
++    return v8::String::NewFromUtf8(
++        v8::Isolate::GetCurrent()
++      , arg
++      , v8::String::kNormalString
++      , length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, char *>(char *arg) {
++    return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), arg);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const char *>(
++      const char *arg) {
++    return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), arg);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint8_t *>(
++      uint8_t *arg
++    , int length) {
++    return v8::String::NewFromOneByte(
++        v8::Isolate::GetCurrent()
++      , arg
++      , v8::String::kNormalString
++      , length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint8_t *>(
++      const uint8_t *arg
++    , int length) {
++    return v8::String::NewFromOneByte(
++        v8::Isolate::GetCurrent()
++      , arg
++      , v8::String::kNormalString
++      , length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint8_t *>(uint8_t *arg) {
++    return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint8_t *>(
++      const uint8_t *arg) {
++    return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint16_t *>(
++      uint16_t *arg
++    , int length) {
++    return v8::String::NewFromTwoByte(
++        v8::Isolate::GetCurrent()
++      , arg
++      , v8::String::kNormalString
++      , length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint16_t *>(
++      const uint16_t *arg
++    , int length) {
++    return v8::String::NewFromTwoByte(
++        v8::Isolate::GetCurrent()
++      , arg
++      , v8::String::kNormalString
++      , length);
++  }
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint16_t *>(
++      uint16_t *arg) {
++    return v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), arg);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint16_t *>(
++      const uint16_t *arg) {
++    return v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), arg);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, std::string>(
++      std::string arg) {
++    return NanNew<v8::String>(arg.c_str(), arg.size());
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String>() {
++    return v8::String::Empty(v8::Isolate::GetCurrent());
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(const char* arg, int length = -1) {
++    return NanNew<v8::String>(arg, length);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      const uint8_t* arg
++    , int length = -1) {
++    return NanNew<v8::String>(arg, length);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      const uint16_t* arg
++    , int length = -1) {
++    return NanNew<v8::String>(arg, length);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      const std::string& arg) {
++    return NanNew<v8::String>(arg.c_str(), arg.size());
++  }
++
++  NAN_INLINE v8::Local<v8::Number> NanNew(double val) {
++    return NanNew<v8::Number>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::Integer> NanNew(int val) {
++    return NanNew<v8::Integer>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::Uint32> NanNew(unsigned int val) {
++    return NanNew<v8::Uint32>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::Boolean> NanNew(bool val) {
++    return NanNew<v8::Boolean>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      v8::String::ExternalStringResource *resource) {
++    return v8::String::NewExternal(v8::Isolate::GetCurrent(), resource);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      v8::String::ExternalAsciiStringResource *resource) {
++    return v8::String::NewExternal(v8::Isolate::GetCurrent(), resource);
++  }
++
++# define NanScope() v8::HandleScope scope(v8::Isolate::GetCurrent())
++# define NanEscapableScope()                                                   \
++  v8::EscapableHandleScope scope(v8::Isolate::GetCurrent())
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Handle<T> val) {
++    return NanNew(val);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> _NanEscapeScopeHelper(v8::Local<T> val) {
++    return val;
++  }
++
++# define NanEscapeScope(val) scope.Escape(_NanEscapeScopeHelper(val))
++# define NanLocker() v8::Locker locker(v8::Isolate::GetCurrent())
++# define NanUnlocker() v8::Unlocker unlocker(v8::Isolate::GetCurrent())
++# define NanReturnValue(value) return args.GetReturnValue().Set(value)
++# define NanReturnUndefined() return
++# define NanReturnNull() return args.GetReturnValue().SetNull()
++# define NanReturnEmptyString() return args.GetReturnValue().SetEmptyString()
++
++# define NanObjectWrapHandle(obj) obj->handle()
++
++  NAN_INLINE v8::Local<v8::Primitive> NanUndefined() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::Undefined(v8::Isolate::GetCurrent())));
++  }
++
++  NAN_INLINE v8::Local<v8::Primitive> NanNull() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::Null(v8::Isolate::GetCurrent())));
++  }
++
++  NAN_INLINE v8::Local<v8::Boolean> NanTrue() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::True(v8::Isolate::GetCurrent())));
++  }
++
++  NAN_INLINE v8::Local<v8::Boolean> NanFalse() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::False(v8::Isolate::GetCurrent())));
++  }
++
++  NAN_INLINE int NanAdjustExternalMemory(int bc) {
++    return static_cast<int>(
++        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc));
++  }
++
++  NAN_INLINE void NanSetTemplate(
++      v8::Handle<v8::Template> templ
++    , const char *name
++    , v8::Handle<v8::Data> value) {
++    templ->Set(v8::Isolate::GetCurrent(), name, value);
++  }
++
++  NAN_INLINE void NanSetTemplate(
++      v8::Handle<v8::Template> templ
++    , v8::Handle<v8::String> name
++    , v8::Handle<v8::Data> value
++    , v8::PropertyAttribute attributes) {
++    templ->Set(name, value, attributes);
++  }
++
++  NAN_INLINE v8::Local<v8::Context> NanGetCurrentContext() {
++    return v8::Isolate::GetCurrent()->GetCurrentContext();
++  }
++
++  NAN_INLINE void* NanGetInternalFieldPointer(
++      v8::Handle<v8::Object> object
++    , int index) {
++    return object->GetAlignedPointerFromInternalField(index);
++  }
++
++  NAN_INLINE void NanSetInternalFieldPointer(
++      v8::Handle<v8::Object> object
++    , int index
++    , void* value) {
++    object->SetAlignedPointerInInternalField(index, value);
++  }
++
++  NAN_INLINE void NanAddGCEpilogueCallback(
++      v8::Isolate::GCEpilogueCallback callback
++    , v8::GCType gc_type_filter = v8::kGCTypeAll) {
++    v8::Isolate::GetCurrent()->AddGCEpilogueCallback(callback, gc_type_filter);
++  }
++
++  NAN_INLINE void NanRemoveGCEpilogueCallback(
++      v8::Isolate::GCEpilogueCallback callback) {
++    v8::Isolate::GetCurrent()->RemoveGCEpilogueCallback(callback);
++  }
++
++  NAN_INLINE void NanAddGCPrologueCallback(
++      v8::Isolate::GCPrologueCallback callback
++    , v8::GCType gc_type_filter = v8::kGCTypeAll) {
++    v8::Isolate::GetCurrent()->AddGCPrologueCallback(callback, gc_type_filter);
++  }
++
++  NAN_INLINE void NanRemoveGCPrologueCallback(
++      v8::Isolate::GCPrologueCallback callback) {
++    v8::Isolate::GetCurrent()->RemoveGCPrologueCallback(callback);
++  }
++
++  NAN_INLINE void NanGetHeapStatistics(
++      v8::HeapStatistics *heap_statistics) {
++    v8::Isolate::GetCurrent()->GetHeapStatistics(heap_statistics);
++  }
++
++  NAN_DEPRECATED NAN_INLINE v8::Local<v8::String> NanSymbol(
++      const char* data, int length = -1) {
++    return NanNew<v8::String>(data, length);
++  }
++
++  template<typename T>
++  NAN_INLINE void NanAssignPersistent(
++      v8::Persistent<T>& handle
++    , v8::Handle<T> obj) {
++      handle.Reset(v8::Isolate::GetCurrent(), obj);
++  }
++
++  template<typename T>
++  NAN_INLINE void NanAssignPersistent(
++      v8::Persistent<T>& handle
++    , const v8::Persistent<T>& obj) {
++      handle.Reset(v8::Isolate::GetCurrent(), obj);
++  }
++
++  template<typename T, typename P>
++  class _NanWeakCallbackData;
++
++  template<typename T, typename P>
++  struct _NanWeakCallbackInfo {
++    typedef void (*Callback)(const _NanWeakCallbackData<T, P>& data);
++    NAN_INLINE _NanWeakCallbackInfo(v8::Handle<T> handle, P* param, Callback cb)
++      : parameter(param), callback(cb) {
++       NanAssignPersistent(persistent, handle);
++    }
++
++    NAN_INLINE ~_NanWeakCallbackInfo() {
++      persistent.Reset();
++    }
++
++    P* const parameter;
++    Callback const callback;
++    v8::Persistent<T> persistent;
++  };
++
++  template<typename T, typename P>
++  class _NanWeakCallbackData {
++   public:
++    NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo<T, P> *info)
++      : info_(info) { }
++
++    NAN_INLINE v8::Local<T> GetValue() const {
++      return NanNew(info_->persistent);
++    }
++
++    NAN_INLINE P* GetParameter() const { return info_->parameter; }
++
++    NAN_INLINE bool IsNearDeath() const {
++      return info_->persistent.IsNearDeath();
++    }
++
++    NAN_INLINE void Revive() const;
++
++    NAN_INLINE _NanWeakCallbackInfo<T, P>* GetCallbackInfo() const {
++      return info_;
++    }
++
++    NAN_DEPRECATED NAN_INLINE void Dispose() const {
++    }
++
++   private:
++    _NanWeakCallbackInfo<T, P>* info_;
++  };
++
++  template<typename T, typename P>
++  static void _NanWeakCallbackDispatcher(
++    const v8::WeakCallbackData<T, _NanWeakCallbackInfo<T, P> > &data) {
++      _NanWeakCallbackInfo<T, P> *info = data.GetParameter();
++      _NanWeakCallbackData<T, P> wcbd(info);
++      info->callback(wcbd);
++      if (wcbd.IsNearDeath()) {
++        delete wcbd.GetCallbackInfo();
++      }
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE void _NanWeakCallbackData<T, P>::Revive() const {
++      info_->persistent.SetWeak(info_, &_NanWeakCallbackDispatcher<T, P>);
++  }
++
++template<typename T, typename P>
++NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
++    v8::Handle<T> handle
++  , P* parameter
++  , typename _NanWeakCallbackInfo<T, P>::Callback callback) {
++    _NanWeakCallbackInfo<T, P> *cbinfo =
++     new _NanWeakCallbackInfo<T, P>(handle, parameter, callback);
++    cbinfo->persistent.SetWeak(cbinfo, &_NanWeakCallbackDispatcher<T, P>);
++    return cbinfo;
++}
++
++# define NAN_WEAK_CALLBACK(name)                                               \
++    template<typename T, typename P>                                           \
++    static void name(const _NanWeakCallbackData<T, P> &data)
++
++# define _NAN_ERROR(fun, errmsg) fun(NanNew<v8::String>(errmsg))
++
++# define _NAN_THROW_ERROR(fun, errmsg)                                         \
++    do {                                                                       \
++      NanScope();                                                              \
++      v8::Isolate::GetCurrent()->ThrowException(_NAN_ERROR(fun, errmsg));      \
++    } while (0);
++
++  NAN_INLINE v8::Local<v8::Value> NanError(const char* errmsg) {
++    return  _NAN_ERROR(v8::Exception::Error, errmsg);
++  }
++
++  NAN_INLINE void NanThrowError(const char* errmsg) {
++    _NAN_THROW_ERROR(v8::Exception::Error, errmsg);
++  }
++
++  NAN_INLINE void NanThrowError(v8::Handle<v8::Value> error) {
++    NanScope();
++    v8::Isolate::GetCurrent()->ThrowException(error);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanError(
++      const char *msg
++    , const int errorNumber
++  ) {
++    v8::Local<v8::Value> err = v8::Exception::Error(NanNew<v8::String>(msg));
++    v8::Local<v8::Object> obj = err.As<v8::Object>();
++    obj->Set(NanNew<v8::String>("code"), NanNew<v8::Integer>(errorNumber));
++    return err;
++  }
++
++  NAN_INLINE void NanThrowError(
++      const char *msg
++    , const int errorNumber
++  ) {
++    NanThrowError(NanError(msg, errorNumber));
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanTypeError(const char* errmsg) {
++    return _NAN_ERROR(v8::Exception::TypeError, errmsg);
++  }
++
++  NAN_INLINE void NanThrowTypeError(const char* errmsg) {
++    _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanRangeError(const char* errmsg) {
++    return _NAN_ERROR(v8::Exception::RangeError, errmsg);
++  }
++
++  NAN_INLINE void NanThrowRangeError(const char* errmsg) {
++    _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg);
++  }
++
++  template<typename T> NAN_INLINE void NanDisposePersistent(
++      v8::Persistent<T> &handle
++  ) {
++    handle.Reset();
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (
++      char *data
++    , size_t length
++    , node::smalloc::FreeCallback callback
++    , void *hint
++  ) {
++    return node::Buffer::New(
++        v8::Isolate::GetCurrent(), data, length, callback, hint);
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (
++      const char *data
++    , uint32_t size
++  ) {
++    return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (uint32_t size) {
++    return node::Buffer::New(v8::Isolate::GetCurrent(), size);
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanBufferUse(
++      char* data
++    , uint32_t size
++  ) {
++    return node::Buffer::Use(v8::Isolate::GetCurrent(), data, size);
++  }
++
++  NAN_INLINE bool NanHasInstance(
++      v8::Persistent<v8::FunctionTemplate>& function_template
++    , v8::Handle<v8::Value> value
++  ) {
++    return NanNew(function_template)->HasInstance(value);
++  }
++
++  NAN_INLINE v8::Local<v8::Context> NanNewContextHandle(
++      v8::ExtensionConfiguration* extensions = NULL
++    , v8::Handle<v8::ObjectTemplate> tmpl = v8::Handle<v8::ObjectTemplate>()
++    , v8::Handle<v8::Value> obj = v8::Handle<v8::Value>()
++  ) {
++    v8::Isolate* isolate = v8::Isolate::GetCurrent();
++    return v8::Local<v8::Context>::New(
++        isolate
++      , v8::Context::New(isolate, extensions, tmpl, obj)
++    );
++  }
++
++  NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(
++      v8::Local<v8::String> s
++    , const v8::ScriptOrigin& origin
++  ) {
++    v8::ScriptCompiler::Source source(s, origin);
++    return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
++  }
++
++  NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(
++      v8::Local<v8::String> s
++  ) {
++    v8::ScriptCompiler::Source source(s);
++    return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanRunScript(
++      v8::Handle<NanUnboundScript> script
++  ) {
++    return script->BindToCurrentContext()->Run();
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanRunScript(
++      v8::Handle<NanBoundScript> script
++  ) {
++    return script->Run();
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
++      v8::Handle<v8::Object> target
++    , v8::Handle<v8::Function> func
++    , int argc
++    , v8::Handle<v8::Value>* argv) {
++    return NanNew(node::MakeCallback(
++        v8::Isolate::GetCurrent(), target, func, argc, argv));
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
++      v8::Handle<v8::Object> target
++    , v8::Handle<v8::String> symbol
++    , int argc
++    , v8::Handle<v8::Value>* argv) {
++    return NanNew(node::MakeCallback(
++        v8::Isolate::GetCurrent(), target, symbol, argc, argv));
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
++      v8::Handle<v8::Object> target
++    , const char* method
++    , int argc
++    , v8::Handle<v8::Value>* argv) {
++    return NanNew(node::MakeCallback(
++        v8::Isolate::GetCurrent(), target, method, argc, argv));
++  }
++
++  template<typename T>
++  NAN_INLINE void NanSetIsolateData(
++      v8::Isolate *isolate
++    , T *data
++  ) {
++      isolate->SetData(0, data);
++  }
++
++  template<typename T>
++  NAN_INLINE T *NanGetIsolateData(
++      v8::Isolate *isolate
++  ) {
++      return static_cast<T*>(isolate->GetData(0));
++  }
++
++  class NanAsciiString {
++   public:
++    NAN_INLINE explicit NanAsciiString(v8::Handle<v8::Value> from) {
++      v8::Local<v8::String> toStr = from->ToString();
++      int buf_size = toStr->Length() + 1;
++      buf = new char[buf_size];
++      size = toStr->WriteOneByte(
++          reinterpret_cast<unsigned char*>(buf), 0, buf_size);
++    }
++
++    NAN_INLINE int Size() const {
++      return size;
++    }
++
++    NAN_INLINE char* operator*() { return buf; }
++
++    NAN_INLINE ~NanAsciiString() {
++      delete[] buf;
++    }
++
++   private:
++    char *buf;
++    int size;
++  };
++
++  class NanUtf8String {
++   public:
++    NAN_INLINE explicit NanUtf8String(v8::Handle<v8::Value> from) {
++      v8::Local<v8::String> toStr = from->ToString();
++      int buf_size = toStr->Utf8Length() + 1;
++      buf = new char[buf_size];
++      size = toStr->WriteUtf8(buf, buf_size);
++    }
++
++    NAN_INLINE int Size() const {
++      return size;
++    }
++
++    NAN_INLINE char* operator*() { return buf; }
++
++    NAN_INLINE ~NanUtf8String() {
++      delete[] buf;
++    }
++
++   private:
++    char *buf;
++    int size;
++  };
++
++  class NanUcs2String {
++   public:
++    NAN_INLINE explicit NanUcs2String(v8::Handle<v8::Value> from) {
++      v8::Local<v8::String> toStr = from->ToString();
++      int buf_size = toStr->Length() + 1;
++      buf = new uint16_t[buf_size];
++      size = toStr->Write(buf, 0, buf_size);
++    }
++
++    NAN_INLINE int Size() const {
++      return size;
++    }
++
++    NAN_INLINE uint16_t* operator*() { return buf; }
++
++    NAN_INLINE ~NanUcs2String() {
++      delete[] buf;
++    }
++
++   private:
++    uint16_t *buf;
++    int size;
++  };
++
++#else
++// Node 0.8 and 0.10
++
++# define _NAN_METHOD_ARGS_TYPE const v8::Arguments&
++# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args
++# define _NAN_METHOD_RETURN_TYPE v8::Handle<v8::Value>
++
++# define _NAN_GETTER_ARGS_TYPE const v8::AccessorInfo &
++# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args
++# define _NAN_GETTER_RETURN_TYPE v8::Handle<v8::Value>
++
++# define _NAN_SETTER_ARGS_TYPE const v8::AccessorInfo &
++# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args
++# define _NAN_SETTER_RETURN_TYPE void
++
++# define _NAN_PROPERTY_GETTER_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args
++# define _NAN_PROPERTY_GETTER_RETURN_TYPE v8::Handle<v8::Value>
++
++# define _NAN_PROPERTY_SETTER_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args
++# define _NAN_PROPERTY_SETTER_RETURN_TYPE v8::Handle<v8::Value>
++
++# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args
++# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE v8::Handle<v8::Array>
++
++# define _NAN_PROPERTY_DELETER_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_PROPERTY_DELETER_ARGS _NAN_PROPERTY_DELETER_ARGS_TYPE args
++# define _NAN_PROPERTY_DELETER_RETURN_TYPE v8::Handle<v8::Boolean>
++
++# define _NAN_PROPERTY_QUERY_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args
++# define _NAN_PROPERTY_QUERY_RETURN_TYPE v8::Handle<v8::Integer>
++
++# define _NAN_INDEX_GETTER_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args
++# define _NAN_INDEX_GETTER_RETURN_TYPE v8::Handle<v8::Value>
++
++# define _NAN_INDEX_SETTER_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args
++# define _NAN_INDEX_SETTER_RETURN_TYPE v8::Handle<v8::Value>
++
++# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args
++# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE v8::Handle<v8::Array>
++
++# define _NAN_INDEX_DELETER_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args
++# define _NAN_INDEX_DELETER_RETURN_TYPE v8::Handle<v8::Boolean>
++
++# define _NAN_INDEX_QUERY_ARGS_TYPE const v8::AccessorInfo&
++# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args
++# define _NAN_INDEX_QUERY_RETURN_TYPE v8::Handle<v8::Integer>
++
++  typedef v8::InvocationCallback NanFunctionCallback;
++
++  NAN_DEPRECATED NAN_INLINE v8::Local<v8::String> NanSymbol(
++      const char* data, int length = -1) {
++    return v8::String::NewSymbol(data, length);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> NanNew() {
++    return v8::Local<T>::New(T::New());
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> NanNew(v8::Handle<T> arg) {
++    return v8::Local<T>::New(arg);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::Signature> NanNew(
++      v8::Handle<v8::FunctionTemplate> receiver
++    , int argc
++    , v8::Handle<v8::FunctionTemplate> argv[] = 0) {
++    return v8::Signature::New(receiver, argc, argv);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::FunctionTemplate> NanNew(
++      NanFunctionCallback callback
++    , v8::Handle<v8::Value> data = v8::Handle<v8::Value>()
++    , v8::Handle<v8::Signature> signature = v8::Handle<v8::Signature>()) {
++    return T::New(callback, data, signature);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<T> NanNew(const v8::Persistent<T> &arg) {
++    return v8::Local<T>::New(arg);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<T> NanNew(P arg) {
++    return v8::Local<T>::New(T::New(arg));
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<T> NanNew(P arg, int length) {
++    return v8::Local<T>::New(T::New(arg, length));
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Handle<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<typename T>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Local<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Handle<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<v8::RegExp> NanNew(
++      v8::Local<v8::String> pattern, v8::RegExp::Flags flags) {
++    return v8::RegExp::New(pattern, flags);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Array> NanNew<v8::Array>() {
++    return v8::Array::New();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Array> NanNew<v8::Array>(int length) {
++    return v8::Array::New(length);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Date> NanNew<v8::Date>(double time) {
++    return v8::Date::New(time).As<v8::Date>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Date> NanNew<v8::Date>(int time) {
++    return v8::Date::New(time).As<v8::Date>();
++  }
++
++  typedef v8::Script NanUnboundScript;
++  typedef v8::Script NanBoundScript;
++
++  template<typename T, typename P>
++  NAN_INLINE v8::Local<T> NanNew(
++      P s
++    , const v8::ScriptOrigin& origin
++  ) {
++    return v8::Script::New(s, const_cast<v8::ScriptOrigin *>(&origin));
++  }
++
++  template<>
++  NAN_INLINE v8::Local<NanUnboundScript> NanNew<NanUnboundScript>(
++      v8::Local<v8::String> s
++  ) {
++    return v8::Script::New(s);
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::BooleanObject> NanNew(bool value) {
++    return v8::BooleanObject::New(value).As<v8::BooleanObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::StringObject>
++  NanNew<v8::StringObject, v8::Local<v8::String> >(
++      v8::Local<v8::String> value) {
++    return v8::StringObject::New(value).As<v8::StringObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::StringObject>
++  NanNew<v8::StringObject, v8::Handle<v8::String> >(
++      v8::Handle<v8::String> value) {
++    return v8::StringObject::New(value).As<v8::StringObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::NumberObject> NanNew<v8::NumberObject>(double val) {
++    return v8::NumberObject::New(val).As<v8::NumberObject>();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Uint32> NanNew<v8::Uint32, int32_t>(int32_t val) {
++    return v8::Uint32::NewFromUnsigned(val)->ToUint32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Uint32> NanNew<v8::Uint32, uint32_t>(uint32_t val) {
++    return v8::Uint32::NewFromUnsigned(val)->ToUint32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Int32> NanNew<v8::Int32, int32_t>(int32_t val) {
++    return v8::Int32::New(val)->ToInt32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::Int32> NanNew<v8::Int32, uint32_t>(uint32_t val) {
++    return v8::Int32::New(val)->ToInt32();
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint8_t *>(
++      uint8_t *arg
++    , int length) {
++    int len = length;
++    if (len < 0) {
++      size_t temp = strlen(reinterpret_cast<const char *>(arg));
++      assert(temp <= INT_MAX && "too long string");
++      len = static_cast<int>(temp);
++    }
++    uint16_t *warg = new uint16_t[len];
++    for (int i = 0; i < len; i++) {
++      warg[i] = arg[i];
++    }
++    v8::Local<v8::String> retval = v8::String::New(warg, len);
++    delete[] warg;
++    return retval;
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint8_t *>(
++      const uint8_t *arg
++    , int length) {
++    int len = length;
++    if (len < 0) {
++      size_t temp = strlen(reinterpret_cast<const char *>(arg));
++      assert(temp <= INT_MAX && "too long string");
++      len = static_cast<int>(temp);
++    }
++    uint16_t *warg = new uint16_t[len];
++    for (int i = 0; i < len; i++) {
++      warg[i] = arg[i];
++    }
++    v8::Local<v8::String> retval = v8::String::New(warg, len);
++    delete[] warg;
++    return retval;
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, uint8_t *>(uint8_t *arg) {
++    size_t temp = strlen(reinterpret_cast<char *>(arg));
++    assert(temp <= INT_MAX && "too long string");
++    int length = static_cast<int>(temp);
++    uint16_t *warg = new uint16_t[length];
++    for (int i = 0; i < length; i++) {
++      warg[i] = arg[i];
++    }
++
++    v8::Local<v8::String> retval = v8::String::New(warg, length);
++    delete[] warg;
++    return retval;
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, const uint8_t *>(
++      const uint8_t *arg) {
++    size_t temp = strlen(reinterpret_cast<const char *>(arg));
++    assert(temp <= INT_MAX && "too long string");
++    int length = static_cast<int>(temp);
++    uint16_t *warg = new uint16_t[length];
++    for (int i = 0; i < length; i++) {
++      warg[i] = arg[i];
++    }
++    v8::Local<v8::String> retval = v8::String::New(warg, length);
++    delete[] warg;
++    return retval;
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String, std::string>(
++      std::string arg) {
++    return NanNew<v8::String>(arg.c_str(), arg.size());
++  }
++
++  template<>
++  NAN_INLINE v8::Local<v8::String> NanNew<v8::String>() {
++    return v8::String::Empty();
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(const char* arg, int length = -1) {
++    return NanNew<v8::String>(arg, length);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      const uint8_t* arg
++    , int length = -1) {
++    return NanNew<v8::String>(arg, length);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      const uint16_t* arg
++    , int length = -1) {
++    return NanNew<v8::String>(arg, length);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      std::string& arg) {
++    return NanNew<v8::String>(arg.c_str(), arg.size());
++  }
++
++  NAN_INLINE v8::Local<v8::Number> NanNew(double val) {
++    return NanNew<v8::Number>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::Integer> NanNew(int val) {
++    return NanNew<v8::Integer>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::Uint32> NanNew(unsigned int val) {
++    return NanNew<v8::Uint32>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::Boolean> NanNew(bool val) {
++    return NanNew<v8::Boolean>(val);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      v8::String::ExternalStringResource *resource) {
++    return v8::String::NewExternal(resource);
++  }
++
++  NAN_INLINE v8::Local<v8::String> NanNew(
++      v8::String::ExternalAsciiStringResource *resource) {
++    return v8::String::NewExternal(resource);
++  }
++
++# define NanScope() v8::HandleScope scope
++# define NanEscapableScope() v8::HandleScope scope
++# define NanEscapeScope(val) scope.Close(val)
++# define NanLocker() v8::Locker locker
++# define NanUnlocker() v8::Unlocker unlocker
++# define NanReturnValue(value) return scope.Close(value)
++# define NanReturnUndefined() return v8::Undefined()
++# define NanReturnNull() return v8::Null()
++# define NanReturnEmptyString() return v8::String::Empty()
++# define NanObjectWrapHandle(obj) v8::Local<v8::Object>::New(obj->handle_)
++
++  NAN_INLINE v8::Local<v8::Primitive> NanUndefined() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::Undefined()));
++  }
++
++  NAN_INLINE v8::Local<v8::Primitive> NanNull() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::Null()));
++  }
++
++  NAN_INLINE v8::Local<v8::Boolean> NanTrue() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::True()));
++  }
++
++  NAN_INLINE v8::Local<v8::Boolean> NanFalse() {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(v8::False()));
++  }
++
++  NAN_INLINE int NanAdjustExternalMemory(int bc) {
++    return static_cast<int>(v8::V8::AdjustAmountOfExternalAllocatedMemory(bc));
++  }
++
++  NAN_INLINE void NanSetTemplate(
++      v8::Handle<v8::Template> templ
++    , const char *name
++    , v8::Handle<v8::Data> value) {
++    templ->Set(name, value);
++  }
++
++  NAN_INLINE void NanSetTemplate(
++      v8::Handle<v8::Template> templ
++    , v8::Handle<v8::String> name
++    , v8::Handle<v8::Data> value
++    , v8::PropertyAttribute attributes) {
++    templ->Set(name, value, attributes);
++  }
++
++  NAN_INLINE v8::Local<v8::Context> NanGetCurrentContext() {
++    return v8::Context::GetCurrent();
++  }
++
++  NAN_INLINE void* NanGetInternalFieldPointer(
++      v8::Handle<v8::Object> object
++    , int index) {
++    return object->GetPointerFromInternalField(index);
++  }
++
++  NAN_INLINE void NanSetInternalFieldPointer(
++      v8::Handle<v8::Object> object
++    , int index
++    , void* value) {
++    object->SetPointerInInternalField(index, value);
++  }
++
++  NAN_INLINE void NanAddGCEpilogueCallback(
++    v8::GCEpilogueCallback callback
++  , v8::GCType gc_type_filter = v8::kGCTypeAll) {
++    v8::V8::AddGCEpilogueCallback(callback, gc_type_filter);
++  }
++  NAN_INLINE void NanRemoveGCEpilogueCallback(
++    v8::GCEpilogueCallback callback) {
++    v8::V8::RemoveGCEpilogueCallback(callback);
++  }
++  NAN_INLINE void NanAddGCPrologueCallback(
++    v8::GCPrologueCallback callback
++  , v8::GCType gc_type_filter = v8::kGCTypeAll) {
++    v8::V8::AddGCPrologueCallback(callback, gc_type_filter);
++  }
++  NAN_INLINE void NanRemoveGCPrologueCallback(
++    v8::GCPrologueCallback callback) {
++    v8::V8::RemoveGCPrologueCallback(callback);
++  }
++  NAN_INLINE void NanGetHeapStatistics(
++    v8::HeapStatistics *heap_statistics) {
++    v8::V8::GetHeapStatistics(heap_statistics);
++  }
++
++  template<typename T>
++  NAN_INLINE void NanAssignPersistent(
++      v8::Persistent<T>& handle
++    , v8::Handle<T> obj) {
++      handle.Dispose();
++      handle = v8::Persistent<T>::New(obj);
++  }
++
++  template<typename T, typename P>
++  class _NanWeakCallbackData;
++
++  template<typename T, typename P>
++  struct _NanWeakCallbackInfo {
++    typedef void (*Callback)(const _NanWeakCallbackData<T, P> &data);
++    NAN_INLINE _NanWeakCallbackInfo(v8::Handle<T> handle, P* param, Callback cb)
++      : parameter(param)
++      , callback(cb)
++      , persistent(v8::Persistent<T>::New(handle)) { }
++
++    NAN_INLINE ~_NanWeakCallbackInfo() {
++      persistent.Dispose();
++      persistent.Clear();
++    }
++
++    P* const parameter;
++    Callback const callback;
++    v8::Persistent<T> persistent;
++  };
++
++  template<typename T, typename P>
++  class _NanWeakCallbackData {
++   public:
++    NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo<T, P> *info)
++      : info_(info) { }
++
++    NAN_INLINE v8::Local<T> GetValue() const {
++      return NanNew(info_->persistent);
++    }
++
++    NAN_INLINE P* GetParameter() const { return info_->parameter; }
++
++    NAN_INLINE bool IsNearDeath() const {
++      return info_->persistent.IsNearDeath();
++    }
++
++    NAN_INLINE void Revive() const;
++
++    NAN_INLINE _NanWeakCallbackInfo<T, P>* GetCallbackInfo() const {
++      return info_;
++    }
++
++    NAN_DEPRECATED NAN_INLINE void Dispose() const {
++    }
++
++   private:
++    _NanWeakCallbackInfo<T, P>* info_;
++  };
++
++  template<typename T, typename P>
++  static void _NanWeakPersistentDispatcher(
++      v8::Persistent<v8::Value> object, void *data) {
++    _NanWeakCallbackInfo<T, P>* info =
++        static_cast<_NanWeakCallbackInfo<T, P>*>(data);
++    _NanWeakCallbackData<T, P> wcbd(info);
++    info->callback(wcbd);
++    if (wcbd.IsNearDeath()) {
++      delete wcbd.GetCallbackInfo();
++    }
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE void _NanWeakCallbackData<T, P>::Revive() const {
++      info_->persistent.MakeWeak(
++          info_
++        , &_NanWeakPersistentDispatcher<T, P>);
++  }
++
++  template<typename T, typename P>
++  NAN_INLINE _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(
++    v8::Handle<T> handle
++  , P* parameter
++  , typename _NanWeakCallbackInfo<T, P>::Callback callback) {
++      _NanWeakCallbackInfo<T, P> *cbinfo =
++        new _NanWeakCallbackInfo<T, P>(handle, parameter, callback);
++      cbinfo->persistent.MakeWeak(
++          cbinfo
++        , &_NanWeakPersistentDispatcher<T, P>);
++      return cbinfo;
++  }
++
++# define NAN_WEAK_CALLBACK(name)                                               \
++    template<typename T, typename P>                                           \
++    static void name(const _NanWeakCallbackData<T, P> &data)
++
++# define _NAN_ERROR(fun, errmsg)                                               \
++    fun(v8::String::New(errmsg))
++
++# define _NAN_THROW_ERROR(fun, errmsg)                                         \
++    do {                                                                       \
++      NanScope();                                                              \
++      return v8::Local<v8::Value>::New(                                        \
++        v8::ThrowException(_NAN_ERROR(fun, errmsg)));                          \
++    } while (0);
++
++  NAN_INLINE v8::Local<v8::Value> NanError(const char* errmsg) {
++    return _NAN_ERROR(v8::Exception::Error, errmsg);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanThrowError(const char* errmsg) {
++    _NAN_THROW_ERROR(v8::Exception::Error, errmsg);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanThrowError(
++      v8::Handle<v8::Value> error
++  ) {
++    NanScope();
++    return v8::Local<v8::Value>::New(v8::ThrowException(error));
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanError(
++      const char *msg
++    , const int errorNumber
++  ) {
++    v8::Local<v8::Value> err = v8::Exception::Error(v8::String::New(msg));
++    v8::Local<v8::Object> obj = err.As<v8::Object>();
++    obj->Set(v8::String::New("code"), v8::Int32::New(errorNumber));
++    return err;
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanThrowError(
++      const char *msg
++    , const int errorNumber
++  ) {
++    return NanThrowError(NanError(msg, errorNumber));
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanTypeError(const char* errmsg) {
++    return _NAN_ERROR(v8::Exception::TypeError, errmsg);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanThrowTypeError(
++      const char* errmsg
++  ) {
++    _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanRangeError(
++      const char* errmsg
++  ) {
++    return _NAN_ERROR(v8::Exception::RangeError, errmsg);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanThrowRangeError(
++      const char* errmsg
++  ) {
++    _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg);
++  }
++
++  template<typename T>
++  NAN_INLINE void NanDisposePersistent(
++      v8::Persistent<T> &handle) {  // NOLINT(runtime/references)
++    handle.Dispose();
++    handle.Clear();
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (
++      char *data
++    , size_t length
++    , node::Buffer::free_callback callback
++    , void *hint
++  ) {
++    return NanNew(
++        node::Buffer::New(data, length, callback, hint)->handle_);
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (
++      const char *data
++    , uint32_t size
++  ) {
++#if NODE_MODULE_VERSION >= 0x000B
++    return NanNew(node::Buffer::New(data, size)->handle_);
++#else
++    return NanNew(
++      node::Buffer::New(const_cast<char*>(data), size)->handle_);
++#endif
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanNewBufferHandle (uint32_t size) {
++    return NanNew(node::Buffer::New(size)->handle_);
++  }
++
++  NAN_INLINE void FreeData(char *data, void *hint) {
++    delete[] data;
++  }
++
++  NAN_INLINE v8::Local<v8::Object> NanBufferUse(
++      char* data
++    , uint32_t size
++  ) {
++    return NanNew(
++        node::Buffer::New(data, size, FreeData, NULL)->handle_);
++  }
++
++  NAN_INLINE bool NanHasInstance(
++      v8::Persistent<v8::FunctionTemplate>& function_template
++    , v8::Handle<v8::Value> value
++  ) {
++    return function_template->HasInstance(value);
++  }
++
++  NAN_INLINE v8::Local<v8::Context> NanNewContextHandle(
++      v8::ExtensionConfiguration* extensions = NULL
++    , v8::Handle<v8::ObjectTemplate> tmpl = v8::Handle<v8::ObjectTemplate>()
++    , v8::Handle<v8::Value> obj = v8::Handle<v8::Value>()
++  ) {
++    v8::Persistent<v8::Context> ctx = v8::Context::New(extensions, tmpl, obj);
++    v8::Local<v8::Context> lctx = NanNew(ctx);
++    ctx.Dispose();
++    return lctx;
++  }
++
++  NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(
++      v8::Local<v8::String> s
++    , const v8::ScriptOrigin& origin
++  ) {
++    return v8::Script::Compile(s, const_cast<v8::ScriptOrigin *>(&origin));
++  }
++
++  NAN_INLINE v8::Local<NanBoundScript> NanCompileScript(
++    v8::Local<v8::String> s
++  ) {
++    return v8::Script::Compile(s);
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanRunScript(v8::Handle<v8::Script> script) {
++    return script->Run();
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
++      v8::Handle<v8::Object> target
++    , v8::Handle<v8::Function> func
++    , int argc
++    , v8::Handle<v8::Value>* argv) {
++# if NODE_VERSION_AT_LEAST(0, 8, 0)
++    return NanNew(node::MakeCallback(target, func, argc, argv));
++# else
++    v8::TryCatch try_catch;
++    v8::Local<v8::Value> result = NanNew(func->Call(target, argc, argv));
++    if (try_catch.HasCaught()) {
++        node::FatalException(try_catch);
++    }
++    return result;
++# endif
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
++      v8::Handle<v8::Object> target
++    , v8::Handle<v8::String> symbol
++    , int argc
++    , v8::Handle<v8::Value>* argv) {
++# if NODE_VERSION_AT_LEAST(0, 8, 0)
++    return NanNew(node::MakeCallback(target, symbol, argc, argv));
++# else
++    v8::Local<v8::Function> callback = target->Get(symbol).As<v8::Function>();
++    return NanMakeCallback(target, callback, argc, argv);
++# endif
++  }
++
++  NAN_INLINE v8::Local<v8::Value> NanMakeCallback(
++      v8::Handle<v8::Object> target
++    , const char* method
++    , int argc
++    , v8::Handle<v8::Value>* argv) {
++# if NODE_VERSION_AT_LEAST(0, 8, 0)
++    return NanNew(node::MakeCallback(target, method, argc, argv));
++# else
++    return NanMakeCallback(target, NanNew(method), argc, argv);
++# endif
++  }
++
++  template<typename T>
++  NAN_INLINE void NanSetIsolateData(
++      v8::Isolate *isolate
++    , T *data
++  ) {
++      isolate->SetData(data);
++  }
++
++  template<typename T>
++  NAN_INLINE T *NanGetIsolateData(
++      v8::Isolate *isolate
++  ) {
++      return static_cast<T*>(isolate->GetData());
++  }
++
++  class NanAsciiString {
++   public:
++    NAN_INLINE explicit NanAsciiString(v8::Handle<v8::Value> from) {
++      v8::Local<v8::String> toStr = from->ToString();
++      int buf_size = toStr->Length() + 1;
++      buf = new char[buf_size];
++      size = toStr->WriteAscii(buf, 0, buf_size);
++    }
++
++    NAN_INLINE int Size() const {
++      return size;
++    }
++
++    NAN_INLINE char* operator*() { return buf; }
++
++    NAN_INLINE ~NanAsciiString() {
++      delete[] buf;
++    }
++
++   private:
++    char *buf;
++    int size;
++  };
++
++  class NanUtf8String {
++   public:
++    NAN_INLINE explicit NanUtf8String(v8::Handle<v8::Value> from) {
++      v8::Local<v8::String> toStr = from->ToString();
++      int buf_size = toStr->Utf8Length() + 1;
++      buf = new char[buf_size];
++      size = toStr->WriteUtf8(buf, buf_size);
++    }
++
++    NAN_INLINE int Size() const {
++      return size;
++    }
++
++    NAN_INLINE char* operator*() { return buf; }
++
++    NAN_INLINE ~NanUtf8String() {
++      delete[] buf;
++    }
++
++   private:
++    char *buf;
++    int size;
++  };
++
++  class NanUcs2String {
++   public:
++    NAN_INLINE explicit NanUcs2String(v8::Handle<v8::Value> from) {
++      v8::Local<v8::String> toStr = from->ToString();
++      int buf_size = toStr->Length() + 1;
++      buf = new uint16_t[buf_size];
++      size = toStr->Write(buf, 0, buf_size);
++    }
++
++    NAN_INLINE int Size() const {
++      return size;
++    }
++
++    NAN_INLINE uint16_t* operator*() { return buf; }
++
++    NAN_INLINE ~NanUcs2String() {
++      delete[] buf;
++    }
++
++   private:
++    uint16_t *buf;
++    int size;
++  };
++
++#endif  // NODE_MODULE_VERSION
++
++typedef void (*NanFreeCallback)(char *data, void *hint);
++
++#define NAN_METHOD(name) _NAN_METHOD_RETURN_TYPE name(_NAN_METHOD_ARGS)
++#define NAN_GETTER(name)                                                       \
++    _NAN_GETTER_RETURN_TYPE name(                                              \
++        v8::Local<v8::String> property                                         \
++      , _NAN_GETTER_ARGS)
++#define NAN_SETTER(name)                                                       \
++    _NAN_SETTER_RETURN_TYPE name(                                              \
++        v8::Local<v8::String> property                                         \
++      , v8::Local<v8::Value> value                                             \
++      , _NAN_SETTER_ARGS)
++#define NAN_PROPERTY_GETTER(name)                                              \
++    _NAN_PROPERTY_GETTER_RETURN_TYPE name(                                     \
++        v8::Local<v8::String> property                                         \
++      , _NAN_PROPERTY_GETTER_ARGS)
++#define NAN_PROPERTY_SETTER(name)                                              \
++    _NAN_PROPERTY_SETTER_RETURN_TYPE name(                                     \
++        v8::Local<v8::String> property                                         \
++      , v8::Local<v8::Value> value                                             \
++      , _NAN_PROPERTY_SETTER_ARGS)
++#define NAN_PROPERTY_ENUMERATOR(name)                                          \
++    _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE name(_NAN_PROPERTY_ENUMERATOR_ARGS)
++#define NAN_PROPERTY_DELETER(name)                                             \
++    _NAN_PROPERTY_DELETER_RETURN_TYPE name(                                    \
++        v8::Local<v8::String> property                                         \
++      , _NAN_PROPERTY_DELETER_ARGS)
++#define NAN_PROPERTY_QUERY(name)                                               \
++    _NAN_PROPERTY_QUERY_RETURN_TYPE name(                                      \
++        v8::Local<v8::String> property                                         \
++      , _NAN_PROPERTY_QUERY_ARGS)
++# define NAN_INDEX_GETTER(name)                                                \
++    _NAN_INDEX_GETTER_RETURN_TYPE name(uint32_t index, _NAN_INDEX_GETTER_ARGS)
++#define NAN_INDEX_SETTER(name)                                                 \
++    _NAN_INDEX_SETTER_RETURN_TYPE name(                                        \
++        uint32_t index                                                         \
++      , v8::Local<v8::Value> value                                             \
++      , _NAN_INDEX_SETTER_ARGS)
++#define NAN_INDEX_ENUMERATOR(name)                                             \
++    _NAN_INDEX_ENUMERATOR_RETURN_TYPE name(_NAN_INDEX_ENUMERATOR_ARGS)
++#define NAN_INDEX_DELETER(name)                                                \
++    _NAN_INDEX_DELETER_RETURN_TYPE name(                                       \
++        uint32_t index                                                         \
++      , _NAN_INDEX_DELETER_ARGS)
++#define NAN_INDEX_QUERY(name)                                                  \
++    _NAN_INDEX_QUERY_RETURN_TYPE name(uint32_t index, _NAN_INDEX_QUERY_ARGS)
++
++class NanCallback {
++ public:
++  NanCallback() {
++    NanScope();
++    v8::Local<v8::Object> obj = NanNew<v8::Object>();
++    NanAssignPersistent(handle, obj);
++  }
++
++  explicit NanCallback(const v8::Handle<v8::Function> &fn) {
++    NanScope();
++    v8::Local<v8::Object> obj = NanNew<v8::Object>();
++    NanAssignPersistent(handle, obj);
++    SetFunction(fn);
++  }
++
++  ~NanCallback() {
++    if (handle.IsEmpty()) return;
++    NanDisposePersistent(handle);
++  }
++
++  NAN_INLINE void SetFunction(const v8::Handle<v8::Function> &fn) {
++    NanScope();
++    NanNew(handle)->Set(kCallbackIndex, fn);
++  }
++
++  NAN_INLINE v8::Local<v8::Function> GetFunction() const {
++    NanEscapableScope();
++    return NanEscapeScope(NanNew(handle)->Get(kCallbackIndex)
++        .As<v8::Function>());
++  }
++
++  NAN_INLINE bool IsEmpty() const {
++    NanScope();
++    return NanNew(handle)->Get(kCallbackIndex)->IsUndefined();
++  }
++
++  v8::Handle<v8::Value> Call(int argc, v8::Handle<v8::Value> argv[]) const {
++    NanEscapableScope();
++#if (NODE_MODULE_VERSION > 0x000B)  // 0.11.12+
++    v8::Isolate* isolate = v8::Isolate::GetCurrent();
++    v8::Local<v8::Function> callback = NanNew(handle)->
++        Get(kCallbackIndex).As<v8::Function>();
++    return NanEscapeScope(node::MakeCallback(
++        isolate
++      , isolate->GetCurrentContext()->Global()
++      , callback
++      , argc
++      , argv
++    ));
++#else
++#if NODE_VERSION_AT_LEAST(0, 8, 0)
++    v8::Local<v8::Function> callback = handle->
++        Get(kCallbackIndex).As<v8::Function>();
++    return NanEscapeScope(node::MakeCallback(
++        v8::Context::GetCurrent()->Global()
++      , callback
++      , argc
++      , argv
++    ));
++#else
++    v8::Local<v8::Function> callback = handle->
++        Get(kCallbackIndex).As<v8::Function>();
++    return NanEscapeScope(NanMakeCallback(
++        v8::Context::GetCurrent()->Global(), callback, argc, argv));
++#endif
++#endif
++  }
++
++ private:
++  v8::Persistent<v8::Object> handle;
++  static const uint32_t kCallbackIndex = 0;
++};
++
++/* abstract */ class NanAsyncWorker {
++ public:
++  explicit NanAsyncWorker(NanCallback *callback)
++      : callback(callback), errmsg_(NULL) {
++    request.data = this;
++
++    NanScope();
++    v8::Local<v8::Object> obj = NanNew<v8::Object>();
++    NanAssignPersistent(persistentHandle, obj);
++  }
++
++  virtual ~NanAsyncWorker() {
++    NanScope();
++
++    if (!persistentHandle.IsEmpty())
++      NanDisposePersistent(persistentHandle);
++    if (callback)
++      delete callback;
++    if (errmsg_)
++      delete[] errmsg_;
++  }
++
++  virtual void WorkComplete() {
++    NanScope();
++
++    if (errmsg_ == NULL)
++      HandleOKCallback();
++    else
++      HandleErrorCallback();
++    delete callback;
++    callback = NULL;
++  }
++
++  NAN_INLINE void SaveToPersistent(
++      const char *key, const v8::Local<v8::Object> &obj) {
++    v8::Local<v8::Object> handle = NanNew(persistentHandle);
++    handle->Set(NanNew<v8::String>(key), obj);
++  }
++
++  v8::Local<v8::Object> GetFromPersistent(const char *key) const {
++    NanEscapableScope();
++    v8::Local<v8::Object> handle = NanNew(persistentHandle);
++    return NanEscapeScope(handle->Get(NanNew(key)).As<v8::Object>());
++  }
++
++  virtual void Execute() = 0;
++
++  uv_work_t request;
++
++ protected:
++  v8::Persistent<v8::Object> persistentHandle;
++  NanCallback *callback;
++
++  virtual void HandleOKCallback() {
++    NanScope();
++
++    callback->Call(0, NULL);
++  }
++
++  virtual void HandleErrorCallback() {
++    NanScope();
++
++    v8::Local<v8::Value> argv[] = {
++        v8::Exception::Error(NanNew<v8::String>(ErrorMessage()))
++    };
++    callback->Call(1, argv);
++  }
++
++  void SetErrorMessage(const char *msg) {
++    if (errmsg_) {
++      delete[] errmsg_;
++    }
++
++    size_t size = strlen(msg) + 1;
++    errmsg_ = new char[size];
++    memcpy(errmsg_, msg, size);
++  }
++
++  const char* ErrorMessage() const {
++    return errmsg_;
++  }
++
++ private:
++  char *errmsg_;
++};
++
++NAN_INLINE void NanAsyncExecute (uv_work_t* req) {
++  NanAsyncWorker *worker = static_cast<NanAsyncWorker*>(req->data);
++  worker->Execute();
++}
++
++NAN_INLINE void NanAsyncExecuteComplete (uv_work_t* req) {
++  NanAsyncWorker* worker = static_cast<NanAsyncWorker*>(req->data);
++  worker->WorkComplete();
++  delete worker;
++}
++
++NAN_INLINE void NanAsyncQueueWorker (NanAsyncWorker* worker) {
++  uv_queue_work(
++      uv_default_loop()
++    , &worker->request
++    , NanAsyncExecute
++    , (uv_after_work_cb)NanAsyncExecuteComplete
++  );
++}
++
++//// Base 64 ////
++
++#define _nan_base64_encoded_size(size) ((size + 2 - ((size + 2) % 3)) / 3 * 4)
++
++// Doesn't check for padding at the end.  Can be 1-2 bytes over.
++NAN_INLINE size_t _nan_base64_decoded_size_fast(size_t size) {
++  size_t remainder = size % 4;
++
++  size = (size / 4) * 3;
++  if (remainder) {
++    if (size == 0 && remainder == 1) {
++      // special case: 1-byte input cannot be decoded
++      size = 0;
++    } else {
++      // non-padded input, add 1 or 2 extra bytes
++      size += 1 + (remainder == 3);
++    }
++  }
++
++  return size;
++}
++
++template<typename T>
++NAN_INLINE size_t _nan_base64_decoded_size(
++    const T* src
++  , size_t size
++) {
++  if (size == 0)
++    return 0;
++
++  if (src[size - 1] == '=')
++    size--;
++  if (size > 0 && src[size - 1] == '=')
++    size--;
++
++  return _nan_base64_decoded_size_fast(size);
++}
++
++// supports regular and URL-safe base64
++static const int _nan_unbase64_table[] = {
++    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -2, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63
++  , 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1
++  , -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14
++  , 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63
++  , -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40
++  , 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++  , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
++};
++
++#define _nan_unbase64(x) _nan_unbase64_table[(uint8_t)(x)]
++
++template<typename T> static size_t _nan_base64_decode(
++    char* buf
++  , size_t len
++  , const T* src
++  , const size_t srcLen
++) {
++  char* dst = buf;
++  char* dstEnd = buf + len;
++  const T* srcEnd = src + srcLen;
++
++  while (src < srcEnd && dst < dstEnd) {
++    ptrdiff_t remaining = srcEnd - src;
++    char a, b, c, d;
++
++    while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
++    if (remaining == 0 || *src == '=') break;
++    a = _nan_unbase64(*src++);
++
++    while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
++    if (remaining <= 1 || *src == '=') break;
++    b = _nan_unbase64(*src++);
++
++    *dst++ = (a << 2) | ((b & 0x30) >> 4);
++    if (dst == dstEnd) break;
++
++    while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
++    if (remaining <= 2 || *src == '=') break;
++    c = _nan_unbase64(*src++);
++
++    *dst++ = ((b & 0x0F) << 4) | ((c & 0x3C) >> 2);
++    if (dst == dstEnd) break;
++
++    while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--;
++    if (remaining <= 3 || *src == '=') break;
++    d = _nan_unbase64(*src++);
++
++    *dst++ = ((c & 0x03) << 6) | (d & 0x3F);
++  }
++
++  return dst - buf;
++}
++
++//// HEX ////
++
++template<typename T> unsigned _nan_hex2bin(T c) {
++  if (c >= '0' && c <= '9') return c - '0';
++  if (c >= 'A' && c <= 'F') return 10 + (c - 'A');
++  if (c >= 'a' && c <= 'f') return 10 + (c - 'a');
++  return static_cast<unsigned>(-1);
++}
++
++template<typename T> static size_t _nan_hex_decode(
++    char* buf
++  , size_t len
++  , const T* src
++  , const size_t srcLen
++) {
++  size_t i;
++  for (i = 0; i < len && i * 2 + 1 < srcLen; ++i) {
++    unsigned a = _nan_hex2bin(src[i * 2 + 0]);
++    unsigned b = _nan_hex2bin(src[i * 2 + 1]);
++    if (!~a || !~b) return i;
++    buf[i] = a * 16 + b;
++  }
++
++  return i;
++}
++
++static bool _NanGetExternalParts(
++    v8::Handle<v8::Value> val
++  , const char** data
++  , size_t* len
++) {
++  if (node::Buffer::HasInstance(val)) {
++    *data = node::Buffer::Data(val.As<v8::Object>());
++    *len = node::Buffer::Length(val.As<v8::Object>());
++    return true;
++  }
++
++  assert(val->IsString());
++  v8::Local<v8::String> str = NanNew(val.As<v8::String>());
++
++  if (str->IsExternalAscii()) {
++    const v8::String::ExternalAsciiStringResource* ext;
++    ext = str->GetExternalAsciiStringResource();
++    *data = ext->data();
++    *len = ext->length();
++    return true;
++
++  } else if (str->IsExternal()) {
++    const v8::String::ExternalStringResource* ext;
++    ext = str->GetExternalStringResource();
++    *data = reinterpret_cast<const char*>(ext->data());
++    *len = ext->length();
++    return true;
++  }
++
++  return false;
++}
++
++namespace Nan {
++  enum Encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
++}
++
++/* NAN_DEPRECATED */ NAN_INLINE void* _NanRawString(
++    v8::Handle<v8::Value> from
++  , enum Nan::Encoding encoding
++  , size_t *datalen
++  , void *buf
++  , size_t buflen
++  , int flags
++) {
++  NanScope();
++
++  size_t sz_;
++  size_t term_len = !(flags & v8::String::NO_NULL_TERMINATION);
++  char *data = NULL;
++  size_t len;
++  bool is_extern = _NanGetExternalParts(
++      from
++    , const_cast<const char**>(&data)
++    , &len);
++
++  if (is_extern && !term_len) {
++    NanSetPointerSafe(datalen, len);
++    return data;
++  }
++
++  v8::Local<v8::String> toStr = from->ToString();
++
++  char *to = static_cast<char *>(buf);
++
++  switch (encoding) {
++    case Nan::ASCII:
++#if NODE_MODULE_VERSION < 0x000C
++      sz_ = toStr->Length();
++      if (to == NULL) {
++        to = new char[sz_ + term_len];
++      } else {
++        assert(buflen >= sz_ + term_len && "too small buffer");
++      }
++      NanSetPointerSafe<size_t>(
++          datalen
++        , toStr->WriteAscii(to, 0, static_cast<int>(sz_ + term_len), flags));
++      return to;
++#endif
++    case Nan::BINARY:
++    case Nan::BUFFER:
++      sz_ = toStr->Length();
++      if (to == NULL) {
++        to = new char[sz_ + term_len];
++      } else {
++        assert(buflen >= sz_ + term_len && "too small buffer");
++      }
++#if NODE_MODULE_VERSION < 0x000C
++      {
++        uint16_t* twobytebuf = new uint16_t[sz_ + term_len];
++
++        size_t len = toStr->Write(twobytebuf, 0,
++          static_cast<int>(sz_ + term_len), flags);
++
++        for (size_t i = 0; i < sz_ + term_len && i < len + term_len; i++) {
++          unsigned char *b = reinterpret_cast<unsigned char*>(&twobytebuf[i]);
++          to[i] = *b;
++        }
++
++        NanSetPointerSafe<size_t>(datalen, len);
++
++        delete[] twobytebuf;
++        return to;
++      }
++#else
++      NanSetPointerSafe<size_t>(
++        datalen,
++        toStr->WriteOneByte(
++            reinterpret_cast<uint8_t *>(to)
++          , 0
++          , static_cast<int>(sz_ + term_len)
++          , flags));
++      return to;
++#endif
++    case Nan::UTF8:
++      sz_ = toStr->Utf8Length();
++      if (to == NULL) {
++        to = new char[sz_ + term_len];
++      } else {
++        assert(buflen >= sz_ + term_len && "too small buffer");
++      }
++      NanSetPointerSafe<size_t>(
++          datalen
++        , toStr->WriteUtf8(to, static_cast<int>(sz_ + term_len)
++            , NULL, flags)
++          - term_len);
++      return to;
++    case Nan::BASE64:
++      {
++        v8::String::Value value(toStr);
++        sz_ = _nan_base64_decoded_size(*value, value.length());
++        if (to == NULL) {
++          to = new char[sz_ + term_len];
++        } else {
++          assert(buflen >= sz_ + term_len);
++        }
++        NanSetPointerSafe<size_t>(
++            datalen
++          , _nan_base64_decode(to, sz_, *value, value.length()));
++        if (term_len) {
++          to[sz_] = '\0';
++        }
++        return to;
++      }
++    case Nan::UCS2:
++      {
++        sz_ = toStr->Length();
++        if (to == NULL) {
++          to = new char[(sz_ + term_len) * 2];
++        } else {
++          assert(buflen >= (sz_ + term_len) * 2 && "too small buffer");
++        }
++
++        int bc = 2 * toStr->Write(
++            reinterpret_cast<uint16_t *>(to)
++          , 0
++          , static_cast<int>(sz_ + term_len)
++          , flags);
++        NanSetPointerSafe<size_t>(datalen, bc);
++        return to;
++      }
++    case Nan::HEX:
++      {
++        v8::String::Value value(toStr);
++        sz_ = value.length();
++        assert(!(sz_ & 1) && "bad hex data");
++        if (to == NULL) {
++          to = new char[sz_ / 2 + term_len];
++        } else {
++          assert(buflen >= sz_ / 2 + term_len && "too small buffer");
++        }
++        NanSetPointerSafe<size_t>(
++            datalen
++          , _nan_hex_decode(to, sz_ / 2, *value, value.length()));
++      }
++      if (term_len) {
++        to[sz_ / 2] = '\0';
++      }
++      return to;
++    default:
++      assert(0 && "unknown encoding");
++  }
++  return to;
++}
++
++NAN_DEPRECATED NAN_INLINE void* NanRawString(
++    v8::Handle<v8::Value> from
++  , enum Nan::Encoding encoding
++  , size_t *datalen
++  , void *buf
++  , size_t buflen
++  , int flags
++) {
++  return _NanRawString(from, encoding, datalen, buf, buflen, flags);
++}
++
++
++NAN_DEPRECATED NAN_INLINE char* NanCString(
++    v8::Handle<v8::Value> from
++  , size_t *datalen
++  , char *buf = NULL
++  , size_t buflen = 0
++  , int flags = v8::String::NO_OPTIONS
++) {
++    return static_cast<char *>(
++      _NanRawString(from, Nan::UTF8, datalen, buf, buflen, flags)
++    );
++}
++
++NAN_INLINE void NanSetPrototypeTemplate(
++    v8::Local<v8::FunctionTemplate> templ
++  , const char *name
++  , v8::Handle<v8::Data> value
++) {
++  NanSetTemplate(templ->PrototypeTemplate(), name, value);
++}
++
++NAN_INLINE void NanSetPrototypeTemplate(
++    v8::Local<v8::FunctionTemplate> templ
++  , v8::Handle<v8::String> name
++  , v8::Handle<v8::Data> value
++  , v8::PropertyAttribute attributes
++) {
++  NanSetTemplate(templ->PrototypeTemplate(), name, value, attributes);
++}
++
++NAN_INLINE void NanSetInstanceTemplate(
++    v8::Local<v8::FunctionTemplate> templ
++  , const char *name
++  , v8::Handle<v8::Data> value
++) {
++  NanSetTemplate(templ->InstanceTemplate(), name, value);
++}
++
++NAN_INLINE void NanSetInstanceTemplate(
++    v8::Local<v8::FunctionTemplate> templ
++  , v8::Handle<v8::String> name
++  , v8::Handle<v8::Data> value
++  , v8::PropertyAttribute attributes
++) {
++  NanSetTemplate(templ->InstanceTemplate(), name, value, attributes);
++}
++
++#endif  // NAN_H_
diff --git a/lang/node-serialport/Makefile b/lang/node-serialport/Makefile
new file mode 100644 (file)
index 0000000..ad4b7af
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2014 Arduino LLC
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NPM_NAME:=serialport
+PKG_NAME:=node-$(PKG_NPM_NAME)
+PKG_VERSION:=1.4.6
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NPM_NAME)-$(PKG_VERSION).tgz
+PKG_SOURCE_URL:=http://registry.npmjs.org/$(PKG_NPM_NAME)/-/
+PKG_MD5SUM:=1eb21082e0aa676b8350182a60230808
+
+PKG_BUILD_DEPENDS:=node
+PKG_NODE_VERSION:=0.12.7
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=Custom
+PKG_LICENSE_FILE:=LICENSE
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/node-serialport
+  DEPENDS:=+node
+  SUBMENU:=Node.js
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=Node.js package to access serial ports for reading and writing
+  URL:=https://www.npmjs.org/package/serialport
+endef
+
+define Package/node-serialport/description
+ Node.js package to access serial ports for reading and writing OR Welcome your robotic JavaScript overlords. Better yet, program them!
+endef
+
+define Build/Prepare
+       /bin/tar xzf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR) --strip-components 1
+       $(Build/Patch)
+endef
+
+EXTRA_LDFLAGS="-L$(TOOLCHAIN_DIR)/lib/ -Wl,-rpath-link $(TOOLCHAIN_DIR)/lib/" \
+
+define Build/Compile
+       $(MAKE_FLAGS) \
+       npm_config_arch=$(CONFIG_ARCH) \
+       npm_config_nodedir=$(BUILD_DIR)/node-v$(PKG_NODE_VERSION)/ \
+       PREFIX="$(PKG_INSTALL_DIR)/usr/" \
+       $(STAGING_DIR_HOST)/bin/npm install -g $(PKG_BUILD_DIR)
+endef
+
+define Package/node-serialport/install
+       mkdir -p $(1)/usr/lib/node/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/* $(1)/usr/lib/node/
+endef
+
+$(eval $(call BuildPackage,node-serialport))
+
diff --git a/lang/node-serialport/patches/package.json.patch b/lang/node-serialport/patches/package.json.patch
new file mode 100644 (file)
index 0000000..a20c6a5
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/package.json     2014-05-02 12:02:02.940515727 +0200
++++ b/package.json     2014-05-02 12:03:08.488512762 +0200
+@@ -69,7 +71,7 @@
+     "serialportterm": "./bin/serialportTerminal.js"
+   },
+   "scripts": {
+-    "install": "node-pre-gyp install --fallback-to-build",
++    "install": "node-pre-gyp reinstall --build-from-source --target_arch=${npm_config_arch}",
+     "test": "grunt --verbose"
+   }
+ }
diff --git a/lang/node/Makefile b/lang/node/Makefile
new file mode 100644 (file)
index 0000000..74eb44e
--- /dev/null
@@ -0,0 +1,72 @@
+#
+# Copyright (C) 2006-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=node
+PKG_VERSION:=v0.12.7
+PKG_RELEASE:=1
+
+PKG_SOURCE:=node-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://nodejs.org/dist/${PKG_VERSION}
+
+PKG_BUILD_DEPENDS:=python/host
+PKG_INSTALL:=1
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/node
+  SECTION:=lang
+  CATEGORY:=Languages
+  SUBMENU:=Node.js
+  TITLE:=Node.js is a platform built on Chrome's JavaScript runtime
+  URL:=http://nodejs.org/
+  DEPENDS:=+libpthread +librt +libstdcpp +libopenssl +libuv
+endef
+
+define Package/node/description
+  Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses
+  an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js'
+   package ecosystem, npm, is the largest ecosystem of open source libraries in the world.
+endef
+
+CONFIGURE_ARGS= \
+       --dest-cpu=$(CONFIG_ARCH) \
+       --dest-os=linux \
+       --without-snapshot \
+       --shared-zlib \
+       --shared-openssl \
+       --prefix=/usr
+
+HOST_CONFIGURE_VARS:=
+HOST_CONFIGURE_ARGS:= \
+       --dest-os=linux \
+       --without-snapshot \
+       --prefix=$(STAGING_DIR_HOST)/
+
+HOST_CONFIGURE_CMD:=python ./configure
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+endef
+
+define Package/node/install
+       mkdir -p $(1)/usr/bin $(1)/usr/lib/node_modules/npm/{bin,lib,node_modules}
+       $(CP) $(PKG_INSTALL_DIR)/usr/bin/{node,npm} $(1)/usr/bin/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/npm/{package.json,LICENSE,cli.js} $(1)/usr/lib/node_modules/npm
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/npm/bin/npm-cli.js $(1)/usr/lib/node_modules/npm/bin
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/npm/lib/* $(1)/usr/lib/node_modules/npm/lib/
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/npm/node_modules/* $(1)/usr/lib/node_modules/npm/node_modules/
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,node))
diff --git a/lang/node/patches/001-mips-no-fpu.patch b/lang/node/patches/001-mips-no-fpu.patch
new file mode 100644 (file)
index 0000000..5bf8142
--- /dev/null
@@ -0,0 +1,15 @@
+--- a/deps/v8/build/toolchain.gypi
++++ b/deps/v8/build/toolchain.gypi
+@@ -50,10 +50,10 @@
+     'arm_test_noprobe%': 'off',
+     # Similar to vfp but on MIPS.
+-    'v8_can_use_fpu_instructions%': 'true',
++    'v8_can_use_fpu_instructions%': 'false',
+     # Similar to the ARM hard float ABI but on MIPS.
+-    'v8_use_mips_abi_hardfloat%': 'true',
++    'v8_use_mips_abi_hardfloat%': 'false',
+     # Default arch variant for MIPS.
+     'mips_arch_variant%': 'r2',
diff --git a/lang/node/patches/002-addr_info.patch b/lang/node/patches/002-addr_info.patch
new file mode 100644 (file)
index 0000000..78225db
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/deps/uv/src/unix/getaddrinfo.c
++++ b/deps/uv/src/unix/getaddrinfo.c
+@@ -99,6 +99,7 @@
+   int err;
+   req = container_of(w, uv_getaddrinfo_t, work_req);
++   req->hints->ai_flags &= ~AI_V4MAPPED;
+   err = getaddrinfo(req->hostname, req->service, req->hints, &req->addrinfo);
+   req->retcode = uv__getaddrinfo_translate_error(err);
+ }
diff --git a/lang/node/patches/003-path.patch b/lang/node/patches/003-path.patch
new file mode 100644 (file)
index 0000000..723fe9d
--- /dev/null
@@ -0,0 +1,12 @@
+--- a/lib/module.js
++++ b/lib/module.js
+@@ -512,7 +512,8 @@
+     var homeDir = process.env.HOME;
+   }
+-  var paths = [path.resolve(process.execPath, '..', '..', 'lib', 'node')];
++  var paths = [path.resolve(process.execPath, '..', '..', 'lib', 'node'),
++    path.resolve(process.execPath, '..', '..', 'lib', 'node_modules')];
+   if (homeDir) {
+     paths.unshift(path.resolve(homeDir, '.node_libraries'));
index 6c302b9ef85cdd9e339f513e14fb0d52679a5a21..cd6989a49f32d5cb3aa9ce63d9b92d55670015ab 100644 (file)
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=php
-PKG_VERSION:=5.6.13
+PKG_VERSION:=5.6.14
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>, Michael Heimpold <mhei@heimpold.de>
@@ -18,7 +18,7 @@ PKG_LICENSE_FILES:=LICENSE
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://www.php.net/distributions/
-PKG_MD5SUM:=64d9a82068e3b0bbb16c261261391172
+PKG_MD5SUM:=2e1332123a7e19d15ed2af2d1d6bd6fd
 
 PKG_FIXUP:=libtool autoreconf
 PKG_BUILD_PARALLEL:=1
index b6cd2de410d11eeb3ec94adcabfe9cfcc21d6478..8dbf7217c0c5ed333ad901b9c83b0a62a5d23e78 100644 (file)
@@ -8,13 +8,13 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=gnutls
-PKG_VERSION:=3.4.5
+PKG_VERSION:=3.4.6
 PKG_RELEASE:=1
 PKG_USE_MIPS16:=0
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=ftp://ftp.gnutls.org/gcrypt/gnutls/v3.4
-PKG_MD5SUM:=f5dae0e0ecda28aab12386e6c0705d4c
+PKG_MD5SUM:=4f2c4b4483da65de7edfeb050911fafb
 #PKG_FIXUP:=autoreconf gettext-version
 PKG_MAINTAINER:=Nikos Mavrogiannopoulos <nmav@gnutls.org>
 PKG_LICENSE:=LGPLv2.1+
index 557b31e205f07675fb57e37a5a4dddac2dc99ab5..522eb0649ce5dd156e2137d08e9b97fb1fea0c48 100644 (file)
@@ -10,7 +10,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libdmapsharing
-PKG_VERSION:=2.9.30
+PKG_VERSION:=2.9.32
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
@@ -20,7 +20,7 @@ PKG_LICENSE_FILES:=COPYING
 
 PKG_SOURCE:=libdmapsharing-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://www.flyn.org/projects/libdmapsharing/
-PKG_MD5SUM:=25de55d128d432d82f2a1ec010d7069a
+PKG_MD5SUM:=b0bb27525c92233bd76e5f7b7b6cfe6d
 
 PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
diff --git a/libs/libmraa/Makefile b/libs/libmraa/Makefile
new file mode 100644 (file)
index 0000000..3e3202a
--- /dev/null
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libmraa
+PKG_VERSION:=0.8.0
+
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/intel-iot-devkit/mraa.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=70600dece4138b0c0dbaff42f57828f1559cd840
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_BUILD_DEPENDS:=node python/host swig/host node/host
+CMAKE_INSTALL:=1
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=LGPL-2.1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_OPTIONS=-DBUILDARCH=$(CONFIG_ARCH) \
+       -DENABLEEXAMPLES=0 \
+       -DNODE_EXECUTABLE=$(STAGING_DIR_HOST)/bin/node \
+       -DSWIG_DIR=$(STAGING_DIR_HOST)/bin
+
+TARGET_CFLAGS+=-I$(STAGING_DIR)/usr/include/node
+
+define Package/libmraa
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+python +libstdcpp
+  TITLE:=Intel IoT lowlevel IO library
+endef
+
+define Package/libmraa/install
+       $(INSTALL_DIR) $(1)/usr/lib/{node/mraa,python2.7/site-packages} $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/libmraa.so* $(1)/usr/lib/
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/node_modules/mraa/* $(1)/usr/lib/node/mraa/
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/python2.7/site-packages/* $(1)/usr/lib/python2.7/site-packages/
+#      $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/share/mraa/examples/python/blink-io8.py $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libmraa))
diff --git a/libs/libmraa/patches/0001-base.patch b/libs/libmraa/patches/0001-base.patch
new file mode 100644 (file)
index 0000000..5094389
--- /dev/null
@@ -0,0 +1,118 @@
+From 6fecad819376442d057bdd35a0909cfac9df02f5 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 23 Jul 2015 12:18:39 +0200
+Subject: [PATCH 1/4] base
+
+---
+ CMakeLists.txt          |   10 ++++------
+ api/mraa/types.h        |    1 +
+ include/mraa_internal.h |    7 +++++++
+ src/CMakeLists.txt      |    5 +++++
+ src/i2c/i2c.c           |    2 +-
+ src/mraa.c              |    3 +++
+ src/uart/uart.c         |    1 +
+ 7 files changed, 22 insertions(+), 7 deletions(-)
+
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -14,12 +14,7 @@
+ set (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH})
+ # Make a version file containing the current version from git.
+-include (GetGitRevisionDescription)
+-git_describe (VERSION "--tags")
+-if ("x_${VERSION}" STREQUAL "x_GIT-NOTFOUND" OR "x_${VERSION}" STREQUAL "x_HEAD-HASH-NOTFOUND")
+-  message (WARNING " - Install git to compile a production libmraa!")
+-  set (VERSION "v0.8.0-dirty")
+-endif ()
++set (VERSION "v0.8.0")
+ message (INFO " - libmraa Version ${VERSION}")
+@@ -84,8 +79,10 @@
+   set (X86PLAT ON)
+ elseif (DETECTED_ARCH MATCHES "arm.*")
+   set (ARMPLAT ON)
++elseif (DETECTED_ARCH MATCHES "mips")
++  set (MIPSPLAT ON)
+ else ()
+-  message(FATAL_ERROR "Only x86 and arm platforms currently supported")
++  message(FATAL_ERROR "Only x86, arm and mips platforms currently supported")
+ endif()
+ if (BUILDSWIGPYTHON)
+--- a/api/mraa/types.h
++++ b/api/mraa/types.h
+@@ -46,6 +46,7 @@
+     MRAA_BEAGLEBONE = 6,            /**< The different BeagleBone Black Modes B/C */
+     MRAA_BANANA = 7,                /**< Allwinner A20 based Banana Pi and Banana Pro */
+     MRAA_INTEL_NUC5 = 8,            /**< The Intel 5th generations Broadwell NUCs */
++    MRAA_MTK_LINKIT = 9,            /**< Mediatek MT7688 based Linkit (Air) */
+     // USB platform extenders start at 256
+     MRAA_FTDI_FT4222 = 256,         /**< FTDI FT4222 USB to i2c bridge */
+--- a/include/mraa_internal.h
++++ b/include/mraa_internal.h
+@@ -66,6 +66,13 @@
+ mraa_platform_t mraa_usb_platform_extender(mraa_board_t* board);
+ /**
++ * runtime detect running arm platforms
++ *
++ * @return mraa_platform_t of the init'ed platform
++ */
++mraa_platform_t mraa_mips_platform();
++
++/**
+  * helper function to check if file exists
+  *
+  * @param filename to check
+--- a/src/CMakeLists.txt
++++ b/src/CMakeLists.txt
+@@ -71,6 +71,11 @@
+   add_subdirectory(usb)
+ endif ()
++if (MIPSPLAT)
++  add_subdirectory(mips)
++  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMIPSPLAT=1")
++endif()
++
+ set (mraa_LIB_SRCS
+   ${mraa_LIB_PLAT_SRCS_NOAUTO}
+ # autogenerated version file
+--- a/src/i2c/i2c.c
++++ b/src/i2c/i2c.c
+@@ -31,9 +31,9 @@
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <fcntl.h>
++#include <errno.h>
+ #include <inttypes.h>
+ #include <sys/types.h>
+-#include <sys/errno.h>
+ #include <sys/ioctl.h>
+ #include "linux/i2c-dev.h"
+--- a/src/mraa.c
++++ b/src/mraa.c
+@@ -111,6 +111,9 @@
+ #elif defined(ARMPLAT)
+     // Use runtime ARM platform detection
+     platform_type = mraa_arm_platform();
++#elif MIPSPLAT
++    // Use runtime ARM platform detection
++    platform_type = mraa_mips_platform();
+ #else
+ #error mraa_ARCH NOTHING
+ #endif
+--- a/src/uart/uart.c
++++ b/src/uart/uart.c
+@@ -26,6 +26,7 @@
+ #include <stdlib.h>
+ #include <sys/stat.h>
++#include <sys/time.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <termios.h>
diff --git a/libs/libmraa/patches/0002-add-mips-support.patch b/libs/libmraa/patches/0002-add-mips-support.patch
new file mode 100644 (file)
index 0000000..66219b9
--- /dev/null
@@ -0,0 +1,483 @@
+From 2c67c6f51ce5bab18c79f4304ccf42716f59f13c Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 23 Jul 2015 13:21:25 +0200
+Subject: [PATCH 2/4] add mips support
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ include/mips/mediatek.h |   39 ++++++
+ src/mips/CMakeLists.txt |    6 +
+ src/mips/mediatek.c     |  349 +++++++++++++++++++++++++++++++++++++++++++++++
+ src/mips/mips.c         |   60 ++++++++
+ 4 files changed, 454 insertions(+)
+ create mode 100644 include/mips/mediatek.h
+ create mode 100644 src/mips/CMakeLists.txt
+ create mode 100644 src/mips/mediatek.c
+ create mode 100644 src/mips/mips.c
+
+--- /dev/null
++++ b/include/mips/mediatek.h
+@@ -0,0 +1,39 @@
++/*
++ * Author: Thomas Ingleby <thomas.c.ingleby@intel.com>
++ * Author: Michael Ring <mail@michael-ring.org>
++ * Copyright (c) 2014 Intel Corporation.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be
++ * included in all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++#pragma once
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#include "mraa_internal.h"
++
++mraa_board_t *
++        mraa_mtk_linkit();
++
++#ifdef __cplusplus
++}
++#endif
+--- /dev/null
++++ b/src/mips/CMakeLists.txt
+@@ -0,0 +1,6 @@
++message (INFO " - Adding MIPS platforms")
++set (mraa_LIB_PLAT_SRCS_NOAUTO ${mraa_LIB_SRCS_NOAUTO}
++  ${PROJECT_SOURCE_DIR}/src/mips/mips.c
++  ${PROJECT_SOURCE_DIR}/src/mips/mediatek.c
++  PARENT_SCOPE
++)
+--- /dev/null
++++ b/src/mips/mediatek.c
+@@ -0,0 +1,349 @@
++/*
++ * Author: Thomas Ingleby <thomas.c.ingleby@intel.com>
++ * Author: Michael Ring <mail@michael-ring.org>
++ * Copyright (c) 2014 Intel Corporation.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be
++ * included in all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++#include <stdio.h>
++#include <stdint.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/mman.h>
++#include <mraa/common.h>
++
++#include "mraa_internal.h"
++
++#include "common.h"
++
++#define PLATFORM_MEDIATEK_LINKIT      1
++#define PLATFORM_MEDIATEK_LINKIT_AIR  2
++#define MMAP_PATH                     "/dev/mem"
++#define MT7628_GPIO_BASE              0x100
++#define MT7628_BLOCK_SIZE             (4 * 1024)
++#define MT7628_GPIO_CTRL              0x00
++#define MT7628_GPIO_DATA              0x20
++#define MT7628_GPIO_SET                       0x30
++#define MT7628_GPIO_CLEAR             0x40
++
++#define MAX_SIZE 64
++
++// MMAP
++static uint8_t* mmap_reg = NULL;
++static int mmap_fd = 0;
++static int mmap_size;
++static unsigned int mmap_count = 0;
++static int platform_detected = 0;
++
++mraa_result_t
++mraa_mtk_linkit_mmap_write(mraa_gpio_context dev, int value)
++{
++    volatile uint32_t* addr;
++    if (value) {
++        *(volatile uint32_t*) (mmap_reg + MT7628_GPIO_SET + (dev->pin / 32) * 4) =
++        (uint32_t)(1 << (dev->pin % 32));
++    } else {
++        *(volatile uint32_t*) (mmap_reg + MT7628_GPIO_CLEAR + (dev->pin / 32) * 4) =
++        (uint32_t)(1 << (dev->pin % 32));
++    }
++    return MRAA_SUCCESS;
++}
++
++static mraa_result_t
++mraa_mtk_linkit_mmap_unsetup()
++{
++    if (mmap_reg == NULL) {
++        syslog(LOG_ERR, "linkit mmap: null register cant unsetup");
++        return MRAA_ERROR_INVALID_RESOURCE;
++    }
++    munmap(mmap_reg, mmap_size);
++    mmap_reg = NULL;
++    if (close(mmap_fd) != 0) {
++        return MRAA_ERROR_INVALID_RESOURCE;
++    }
++    return MRAA_SUCCESS;
++}
++
++int
++mraa_mtk_linkit_mmap_read(mraa_gpio_context dev)
++{
++    uint32_t value = *(volatile uint32_t*) (mmap_reg + MT7628_GPIO_DATA + (dev->pin / 32) * 4);
++    if (value & (uint32_t)(1 << (dev->pin % 32))) {
++        return 1;
++    }
++    return 0;
++}
++
++mraa_result_t
++mraa_mtk_linkit_mmap_setup(mraa_gpio_context dev, mraa_boolean_t en)
++{
++    if (dev == NULL) {
++        syslog(LOG_ERR, "linkit mmap: context not valid");
++        return MRAA_ERROR_INVALID_HANDLE;
++    }
++
++    if (en == 0) {
++        if (dev->mmap_write == NULL && dev->mmap_read == NULL) {
++            syslog(LOG_ERR, "linkit mmap: can't disable disabled mmap gpio");
++            return MRAA_ERROR_INVALID_PARAMETER;
++        }
++        dev->mmap_write = NULL;
++        dev->mmap_read = NULL;
++        mmap_count--;
++        if (mmap_count == 0) {
++            return mraa_mtk_linkit_mmap_unsetup();
++        }
++        return MRAA_SUCCESS;
++    }
++
++    if (dev->mmap_write != NULL && dev->mmap_read != NULL) {
++        syslog(LOG_ERR, "linkit mmap: can't enable enabled mmap gpio");
++        return MRAA_ERROR_INVALID_PARAMETER;
++    }
++
++    // Might need to make some elements of this thread safe.
++    // For example only allow one thread to enter the following block
++    // to prevent mmap'ing twice.
++    if (mmap_reg == NULL) {
++        if ((mmap_fd = open(MMAP_PATH, O_RDWR)) < 0) {
++            syslog(LOG_ERR, "linkit map: unable to open resource0 file");
++            return MRAA_ERROR_INVALID_HANDLE;
++        }
++
++        mmap_reg = (uint8_t*) mmap(NULL, MT7628_BLOCK_SIZE, PROT_READ | PROT_WRITE,
++                                       MAP_FILE | MAP_SHARED, mmap_fd, MT7628_GPIO_BASE);
++        if (mmap_reg == MAP_FAILED) {
++            syslog(LOG_ERR, "linkit mmap: failed to mmap");
++            mmap_reg = NULL;
++            close(mmap_fd);
++            return MRAA_ERROR_NO_RESOURCES;
++        }
++    }
++    dev->mmap_write = &mraa_mtk_linkit_mmap_write;
++    dev->mmap_read = &mraa_mtk_linkit_mmap_read;
++    mmap_count++;
++
++    return MRAA_SUCCESS;
++}
++
++mraa_board_t*
++mraa_mtk_linkit()
++{
++    mraa_board_t* b = (mraa_board_t*) malloc(sizeof(mraa_board_t));
++    if (b == NULL) {
++        return NULL;
++    }
++
++    b->platform_name = "LINKIT";
++    platform_detected = PLATFORM_MEDIATEK_LINKIT;
++    b->phy_pin_count = 31;
++
++    b->aio_count = 0;
++    b->adc_raw = 0;
++    b->adc_supported = 0;
++    b->pwm_default_period = 500;
++    b->pwm_max_period = 2147483;
++    b->pwm_min_period = 1;
++
++    b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * b->phy_pin_count);
++
++    advance_func->gpio_mmap_setup = &mraa_mtk_linkit_mmap_setup;
++
++    strncpy(b->pins[0].name, "P0", MRAA_PIN_NAME_SIZE);
++    b->pins[0].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
++
++    strncpy(b->pins[1].name, "P1", MRAA_PIN_NAME_SIZE);
++    b->pins[1].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
++
++    strncpy(b->pins[2].name, "P2", MRAA_PIN_NAME_SIZE);
++    b->pins[2].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
++
++    strncpy(b->pins[3].name, "P3", MRAA_PIN_NAME_SIZE);
++    b->pins[3].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
++
++    strncpy(b->pins[4].name, "P4", MRAA_PIN_NAME_SIZE);
++    b->pins[4].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
++
++    strncpy(b->pins[5].name, "P5", MRAA_PIN_NAME_SIZE);
++    b->pins[5].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
++
++    strncpy(b->pins[6].name, "P6", MRAA_PIN_NAME_SIZE);
++    b->pins[6].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
++
++    strncpy(b->pins[7].name, "P7", MRAA_PIN_NAME_SIZE);
++    b->pins[7].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
++
++    strncpy(b->pins[8].name, "P8", MRAA_PIN_NAME_SIZE);
++    b->pins[8].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
++    b->pins[8].gpio.pinmap = 21;
++    b->pins[8].uart.parent_id = 2;
++    b->pins[8].uart.mux_total = 0;
++
++    strncpy(b->pins[9].name, "P9", MRAA_PIN_NAME_SIZE);
++    b->pins[9].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
++    b->pins[9].gpio.pinmap = 20;
++    b->pins[9].uart.parent_id = 2;
++    b->pins[9].uart.mux_total = 0;
++
++    strncpy(b->pins[10].name, "P10", MRAA_PIN_NAME_SIZE);
++    b->pins[10].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[10].gpio.pinmap = 2;
++
++    strncpy(b->pins[11].name, "P11", MRAA_PIN_NAME_SIZE);
++    b->pins[11].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[11].gpio.pinmap = 3;
++
++    strncpy(b->pins[12].name, "P12", MRAA_PIN_NAME_SIZE);
++    b->pins[12].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[12].gpio.pinmap = 0;
++
++    strncpy(b->pins[13].name, "P13", MRAA_PIN_NAME_SIZE);
++    b->pins[13].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[13].gpio.pinmap = 1;
++
++    strncpy(b->pins[14].name, "P14", MRAA_PIN_NAME_SIZE);
++    b->pins[14].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
++
++    strncpy(b->pins[15].name, "P15", MRAA_PIN_NAME_SIZE);
++    b->pins[15].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[15].gpio.pinmap = 44;
++
++    strncpy(b->pins[16].name, "P16", MRAA_PIN_NAME_SIZE);
++    b->pins[16].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
++    b->pins[16].gpio.pinmap = 46;
++    b->pins[16].uart.parent_id = 1;
++    b->pins[16].uart.mux_total = 0;
++
++    strncpy(b->pins[17].name, "P17", MRAA_PIN_NAME_SIZE);
++    b->pins[17].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
++    b->pins[17].gpio.pinmap = 45;
++    b->pins[17].uart.parent_id = 1;
++    b->pins[17].uart.mux_total = 0;
++
++    strncpy(b->pins[18].name, "P18", MRAA_PIN_NAME_SIZE);
++    b->pins[18].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
++    b->pins[18].gpio.pinmap = 13;
++    b->pins[18].uart.parent_id = 1;
++    b->pins[18].uart.mux_total = 0;
++
++    strncpy(b->pins[19].name, "P19", MRAA_PIN_NAME_SIZE);
++    b->pins[19].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
++    b->pins[19].gpio.pinmap = 12;
++    b->pins[19].uart.parent_id = 0;
++    b->pins[19].uart.mux_total = 0;
++
++    strncpy(b->pins[20].name, "P20", MRAA_PIN_NAME_SIZE);
++    b->pins[20].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 };
++    b->pins[20].gpio.pinmap = 5;
++    b->pins[20].i2c.pinmap = 0;
++    b->pins[20].i2c.mux_total = 0;
++
++    strncpy(b->pins[21].name, "P21", MRAA_PIN_NAME_SIZE);
++    b->pins[21].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 };
++    b->pins[21].gpio.pinmap = 4;
++    b->pins[21].i2c.pinmap = 0;
++    b->pins[21].i2c.mux_total = 0;
++
++    strncpy(b->pins[22].name, "P22", MRAA_PIN_NAME_SIZE);
++    b->pins[22].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
++    b->pins[22].gpio.pinmap = 8;
++    b->pins[22].spi.pinmap = 0;
++    b->pins[22].spi.mux_total = 0;
++
++    strncpy(b->pins[23].name, "P23", MRAA_PIN_NAME_SIZE);
++    b->pins[23].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
++    b->pins[23].gpio.pinmap = 9;
++    b->pins[23].spi.pinmap = 0;
++    b->pins[23].spi.mux_total = 0;
++
++    strncpy(b->pins[24].name, "P24", MRAA_PIN_NAME_SIZE);
++    b->pins[24].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
++    b->pins[24].gpio.pinmap = 7;
++    b->pins[24].spi.pinmap = 0;
++    b->pins[24].spi.mux_total = 0;
++
++    strncpy(b->pins[25].name, "P25", MRAA_PIN_NAME_SIZE);
++    b->pins[25].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
++    b->pins[25].gpio.pinmap = 6;
++    b->pins[25].spi.pinmap = 0;
++    b->pins[25].spi.mux_total = 0;
++
++    strncpy(b->pins[26].name, "P26", MRAA_PIN_NAME_SIZE);
++    b->pins[26].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 };
++    b->pins[26].gpio.pinmap = 18;
++
++    strncpy(b->pins[27].name, "P27", MRAA_PIN_NAME_SIZE);
++    b->pins[27].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 };
++    b->pins[27].gpio.pinmap = 19;
++
++    strncpy(b->pins[28].name, "P28", MRAA_PIN_NAME_SIZE);
++    b->pins[28].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[28].gpio.pinmap = 16;
++
++    strncpy(b->pins[29].name, "P29", MRAA_PIN_NAME_SIZE);
++    b->pins[29].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[29].gpio.pinmap = 17;
++
++    strncpy(b->pins[30].name, "P30", MRAA_PIN_NAME_SIZE);
++    b->pins[30].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[30].gpio.pinmap = 14;
++
++    strncpy(b->pins[31].name, "P31", MRAA_PIN_NAME_SIZE);
++    b->pins[31].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[31].gpio.pinmap = 15;
++
++    // BUS DEFINITIONS
++    b->i2c_bus_count = 1;
++    b->def_i2c_bus = 0;
++        b->i2c_bus[0].bus_id = 0;
++    b->i2c_bus[0].sda = 20;
++    b->i2c_bus[0].scl = 21;
++
++    b->spi_bus_count = 1;
++    b->def_spi_bus = 0;
++    b->spi_bus[0].bus_id = 0;
++    b->spi_bus[0].slave_s = 0;
++    b->spi_bus[0].cs = 25;
++    b->spi_bus[0].mosi = 22;
++    b->spi_bus[0].miso = 23;
++    b->spi_bus[0].sclk = 21;
++
++    b->uart_dev_count = 3;
++    b->def_uart_dev = 0;
++    b->uart_dev[0].rx = 18;
++    b->uart_dev[0].tx = 19;
++
++    b->uart_dev[1].rx = 16;
++    b->uart_dev[1].tx = 17;
++
++    b->uart_dev[2].rx = 9;
++    b->uart_dev[2].tx = 8;
++
++    b->gpio_count = 0;
++    int i;
++    for (i = 0; i < b->phy_pin_count; i++) {
++        if (b->pins[i].capabilites.gpio) {
++            b->gpio_count++;
++        }
++    }
++
++    return b;
++}
+--- /dev/null
++++ b/src/mips/mips.c
+@@ -0,0 +1,60 @@
++/*
++ * Author: Thomas Ingleby <thomas.c.ingleby@intel.com>
++ * Author: Michael Ring <mail@michael-ring.org>
++ * Copyright (c) 2014 Intel Corporation.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be
++ * included in all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++#include <stdlib.h>
++#include <string.h>
++
++#include "mraa_internal.h"
++#include "mips/mediatek.h"
++
++mraa_platform_t
++mraa_mips_platform()
++{
++    mraa_platform_t platform_type = MRAA_UNKNOWN_PLATFORM;
++    size_t len = 100;
++    char* line = malloc(len);
++    FILE* fh = fopen("/proc/cpuinfo", "r");
++    if (fh != NULL) {
++        while (getline(&line, &len, fh) != -1) {
++            if (strncmp(line, "machine", 7) == 0) {
++                if (strstr(line, "MediaTek LinkIt Smart7688")) {
++                    platform_type = MRAA_MTK_LINKIT;
++                }
++            }
++        }
++        fclose(fh);
++    }
++    free(line);
++
++    switch (platform_type) {
++        case MRAA_MTK_LINKIT:
++            plat = mraa_mtk_linkit();
++            break;
++        default:
++            plat = NULL;
++            syslog(LOG_ERR, "Unknown Platform, currently not supported by MRAA");
++    }
++    return platform_type;
++}
diff --git a/libs/libmraa/patches/0003-uart.patch b/libs/libmraa/patches/0003-uart.patch
new file mode 100644 (file)
index 0000000..647abc5
--- /dev/null
@@ -0,0 +1,26 @@
+From 9540f9b93704e8e80ab2048954ca88d8e6eddf86 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 23 Jul 2015 16:43:42 +0200
+Subject: [PATCH 3/4] uart
+
+---
+ src/uart/uart.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/uart/uart.c b/src/uart/uart.c
+index 3ef55a4..5102f81 100644
+--- a/src/uart/uart.c
++++ b/src/uart/uart.c
+@@ -34,6 +34,9 @@
+ #include "uart.h"
+ #include "mraa_internal.h"
++#ifndef CMSPAR
++#define CMSPAR          010000000000
++#endif
+ // This function takes an unsigned int and converts it to a B* speed_t
+ // that can be used with linux/posix termios
+ static speed_t
+-- 
+1.7.10.4
+
diff --git a/libs/libmraa/patches/0004-fixes.patch b/libs/libmraa/patches/0004-fixes.patch
new file mode 100644 (file)
index 0000000..40e5930
--- /dev/null
@@ -0,0 +1,666 @@
+From 3c34e5f87a741ec2fc7809fc8c169a832275d32c Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 23 Jul 2015 18:19:32 +0200
+Subject: [PATCH 4/4] fixes
+
+---
+ src/mips/mediatek.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/src/mips/mediatek.c
++++ b/src/mips/mediatek.c
+@@ -37,12 +37,12 @@
+ #define PLATFORM_MEDIATEK_LINKIT      1
+ #define PLATFORM_MEDIATEK_LINKIT_AIR  2
+ #define MMAP_PATH                     "/dev/mem"
+-#define MT7628_GPIO_BASE              0x100
+-#define MT7628_BLOCK_SIZE             (4 * 1024)
+-#define MT7628_GPIO_CTRL              0x00
+-#define MT7628_GPIO_DATA              0x20
+-#define MT7628_GPIO_SET                       0x30
+-#define MT7628_GPIO_CLEAR             0x40
++#define MT7628_GPIOMODE_BASE          0x10000000
++#define MT7628_BLOCK_SIZE             0x1000
++#define MT7628_GPIO_CTRL              0x600
++#define MT7628_GPIO_DATA              0x620
++#define MT7628_GPIO_SET                       0x630
++#define MT7628_GPIO_CLEAR             0x640
+ #define MAX_SIZE 64
+@@ -50,6 +50,9 @@
+ static uint8_t* mmap_reg = NULL;
+ static int mmap_fd = 0;
+ static int mmap_size;
++static uint8_t* gpio_mmap_reg = NULL;
++static int gpio_mmap_fd = 0;
++static int gpio_mmap_size;
+ static unsigned int mmap_count = 0;
+ static int platform_detected = 0;
+@@ -129,9 +132,10 @@
+         }
+         mmap_reg = (uint8_t*) mmap(NULL, MT7628_BLOCK_SIZE, PROT_READ | PROT_WRITE,
+-                                       MAP_FILE | MAP_SHARED, mmap_fd, MT7628_GPIO_BASE);
++                                       MAP_FILE | MAP_SHARED, mmap_fd, 0x10000000);
+         if (mmap_reg == MAP_FAILED) {
+-            syslog(LOG_ERR, "linkit mmap: failed to mmap");
++            perror("foo");
++          syslog(LOG_ERR, "linkit mmap: failed to mmap");
+             mmap_reg = NULL;
+             close(mmap_fd);
+             return MRAA_ERROR_NO_RESOURCES;
+@@ -144,201 +148,442 @@
+     return MRAA_SUCCESS;
+ }
++static int mmap_gpiomode(void)
++{
++    if ((gpio_mmap_fd = open(MMAP_PATH, O_RDWR)) < 0) {
++        syslog(LOG_ERR, "linkit map: unable to open resource0 file");
++        return MRAA_ERROR_INVALID_HANDLE;
++    }
++
++    gpio_mmap_reg = (uint8_t*) mmap(NULL, MT7628_BLOCK_SIZE, PROT_READ | PROT_WRITE,
++                                   MAP_FILE | MAP_SHARED, gpio_mmap_fd, MT7628_GPIOMODE_BASE);
++    if (gpio_mmap_reg == MAP_FAILED) {
++        syslog(LOG_ERR, "linkit gpio_mmap: failed to mmap");
++        gpio_mmap_reg = NULL;
++        close(gpio_mmap_fd);
++        return MRAA_ERROR_NO_RESOURCES;
++    }
++    return 0;
++}
++
++static void set_gpiomode(unsigned int mask, unsigned int shift, unsigned int val)
++{
++    unsigned int reg;
++    unsigned int offset = 0x60;
++
++    if (shift >= 32) {
++              shift -= 32;
++              offset += 4;
++    }
++
++    reg = *(volatile uint32_t*) (gpio_mmap_reg + offset);
++
++    reg &= ~(mask << shift);
++    reg |= (val << shift);
++    *(volatile uint32_t*) (gpio_mmap_reg + offset) = reg;
++}
++
++enum {
++      MUX_GPIO = 0,
++      MUX_SPI_S,
++      MUX_SPI_CS1,
++      MUX_I2S,
++      MUX_UART0,
++      MUX_I2C,
++      MUX_UART1,
++      MUX_UART2,
++      MUX_PWM0,
++      MUX_PWM1,
++      MUX_EPHY,
++      MUX_WLED,
++      __MUX_MAX,
++};
++
++static unsigned char gpio_mux_groups[64];
++static struct pinmux {
++      char *name;
++      char *func[4];
++      unsigned int shift;
++      unsigned int mask;
++} mt7688_mux[] = {
++      {
++              .name = "refclk",
++              .func = { "refclk", "gpio", NULL, NULL },
++              .shift = 18,
++              .mask = 0x1,
++      }, {
++              .name = "spi_s",
++              .func = { "spi_s", "gpio", "utif", "pwm" },
++              .shift = 2,
++              .mask = 0x3,
++      }, {
++              .name = "spi_cs1",
++              .func = { "spi_cs1", "gpio", NULL, "refclk" },
++              .shift = 4,
++              .mask = 0x3,
++      }, {
++              .name = "i2s",
++              .func = { "i2s", "gpio", "pcm", NULL },
++              .shift = 6,
++              .mask = 0x3,
++      }, {
++              .name = "uart0",
++              .func = { "uart", "gpio", NULL, NULL },
++              .shift = 8,
++              .mask = 0x3,
++      }, {
++              .name = "i2c",
++              .func = { "i2c", "gpio", NULL, NULL },
++              .shift = 20,
++              .mask = 0x3,
++      }, {
++              .name = "uart1",
++              .func = { "uart", "gpio", NULL, NULL },
++              .shift = 24,
++              .mask = 0x3,
++      }, {
++              .name = "uart2",
++              .func = { "uart", "gpio", "pwm", NULL },
++              .shift = 26,
++              .mask = 0x3,
++      }, {
++              .name = "pwm0",
++              .func = { "pwm", "gpio", NULL, NULL },
++              .shift = 28,
++              .mask = 0x3,
++      }, {
++              .name = "pwm1",
++              .func = { "pwm", "gpio", NULL, NULL },
++              .shift = 30,
++              .mask = 0x3,
++      }, {
++              .name = "ephy",
++              .func = { "ephy", "gpio", NULL, NULL },
++              .shift = 34,
++              .mask = 0x3,
++      }, {
++              .name = "wled",
++              .func = { "wled", "gpio", NULL, NULL },
++              .shift = 32,
++              .mask = 0x3,
++      },
++};
++
++mraa_result_t gpio_init_pre(int pin)
++{
++      struct pinmux *m = &mt7688_mux[gpio_mux_groups[pin]];
++
++      set_gpiomode(m->mask, m->shift, 1);
++
++      return 0;
++}
++
++static void gpiomode_set(unsigned int id, char *name)
++{
++      int i;
++
++      if (id >= __MUX_MAX)
++              return;
++
++      for (i = 0; i < 4; i++) {
++              if (!mt7688_mux[id].func[i] || strcmp(mt7688_mux[id].func[i], name))
++                      continue;
++              set_gpiomode(mt7688_mux[id].mask, mt7688_mux[id].shift, i);
++              syslog(0, "mraa: set pinmux %s -> %s\n", mt7688_mux[id].name, name);
++              return;
++      }
++}
++
++mraa_result_t i2c_init_pre(unsigned int bus)
++{
++      gpiomode_set(MUX_I2C, "i2c");
++      return 0;
++}
++
++mraa_result_t
++pwm_init_post(mraa_pwm_context pwm)
++{
++      switch(pwm->pin) {
++      case 0:
++              gpiomode_set(MUX_PWM0, "pwm");
++              break;
++      case 1:
++              gpiomode_set(MUX_PWM1, "pwm");
++              break;
++      case 2:
++      case 3:
++              gpiomode_set(MUX_UART2, "pwm");
++              break;
++      }
++      return 0;
++}
++
++mraa_result_t spi_init_pre(int bus)
++{
++      gpiomode_set(MUX_SPI_CS1, "spi_cs1");
++      return 0;
++}
++
++mraa_result_t uart_init_pre(int index)
++{
++      switch(index) {
++      case 0:
++              gpiomode_set(MUX_UART0, "uart");
++              break;
++      case 1:
++              gpiomode_set(MUX_UART1, "uart");
++              break;
++      case 2:
++              gpiomode_set(MUX_UART2, "uart");
++              break;
++      }
++      return 0;
++}
++
++mraa_result_t
++i2c_freq(mraa_i2c_context dev, mraa_i2c_mode_t mode)
++{
++    switch (mode) {
++        case MRAA_I2C_STD:
++            break;
++        default:
++            syslog(LOG_ERR, "Invalid i2c frequency");
++            break;
++    }
++    return MRAA_SUCCESS;
++}
++
++
+ mraa_board_t*
+ mraa_mtk_linkit()
+ {
++    int i;
++
++    if (mmap_gpiomode())
++          return NULL;
++
+     mraa_board_t* b = (mraa_board_t*) malloc(sizeof(mraa_board_t));
+     if (b == NULL) {
+         return NULL;
+     }
+-    b->platform_name = "LINKIT";
++    memset(b, 0, sizeof(mraa_board_t));
++
++    b->platform_name = "LinkIt Smart 7688";
+     platform_detected = PLATFORM_MEDIATEK_LINKIT;
+-    b->phy_pin_count = 31;
++    b->phy_pin_count = 64;
+     b->aio_count = 0;
+     b->adc_raw = 0;
+     b->adc_supported = 0;
+     b->pwm_default_period = 500;
+-    b->pwm_max_period = 2147483;
++    b->pwm_max_period = 1000000;
+     b->pwm_min_period = 1;
+-    b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * b->phy_pin_count);
+-
+-    advance_func->gpio_mmap_setup = &mraa_mtk_linkit_mmap_setup;
+-
+-    strncpy(b->pins[0].name, "P0", MRAA_PIN_NAME_SIZE);
+-    b->pins[0].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
+-
+-    strncpy(b->pins[1].name, "P1", MRAA_PIN_NAME_SIZE);
+-    b->pins[1].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
+-
+-    strncpy(b->pins[2].name, "P2", MRAA_PIN_NAME_SIZE);
+-    b->pins[2].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
+-
+-    strncpy(b->pins[3].name, "P3", MRAA_PIN_NAME_SIZE);
+-    b->pins[3].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
+-
+-    strncpy(b->pins[4].name, "P4", MRAA_PIN_NAME_SIZE);
+-    b->pins[4].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
+-
+-    strncpy(b->pins[5].name, "P5", MRAA_PIN_NAME_SIZE);
+-    b->pins[5].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
+-
+-    strncpy(b->pins[6].name, "P6", MRAA_PIN_NAME_SIZE);
+-    b->pins[6].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
+-
+-    strncpy(b->pins[7].name, "P7", MRAA_PIN_NAME_SIZE);
+-    b->pins[7].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
+-
+-    strncpy(b->pins[8].name, "P8", MRAA_PIN_NAME_SIZE);
+-    b->pins[8].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
+-    b->pins[8].gpio.pinmap = 21;
+-    b->pins[8].uart.parent_id = 2;
+-    b->pins[8].uart.mux_total = 0;
++    b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t));
++    if (b->adv_func == NULL) {
++        return NULL;
++    }
+-    strncpy(b->pins[9].name, "P9", MRAA_PIN_NAME_SIZE);
+-    b->pins[9].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
+-    b->pins[9].gpio.pinmap = 20;
+-    b->pins[9].uart.parent_id = 2;
+-    b->pins[9].uart.mux_total = 0;
++    b->adv_func->i2c_init_pre = i2c_init_pre;
++    b->adv_func->pwm_init_post = pwm_init_post;
++    b->adv_func->spi_init_pre = spi_init_pre;
++    b->adv_func->uart_init_pre = uart_init_pre;
++    b->adv_func->gpio_init_pre = gpio_init_pre;
++    b->adv_func->i2c_set_frequency_replace = &i2c_freq;
+-    strncpy(b->pins[10].name, "P10", MRAA_PIN_NAME_SIZE);
+-    b->pins[10].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
+-    b->pins[10].gpio.pinmap = 2;
++    b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * b->phy_pin_count);
+-    strncpy(b->pins[11].name, "P11", MRAA_PIN_NAME_SIZE);
+-    b->pins[11].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
+-    b->pins[11].gpio.pinmap = 3;
++    memset(b->pins, 0, sizeof(mraa_pininfo_t) * b->phy_pin_count);
++    memset(gpio_mux_groups, -1, sizeof(gpio_mux_groups));
+-    strncpy(b->pins[12].name, "P12", MRAA_PIN_NAME_SIZE);
+-    b->pins[12].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
+-    b->pins[12].gpio.pinmap = 0;
++    b->adv_func->gpio_mmap_setup = &mraa_mtk_linkit_mmap_setup;
+-    strncpy(b->pins[13].name, "P13", MRAA_PIN_NAME_SIZE);
+-    b->pins[13].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
+-    b->pins[13].gpio.pinmap = 1;
++    for (i = 0; i < b->phy_pin_count; i++) {
++        snprintf(b->pins[i].name, MRAA_PIN_NAME_SIZE, "GPIO%d", i);
++        b->pins[i].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
++    }
+-    strncpy(b->pins[14].name, "P14", MRAA_PIN_NAME_SIZE);
+-    b->pins[14].capabilites = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
++    strncpy(b->pins[43].name, "GPIO43", MRAA_PIN_NAME_SIZE);
++    b->pins[43].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[43].gpio.pinmap = 43;
++    gpio_mux_groups[43] = MUX_EPHY;
++
++    strncpy(b->pins[20].name, "GPIO20", MRAA_PIN_NAME_SIZE);
++    b->pins[20].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 1 };
++    b->pins[20].gpio.pinmap = 20;
++    b->pins[20].uart.parent_id = 2;
++    b->pins[20].uart.mux_total = 0;
++    b->pins[20].pwm.parent_id = 0;
++    b->pins[20].pwm.pinmap = 2;
++    gpio_mux_groups[20] = MUX_UART2;
++
++    strncpy(b->pins[21].name, "GPIO21", MRAA_PIN_NAME_SIZE);
++    b->pins[21].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 1 };
++    b->pins[21].gpio.pinmap = 21;
++    b->pins[21].uart.parent_id = 2;
++    b->pins[21].uart.mux_total = 0;
++    b->pins[21].pwm.parent_id = 0;
++    b->pins[21].pwm.pinmap = 3;
++    gpio_mux_groups[21] = MUX_UART2;
++
++    strncpy(b->pins[2].name, "GPIO2", MRAA_PIN_NAME_SIZE);
++    b->pins[2].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[2].gpio.pinmap = 2;
++    gpio_mux_groups[2] = MUX_I2S;
++
++    strncpy(b->pins[3].name, "GPIO3", MRAA_PIN_NAME_SIZE);
++    b->pins[3].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[3].gpio.pinmap = 3;
++    gpio_mux_groups[3] = MUX_I2S;
++
++    strncpy(b->pins[0].name, "GPIO0", MRAA_PIN_NAME_SIZE);
++    b->pins[0].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[0].gpio.pinmap = 0;
++    gpio_mux_groups[0] = MUX_I2S;
++
++    strncpy(b->pins[1].name, "GPIO1", MRAA_PIN_NAME_SIZE);
++    b->pins[1].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[1].gpio.pinmap = 1;
++    gpio_mux_groups[1] = MUX_I2S;
++
++    strncpy(b->pins[37].name, "GPIO37", MRAA_PIN_NAME_SIZE);
++    b->pins[37].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[37].gpio.pinmap = 37;
++    gpio_mux_groups[37] = MUX_GPIO;
++
++    strncpy(b->pins[44].name, "GPIO44", MRAA_PIN_NAME_SIZE);
++    b->pins[44].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[44].gpio.pinmap = 44;
++    gpio_mux_groups[44] = MUX_WLED;
++
++    strncpy(b->pins[46].name, "GPIO46", MRAA_PIN_NAME_SIZE);
++    b->pins[46].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
++    b->pins[46].gpio.pinmap = 46;
++    b->pins[46].uart.parent_id = 1;
++    b->pins[46].uart.mux_total = 0;
++    gpio_mux_groups[46] = MUX_UART1;
++
++    strncpy(b->pins[45].name, "GPIO45", MRAA_PIN_NAME_SIZE);
++    b->pins[45].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
++    b->pins[45].gpio.pinmap = 45;
++    b->pins[45].uart.parent_id = 1;
++    b->pins[45].uart.mux_total = 0;
++    gpio_mux_groups[45] = MUX_UART1;
++
++    strncpy(b->pins[13].name, "GPIO13", MRAA_PIN_NAME_SIZE);
++    b->pins[13].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
++    b->pins[13].gpio.pinmap = 13;
++    b->pins[13].uart.parent_id = 1;
++    b->pins[13].uart.mux_total = 0;
++    gpio_mux_groups[13] = MUX_UART0;
++
++    strncpy(b->pins[12].name, "GPIO12", MRAA_PIN_NAME_SIZE);
++    b->pins[12].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
++    b->pins[12].gpio.pinmap = 12;
++    b->pins[12].uart.parent_id = 0;
++    b->pins[12].uart.mux_total = 0;
++    gpio_mux_groups[12] = MUX_UART0;
++
++    strncpy(b->pins[5].name, "GPIO5", MRAA_PIN_NAME_SIZE);
++    b->pins[5].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 };
++    b->pins[5].gpio.pinmap = 5;
++    b->pins[5].i2c.pinmap = 0;
++    b->pins[5].i2c.mux_total = 0;
++    gpio_mux_groups[5] = MUX_I2C;
++
++    strncpy(b->pins[4].name, "GPIO4", MRAA_PIN_NAME_SIZE);
++    b->pins[4].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 };
++    b->pins[4].gpio.pinmap = 4;
++    b->pins[4].i2c.pinmap = 0;
++    b->pins[4].i2c.mux_total = 0;
++    gpio_mux_groups[4] = MUX_I2C;
++
++    strncpy(b->pins[6].name, "GPIO6", MRAA_PIN_NAME_SIZE);
++    b->pins[6].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
++    b->pins[6].gpio.pinmap = 6;
++    b->pins[6].spi.pinmap = 0;
++    b->pins[6].spi.mux_total = 0;
++    gpio_mux_groups[6] = MUX_SPI_CS1;
++
++    strncpy(b->pins[7].name, "GPIO7", MRAA_PIN_NAME_SIZE);
++    b->pins[7].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 1, 0, 0, 0 };
++    b->pins[7].spi.pinmap = 0;
++    b->pins[7].spi.mux_total = 0;
++
++    strncpy(b->pins[8].name, "GPIO8", MRAA_PIN_NAME_SIZE);
++    b->pins[8].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 1, 0, 0, 0 };
++    b->pins[8].spi.pinmap = 0;
++    b->pins[8].spi.mux_total = 0;
++
++    strncpy(b->pins[9].name, "GPIO9", MRAA_PIN_NAME_SIZE);
++    b->pins[9].capabilites = (mraa_pincapabilities_t){ 1, 0, 0, 0, 1, 0, 0, 0 };
++    b->pins[9].spi.pinmap = 0;
++    b->pins[9].spi.mux_total = 0;
++
++    strncpy(b->pins[18].name, "GPIO18", MRAA_PIN_NAME_SIZE);
++    b->pins[18].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 };
++    b->pins[18].gpio.pinmap = 18;
++    b->pins[18].pwm.parent_id = 0;
++    b->pins[18].pwm.pinmap = 0;
++    gpio_mux_groups[18] = MUX_PWM0;
++
++    strncpy(b->pins[19].name, "GPIO19", MRAA_PIN_NAME_SIZE);
++    b->pins[19].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 };
++    b->pins[19].gpio.pinmap = 19;
++    b->pins[19].pwm.parent_id = 0;
++    b->pins[19].pwm.pinmap = 1;
++    gpio_mux_groups[19] = MUX_PWM1;
++
++    strncpy(b->pins[16].name, "GPIO16", MRAA_PIN_NAME_SIZE);
++    b->pins[16].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[16].gpio.pinmap = 16;
++    gpio_mux_groups[16] = MUX_SPI_S;
++
++    strncpy(b->pins[17].name, "GPIO17", MRAA_PIN_NAME_SIZE);
++    b->pins[17].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[17].gpio.pinmap = 17;
++    gpio_mux_groups[17] = MUX_SPI_S;
++
++    strncpy(b->pins[14].name, "GPIO14", MRAA_PIN_NAME_SIZE);
++    b->pins[14].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
++    b->pins[14].gpio.pinmap = 14;
++    gpio_mux_groups[14] = MUX_SPI_S;
+-    strncpy(b->pins[15].name, "P15", MRAA_PIN_NAME_SIZE);
++    strncpy(b->pins[15].name, "GPIO15", MRAA_PIN_NAME_SIZE);
+     b->pins[15].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
+-    b->pins[15].gpio.pinmap = 44;
+-
+-    strncpy(b->pins[16].name, "P16", MRAA_PIN_NAME_SIZE);
+-    b->pins[16].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
+-    b->pins[16].gpio.pinmap = 46;
+-    b->pins[16].uart.parent_id = 1;
+-    b->pins[16].uart.mux_total = 0;
+-
+-    strncpy(b->pins[17].name, "P17", MRAA_PIN_NAME_SIZE);
+-    b->pins[17].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
+-    b->pins[17].gpio.pinmap = 45;
+-    b->pins[17].uart.parent_id = 1;
+-    b->pins[17].uart.mux_total = 0;
+-
+-    strncpy(b->pins[18].name, "P18", MRAA_PIN_NAME_SIZE);
+-    b->pins[18].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
+-    b->pins[18].gpio.pinmap = 13;
+-    b->pins[18].uart.parent_id = 1;
+-    b->pins[18].uart.mux_total = 0;
+-
+-    strncpy(b->pins[19].name, "P19", MRAA_PIN_NAME_SIZE);
+-    b->pins[19].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 1 };
+-    b->pins[19].gpio.pinmap = 12;
+-    b->pins[19].uart.parent_id = 0;
+-    b->pins[19].uart.mux_total = 0;
+-
+-    strncpy(b->pins[20].name, "P20", MRAA_PIN_NAME_SIZE);
+-    b->pins[20].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 };
+-    b->pins[20].gpio.pinmap = 5;
+-    b->pins[20].i2c.pinmap = 0;
+-    b->pins[20].i2c.mux_total = 0;
+-
+-    strncpy(b->pins[21].name, "P21", MRAA_PIN_NAME_SIZE);
+-    b->pins[21].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 1, 0, 0 };
+-    b->pins[21].gpio.pinmap = 4;
+-    b->pins[21].i2c.pinmap = 0;
+-    b->pins[21].i2c.mux_total = 0;
+-
+-    strncpy(b->pins[22].name, "P22", MRAA_PIN_NAME_SIZE);
+-    b->pins[22].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
+-    b->pins[22].gpio.pinmap = 8;
+-    b->pins[22].spi.pinmap = 0;
+-    b->pins[22].spi.mux_total = 0;
+-
+-    strncpy(b->pins[23].name, "P23", MRAA_PIN_NAME_SIZE);
+-    b->pins[23].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
+-    b->pins[23].gpio.pinmap = 9;
+-    b->pins[23].spi.pinmap = 0;
+-    b->pins[23].spi.mux_total = 0;
+-
+-    strncpy(b->pins[24].name, "P24", MRAA_PIN_NAME_SIZE);
+-    b->pins[24].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
+-    b->pins[24].gpio.pinmap = 7;
+-    b->pins[24].spi.pinmap = 0;
+-    b->pins[24].spi.mux_total = 0;
+-
+-    strncpy(b->pins[25].name, "P25", MRAA_PIN_NAME_SIZE);
+-    b->pins[25].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 1, 0, 0, 0 };
+-    b->pins[25].gpio.pinmap = 6;
+-    b->pins[25].spi.pinmap = 0;
+-    b->pins[25].spi.mux_total = 0;
+-
+-    strncpy(b->pins[26].name, "P26", MRAA_PIN_NAME_SIZE);
+-    b->pins[26].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 };
+-    b->pins[26].gpio.pinmap = 18;
+-
+-    strncpy(b->pins[27].name, "P27", MRAA_PIN_NAME_SIZE);
+-    b->pins[27].capabilites = (mraa_pincapabilities_t){ 1, 1, 1, 0, 0, 0, 0, 0 };
+-    b->pins[27].gpio.pinmap = 19;
+-
+-    strncpy(b->pins[28].name, "P28", MRAA_PIN_NAME_SIZE);
+-    b->pins[28].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
+-    b->pins[28].gpio.pinmap = 16;
+-
+-    strncpy(b->pins[29].name, "P29", MRAA_PIN_NAME_SIZE);
+-    b->pins[29].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
+-    b->pins[29].gpio.pinmap = 17;
+-
+-    strncpy(b->pins[30].name, "P30", MRAA_PIN_NAME_SIZE);
+-    b->pins[30].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
+-    b->pins[30].gpio.pinmap = 14;
+-
+-    strncpy(b->pins[31].name, "P31", MRAA_PIN_NAME_SIZE);
+-    b->pins[31].capabilites = (mraa_pincapabilities_t){ 1, 1, 0, 0, 0, 0, 0, 0 };
+-    b->pins[31].gpio.pinmap = 15;
++    b->pins[15].gpio.pinmap = 15;
++    gpio_mux_groups[15] = MUX_SPI_S;
+     // BUS DEFINITIONS
+     b->i2c_bus_count = 1;
+     b->def_i2c_bus = 0;
+-        b->i2c_bus[0].bus_id = 0;
+-    b->i2c_bus[0].sda = 20;
+-    b->i2c_bus[0].scl = 21;
++    b->i2c_bus[0].bus_id = 0;
++    b->i2c_bus[0].sda = 5;
++    b->i2c_bus[0].scl = 4;
+     b->spi_bus_count = 1;
+     b->def_spi_bus = 0;
+-    b->spi_bus[0].bus_id = 0;
+-    b->spi_bus[0].slave_s = 0;
+-    b->spi_bus[0].cs = 25;
+-    b->spi_bus[0].mosi = 22;
+-    b->spi_bus[0].miso = 23;
+-    b->spi_bus[0].sclk = 21;
++    b->spi_bus[0].bus_id = 32766;
++    b->spi_bus[0].slave_s = 1;
++    b->spi_bus[0].cs = 6;
++    b->spi_bus[0].mosi = 8;
++    b->spi_bus[0].miso = 9;
++    b->spi_bus[0].sclk = 7;
+     b->uart_dev_count = 3;
+     b->def_uart_dev = 0;
+-    b->uart_dev[0].rx = 18;
+-    b->uart_dev[0].tx = 19;
+-
+-    b->uart_dev[1].rx = 16;
+-    b->uart_dev[1].tx = 17;
+-
+-    b->uart_dev[2].rx = 9;
+-    b->uart_dev[2].tx = 8;
++    b->uart_dev[0].rx = 13;
++    b->uart_dev[0].tx = 12;
++    b->uart_dev[0].device_path = "/dev/ttyS0";
++    b->uart_dev[1].rx = 46;
++    b->uart_dev[1].tx = 45;
++    b->uart_dev[1].device_path = "/dev/ttyS1";
++    b->uart_dev[2].rx = 21;
++    b->uart_dev[2].tx = 20;
++    b->uart_dev[2].device_path = "/dev/ttyS2";
+     b->gpio_count = 0;
+-    int i;
+     for (i = 0; i < b->phy_pin_count; i++) {
+         if (b->pins[i].capabilites.gpio) {
+             b->gpio_count++;
+--- a/src/gpio/gpio.c
++++ b/src/gpio/gpio.c
+@@ -113,6 +113,8 @@
+         close(export);
+     }
++    mraa_gpio_use_mmaped(dev, 1);
++
+ init_internal_cleanup:
+     if (status != MRAA_SUCCESS) {
+         if (dev != NULL)
diff --git a/libs/libupm/Makefile b/libs/libupm/Makefile
new file mode 100644 (file)
index 0000000..93287c5
--- /dev/null
@@ -0,0 +1,82 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libupm
+PKG_VERSION:=0.4.0
+
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/intel-iot-devkit/upm.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=04dc6df4297a7766d6f1a8fef9699d586e7e0d92
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+CMAKE_INSTALL:=1
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=LGPL-2.1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+UPM_MODULES:= \
+       a110x ad8232 adafruitss adc121c021 adis16448 adxl335 adxl345 am2315 apds9002 at42qt1070 biss0001 bmpx8x buzzer \
+       cjq4435 ds1307 ecs1030 enc03r flex gas gp2y0a grovecircularled grovecollision groveehr groveeldriver groveelectromagnet \
+       groveemg grovegprs grovegsr grovelinefinder grovemd grovemoisture groveo2 grovescam grove grovespeaker grovevdiv grovewater \
+       grovewfs guvas12d h3lis331dl hcsr04 hm11 hmc5883l hmtrp hp20x ht9170 htu21d hx711 i2clcd ina132 isd1820 itg3200 joystick12 \
+       l298 ldt0028 lm35 lol loudness lpd8806 lsm303 lsm9ds0 m24lr64e max31723 max31855 max44000 max5487 maxds3231m maxsonarez \
+       mg811 mhz16 mic mlx90614 mma7455 mma7660 mpl3115a2 mpr121 mpu9150 mq303a my9221 nrf24l01 nrf8001 nunchuck otp538u \
+       pn532 ppd42ns pulsensor rfr359f rgbringcoder rotaryencoder rpr220 servo si114x sm130 st7735 stepmotor sx6119 ta12200 tcs3414cs \
+       th02 tm1637 tsl2561 ttp223 ublox6 uln200xa waterlevel wheelencoder wt5001 yg1006 zfm20
+
+CMAKE_OPTIONS=-DBUILDARCH=$(CONFIG_ARCH) \
+       -DNODE_EXECUTABLE=$(STAGING_DIR_HOST)/bin/node \
+       -DSWIG_DIR=$(STAGING_DIR_HOST)/bin
+
+define Package/libupm/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libmraa +librt
+  SUBMENU:=IoT
+endef
+
+define Package/libupm
+  $(call Package/libupm/Default)
+  TITLE:=Intel IoT sensor library - Full
+endef
+
+define Package/libupm/install/Default
+       $(INSTALL_DIR) $(1)/usr/lib/{node/,python2.7/site-packages}; \
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/libupm-$(2).so* $(1)/usr/lib/; \
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/node_modules/jsupm_$(2) $(1)/usr/lib/node/; \
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/python2.7/site-packages/{pyupm_$(2).py,_pyupm_$(2).so} \
+               $(1)/usr/lib/python2.7/site-packages/ ;
+endef
+
+define Package/libupm/install
+       $(foreach module, $(UPM_MODULES),       \
+               $(call Package/libupm/install/Default,$(1),$(module)))
+endef
+
+define UpmPackage
+define Package/libupm-$(1)
+  $(call Package/libupm/Default)
+  TITLE:=Intel IoT sensor library - $(1)
+endef
+
+define Package/libupm-$(1)/install
+       $(call Package/libupm/install/Default,$$(1),$(1))
+endef
+endef
+
+$(eval $(call BuildPackage,libupm))
+$(foreach package, $(UPM_MODULES),                     \
+       $(eval $(call UpmPackage,$(package)))           \
+       $(eval $(call BuildPackage,libupm-$(package)))  \
+)
diff --git a/libs/libupm/patches/001-version.patch b/libs/libupm/patches/001-version.patch
new file mode 100644 (file)
index 0000000..3d4fd6c
--- /dev/null
@@ -0,0 +1,16 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -26,12 +26,7 @@
+ include(GNUInstallDirs)
+ # Make a version file containing the current version from git.
+-include (GetGitRevisionDescription)
+-git_describe (VERSION "--tags")
+-if ("x_${VERSION}" STREQUAL "x_GIT-NOTFOUND")
+-  message (WARNING " - Install git to compile a production UPM!")
+-  set (VERSION "v0.4.0-dirty")
+-endif ()
++set (VERSION "v0.4.0")
+ message (INFO " - UPM Version ${VERSION}")
diff --git a/libs/libupm/patches/002-at42qt1070-id.patch b/libs/libupm/patches/002-at42qt1070-id.patch
new file mode 100644 (file)
index 0000000..85544c9
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/src/at42qt1070/at42qt1070.cxx
++++ b/src/at42qt1070/at42qt1070.cxx
+@@ -53,7 +53,7 @@
+         return;
+     }
+-    if (readChipID() != 0x2E) {
++    if (readChipID() != 0x1b && readChipID() != 0x2E) {
+         throw std::runtime_error("Chip ID does not match the expected value (2Eh)");
+     }
diff --git a/libs/libupm/patches/003-lsm303-args.patch b/libs/libupm/patches/003-lsm303-args.patch
new file mode 100644 (file)
index 0000000..d2b2d0e
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/src/lsm303/lsm303.h
++++ b/src/lsm303/lsm303.h
+@@ -34,7 +34,7 @@
+ /* LSM303 Address definitions */
+ #define LSM303_MAG 0x1E // assuming SA0 grounded
+-#define LSM303_ACC 0x18 // assuming SA0 grounded
++#define LSM303_ACC 0x1E // assuming SA0 grounded
+ /* LSM303 Register definitions */
+ #define CTRL_REG1_A 0x20
index 412b5f90bc5b5a72e94360d7a61f63f3b501909d..eeb49b183705452cbf6cfbeb6a4bbc7dc41fa156 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2008-2011 OpenWrt.org
+# Copyright (C) 2008-2015 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=motion
 PKG_VERSION=3.4.0-20141018-$(PKG_SOURCE_VERSION)
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_MAINTAINER:=Roger D <rogerdammit@gmail.com>
 PKG_LICENSE:=GPLv2
diff --git a/multimedia/motion/patches/100-musl-compat.patch b/multimedia/motion/patches/100-musl-compat.patch
new file mode 100644 (file)
index 0000000..b788e26
--- /dev/null
@@ -0,0 +1,49 @@
+--- a/motion.c
++++ b/motion.c
+@@ -2630,6 +2630,17 @@ int main (int argc, char **argv)
+     struct sigaction sigchild_action;
+     setup_signals(&sig_handler_action, &sigchild_action);
++    /*
++     * Create and a thread attribute for the threads we spawn later on.
++     * PTHREAD_CREATE_DETACHED means to create threads detached, i.e.
++     * their termination cannot be synchronized through 'pthread_join'.
++     */
++    pthread_attr_init(&thread_attr);
++    pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
++
++    /* Create the TLS key for thread number. */
++    pthread_key_create(&tls_key_threadnr, NULL);
++
+     motion_startup(1, argc, argv);
+ #ifdef HAVE_FFMPEG
+@@ -2648,17 +2659,6 @@ int main (int argc, char **argv)
+     if (cnt_list[0]->conf.setup_mode)
+         MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, "%s: Motion running in setup mode.");
+-    /*
+-     * Create and a thread attribute for the threads we spawn later on.
+-     * PTHREAD_CREATE_DETACHED means to create threads detached, i.e.
+-     * their termination cannot be synchronized through 'pthread_join'.
+-     */
+-    pthread_attr_init(&thread_attr);
+-    pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
+-
+-    /* Create the TLS key for thread number. */
+-    pthread_key_create(&tls_key_threadnr, NULL);
+-
+     do {
+         if (restart) {
+             /*
+--- a/motion.h
++++ b/motion.h
+@@ -84,7 +84,7 @@
+ #endif
+ /* strerror_r() XSI vs GNU */
+-#if (defined(BSD)) || ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE)
++#if (defined(BSD)) || ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE) || (!defined(__GLIBC__))
+ #define XSI_STRERROR_R
+ #endif
index 9b0f7e7d16f35bfe55c3703ae3d2f77a3a343aca..5ef68cfa6fcdb4f42ad1b2e2b48ad930294babf5 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=chrony
-PKG_VERSION:=2.1.1
+PKG_VERSION:=2.2
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://download.tuxfamily.org/chrony/
-PKG_MD5SUM:=15e470a51ab6e09e65bc0a2fbc5299af
+PKG_MD5SUM:=17bc77d3d2ce942675f9600b60452717
 
 PKG_MAINTAINER:=Miroslav Lichvar <mlichvar0@gmail.com>
 PKG_LICENSE:=GPL-2.0
@@ -41,7 +41,6 @@ endef
 
 define Package/chrony/conffiles
 /etc/chrony/chrony.conf
-/etc/chrony/chrony.keys
 /etc/config/chrony
 endef
 
@@ -51,6 +50,7 @@ CONFIGURE_ARGS+= \
        --host-system=Linux \
        --sysconfdir=/etc/chrony \
        --prefix=/usr \
+       --chronysockdir=/var/run/chrony \
        --disable-readline \
        --disable-rtc \
        --disable-asyncdns \
@@ -71,7 +71,6 @@ define Package/chrony/install
        $(INSTALL_BIN) ./files/chronyd.init $(1)/etc/init.d/chronyd
        $(INSTALL_CONF) ./files/chrony.config $(1)/etc/config/chrony
        $(INSTALL_CONF) ./files/chrony.conf $(1)/etc/chrony/chrony.conf
-       $(INSTALL_CONF) ./files/chrony.keys $(1)/etc/chrony/chrony.keys
 endef
 
 $(eval $(call BuildPackage,chrony))
index da0aa60ac8ff3108b26fe38658c76048169e96f8..b207c945e2d168d856a04248370ce7e71d5ccd35 100644 (file)
@@ -5,8 +5,3 @@ logchange 0.5
 
 # Don't log client accesses
 noclientlog
-
-# Password config for chronyc
-keyfile /etc/chrony/chrony.keys
-commandkey 1
-generatecommandkey
index 40843363a0c3edb99efed8bf8d036f75f7faa616..5f6a14b283b2656ad7d79bde3aeb62159b62cad2 100644 (file)
@@ -2,5 +2,5 @@ COMMAND=/usr/bin/chronyc
 
 [ -x $COMMAND ] || exit 0
 
-[ "$ACTION" = "ifup" -a "$INTERFACE" = "wan" ] && $COMMAND -a online
-[ "$ACTION" = "ifdown" -a "$INTERFACE" = "wan" ] && $COMMAND -a offline
+[ "$ACTION" = "ifup" -a "$INTERFACE" = "wan" ] && $COMMAND online
+[ "$ACTION" = "ifdown" -a "$INTERFACE" = "wan" ] && $COMMAND offline
diff --git a/net/chrony/files/chrony.keys b/net/chrony/files/chrony.keys
deleted file mode 100644 (file)
index f5f6319..0000000
+++ /dev/null
@@ -1 +0,0 @@
-# Keys for NTP authentication and chronyc commands
diff --git a/net/chrony/files/ntpd.config b/net/chrony/files/ntpd.config
deleted file mode 100644 (file)
index 7a3b6fd..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# Generic NTP configuration
-# Time servers and network(s) that may access the time service
-
-config ntpd
-       option TimeServers      "0.openwrt.pool.ntp.org 1.openwrt.pool.ntp.org 2.openwrt.pool.ntp.org 3.openwrt.pool.ntp.org"
-       option ClientAccessFrom "lan"
diff --git a/net/chrony/files/ntpd.hotplug b/net/chrony/files/ntpd.hotplug
deleted file mode 100644 (file)
index 4084336..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-COMMAND=/usr/bin/chronyc
-
-[ -x $COMMAND ] || exit 0
-
-[ "$ACTION" = "ifup" -a "$INTERFACE" = "wan" ] && $COMMAND -a online
-[ "$ACTION" = "ifdown" -a "$INTERFACE" = "wan" ] && $COMMAND -a offline
diff --git a/net/chrony/files/ntpd.init b/net/chrony/files/ntpd.init
deleted file mode 100644 (file)
index 3450185..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh /etc/rc.common
-# Copyright (C) 2006 OpenWrt.org
-
-START=60
-
-start() {
-       [ ! -f /var/run/chronyd.pid ] && (
-               /usr/sbin/chronyd -f /etc/chrony/chrony.conf
-
-               local NTP_SERVERS
-               local NTP_SERVER
-               local CLIENT_NETWORKS
-               local NETNAME
-               config_load ntpd
-               config_get NTP_SERVERS $CONFIG_SECTION TimeServers
-               config_get CLIENT_NETWORKS $CONFIG_SECTION ClientAccessFrom
-
-               . /lib/functions/network.sh
-
-               # Define servers with the iburst option to speed up the initial
-               # synchronization and allow clients to access the server
-               (
-                       for NTP_SERVER in $NTP_SERVERS; do
-                               echo add server $NTP_SERVER iburst
-                       done
-
-                       for NETNAME in $CLIENT_NETWORKS; do
-                               local subnet
-                               if network_get_subnet subnet "$NETNAME"; then
-                                       echo allow $subnet
-                               fi
-                       done
-               ) | chronyc -a > /dev/null 2>&1
-       )
-}
-
-stop() {
-       [ -r /var/run/chronyd.pid ] && PID=$(cat /var/run/chronyd.pid)
-       [ -n "$PID" ] && kill $PID
-}
-
-restart() {
-       stop
-       while [ -r /var/run/chronyd.pid ] ; do sleep 1; done
-       start
-}
diff --git a/net/chrony/patches/001-crosscompile.patch b/net/chrony/patches/001-crosscompile.patch
deleted file mode 100644 (file)
index d712e06..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
---- a/configure
-+++ b/configure
-@@ -254,6 +254,13 @@ do
-     --host-machine=* )
-       MACHINE=`echo $option | sed -e 's/^.*=//;'`
-     ;;
-+    --target=* )
-+      TARGET=`echo $option | sed -e 's/[^=]*=//;'`
-+      OPERATINGSYSTEM=`echo $TARGET | sed -e 's/.*-//;'`
-+      MACHINE=`echo $TARGET | sed -e 's/-.*//;'`
-+      VERSION=""
-+      SYSTEM=${OPERATINGSYSTEM}-${MACHINE}
-+    ;;
-     --help | -h )
-       usage
-       exit 0
-@@ -287,7 +294,7 @@ case $SYSTEM in
-         ;;
-     esac
-     ;;
--    Linux* )
-+    Linux* | linux* )
-         EXTRA_OBJECTS="sys_linux.o wrap_adjtimex.o"
-         try_linuxcaps=1
-         try_rtc=1
diff --git a/net/chrony/patches/002-ipv6_disabled_fixes.patch b/net/chrony/patches/002-ipv6_disabled_fixes.patch
deleted file mode 100644 (file)
index 629d2c7..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
---- a/ntp_io.c
-+++ b/ntp_io.c
-@@ -355,6 +355,7 @@ read_from_socket(void *anything)
-       }
- #endif
-+#ifdef HAVE_IPV6
- #ifdef IPV6_PKTINFO
-       if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
-         struct in6_pktinfo ipi;
-@@ -365,6 +366,7 @@ read_from_socket(void *anything)
-         remote_addr.local_ip_addr.family = IPADDR_INET6;
-       }
- #endif
-+#endif
- #ifdef SO_TIMESTAMP
-       if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP) {
-@@ -466,6 +468,7 @@ send_packet(void *packet, int packetlen,
-   }
- #endif
-+#ifdef HAVE_IPV6
- #ifdef IPV6_PKTINFO
-   if (remote_addr->local_ip_addr.family == IPADDR_INET6) {
-     struct cmsghdr *cmsg;
-@@ -484,6 +487,7 @@ send_packet(void *packet, int packetlen,
-         sizeof(ipi->ipi6_addr.s6_addr));
-   }
- #endif
-+#endif
- #if 0
-     LOG(LOGS_INFO, LOGF_NtpIO, "sending to %s:%d from %s",
index 27f75c6ef0bfaba3933fd961d0f7776fffa31a51..e529a889185c3c08c496dd18181df55426469ae4 100644 (file)
@@ -1,22 +1,27 @@
 #!/bin/sh /etc/rc.common
-# Copyright (C) 2006 OpenWrt.org
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+
+USE_PROCD=1
+
 START=50
 
+NAME=radiusd
+PROG=/usr/sbin/radiusd
 DEFAULT=/etc/default/radiusd
-LOG_D=/var/log
-RUN_D=/var/run
-PID_F=$RUN_D/radiusd.pid
-RADACCT_D=/var/db/radacct
-IPADDR=$(ifconfig br-lan | sed -n 's/.*dr:\(.*\)Bc.*/\1/p')
 
-start() {
+start_service()
+{
        [ -f $DEFAULT ] && . $DEFAULT
-       mkdir -p $LOG_D
-       mkdir -p $RUN_D
-       mkdir -p $RADACCT_D
-       radiusd -i $IPADDR -p 1812,1813 $OPTIONS
-}
+       mkdir -p /var/log
+       mkdir -p /var/run
+       mkdir -p /var/db/radacct
 
-stop() {
-       [ -f $PID_F ] && kill $(cat $PID_F)
+       procd_open_instance
+       procd_set_param command $PROG
+       [ -n "$IPADDR" ] && procd_append_param command -i $IPADDR
+       [ -n "$OPTIONS" ] && procd_append_param command $OPTIONS
+       procd_set_param respawn
+       procd_close_instance
 }
index 97511b9985df32852e99bf272eb224e837e7f327..bcf56f05ef4c6c58872c9ef9fd7e6bcd86765c33 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=mwan3
 PKG_VERSION:=1.6
-PKG_RELEASE:=2
+PKG_RELEASE:=3
 PKG_MAINTAINER:=Jeroen Louwes <jeroen.louwes@gmail.com>
 PKG_LICENSE:=GPLv2
 
index f117e49e6bc24a5f4356d438808d328bcbcaba0f..12423c794f867ca60011dc4df8bbbcacb7133868 100644 (file)
@@ -1,5 +1,41 @@
 #!/bin/sh
 
+local IP IPS IPT LOG
+
+[ -n "$ACTION" ] || exit 0
+[ -n "$INTERFACE" ] || exit 0
+
+if [ $ACTION == "ifup" ]; then
+        [ -n "$DEVICE" ] || exit 0
+fi
+
+if [ -x /usr/sbin/ip ]; then
+        IP="/usr/sbin/ip -4"
+elif [ -x /usr/bin/ip ]; then
+        IP="/usr/bin/ip -4"
+else
+        exit 1
+fi
+
+if [ -x /usr/sbin/ipset ]; then
+        IPS="/usr/sbin/ipset"
+else
+        exit 1
+fi
+
+if [ -x /usr/sbin/iptables ]; then
+        IPT="/usr/sbin/iptables -t mangle -w"
+else
+        exit 1
+fi
+
+if [ -x /usr/bin/logger ]; then
+        LOG="/usr/bin/logger -t mwan3 -p"
+else
+        exit 1
+fi
+
+
 mwan3_get_iface_id()
 {
        let iface_count++
@@ -398,25 +434,6 @@ mwan3_ifupdown()
        config_foreach mwan3_set_user_rules_iptables rule
 }
 
-[ -n "$ACTION" ] || exit 0
-[ -n "$INTERFACE" ] || exit 0
-
-if [ $ACTION == "ifup" ]; then
-       [ -n "$DEVICE" ] || exit 0
-fi
-
-[ -x /usr/sbin/ip ] || exit 1
-[ -x /usr/sbin/ipset ] || exit 1
-[ -x /usr/sbin/iptables ] || exit 1
-[ -x /usr/bin/logger ] || exit 1
-
-local IP IPS IPT LOG
-
-IP="/usr/sbin/ip -4"
-IPS="/usr/sbin/ipset"
-IPT="/usr/sbin/iptables -t mangle -w"
-LOG="/usr/bin/logger -t mwan3 -p"
-
 case "$ACTION" in
        ifup|ifdown)
                mwan3_ifupdown
index b887fa5e6b446e99312c3c9c814f34c8bde00f7e..a5da22ac9ffcff4a36472b56f0cc53fd92db276e 100755 (executable)
@@ -1,9 +1,26 @@
 #!/bin/sh
-. /lib/functions.sh
 
-IP="/usr/sbin/ip -4"
-IPS="/usr/sbin/ipset"
-IPT="/usr/sbin/iptables -t mangle -w"
+if [ -x /usr/sbin/ip ]; then
+        IP="/usr/sbin/ip -4"
+elif [ -x /usr/bin/ip ]; then
+        IP="/usr/bin/ip -4"
+else
+        exit 1
+fi
+
+if [ -x /usr/sbin/ipset ]; then
+        IPS="/usr/sbin/ipset"
+else
+        exit 1
+fi
+
+if [ -x /usr/sbin/iptables ]; then
+        IPT="/usr/sbin/iptables -t mangle -w"
+else
+        exit 1
+fi
+
+. /lib/functions.sh
 
 help()
 {
index 3c89801a35dd5eb1c4a55291b31ce4f3c3b7f475..b1c97d705988eac0cf7ba6b975282b093578d15a 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=madplay
 PKG_VERSION:=0.15.2b
-PKG_RELEASE:=4
+PKG_RELEASE:=5
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=@SF/mad \
@@ -24,14 +24,18 @@ PKG_FIXUP:=autoreconf
 include $(INCLUDE_DIR)/package.mk
 include $(INCLUDE_DIR)/nls.mk
 
-define Package/madplay
+define Package/madplay/default
   SECTION:=sound
   CATEGORY:=Sound
   DEPENDS:=+libid3tag +libmad $(INTL_DEPENDS)
-  TITLE:=MPEG audio player in fixed point
+  TITLE:=MPEG audio player in fixed point - $(1)
+  VARIANT:=$(1)
   URL:=http://sourceforge.net/projects/mad
 endef
 
+Package/madplay-alsa=$(call Package/madplay/default,alsa)
+Package/madplay=$(call Package/madplay/default,oss)
+
 define Package/madplay/description
        MAD is an MPEG audio decoder. It currently only supports the MPEG 1
        standard, but fully implements all three audio layers (Layer I, Layer II,
@@ -48,16 +52,27 @@ define Build/Configure
                --disable-experimental \
                --without-libiconv-prefix \
                --without-libintl-prefix \
-               --without-alsa \
                --without-esd \
                , \
                LIBS="-lz" \
        )
 endef
 
-define Package/madplay/install
+ifeq ($(BUILD_VARIANT),madplay-alsa)
+       CONFIGURE_ARGS += \
+               --without-oss \
+               --with-alsa
+endif
+
+ifeq ($(BUILD_VARIANT),madplay)
+       CONFIGURE_ARGS += \
+               --without-alsa
+endif
+
+define Package/madplay-$(BUILD_VARIANT)/install
        $(INSTALL_DIR) $(1)/usr/bin
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/madplay $(1)/usr/bin/
 endef
 
+$(eval $(call BuildPackage,madplay-alsa))
 $(eval $(call BuildPackage,madplay))
diff --git a/sound/madplay/patches/0001-switch-to-new-alsa-api.patch b/sound/madplay/patches/0001-switch-to-new-alsa-api.patch
new file mode 100644 (file)
index 0000000..60d7bd3
--- /dev/null
@@ -0,0 +1,173 @@
+Switch madplay to the new API. This is done thanks to a patch written
+by Micha Nelissen <micha@neli.hopto.org> and available at
+http://article.gmane.org/gmane.comp.audio.mad.devel/729.
+
+--- madplay-0.15.2b/audio_alsa.c       2008-10-18 15:10:16.000000000 +0200
++++ madplay-0.15.2b/audio_alsa.c.new   2008-10-18 15:03:27.000000000 +0200
+@@ -28,31 +28,30 @@
+
+ #include <errno.h>
+
+-#define ALSA_PCM_OLD_HW_PARAMS_API
+-#define ALSA_PCM_OLD_SW_PARAMS_API
+ #include <alsa/asoundlib.h>
+
+ #include <mad.h>
+
+ #include "audio.h"
+
+-char *buf     = NULL;
+-int paused    = 0;
++#define BUFFER_TIME_MAX     500000
+
+-int rate      = -1;
+-int channels  = -1;
+-int bitdepth  = -1;
+-int sample_size       = -1;
+-
+-int buffer_time               = 500000;
+-int period_time               = 100000;
+-char *defaultdev      = "plughw:0,0";
++unsigned char *buf  = NULL;
++int paused        = 0;
++
++unsigned int rate           = 0;
++unsigned int channels     = -1;
++unsigned int bitdepth     = -1;
++unsigned int sample_size    = -1;
++
++unsigned int buffer_time;
++unsigned int period_time;
++char *defaultdev          = "plughw:0,0";
+
+ snd_pcm_hw_params_t *alsa_hwparams;
+ snd_pcm_sw_params_t *alsa_swparams;
+
+-snd_pcm_sframes_t buffer_size;
+-snd_pcm_sframes_t period_size;
++snd_pcm_uframes_t buffer_size;
+
+ snd_pcm_format_t  alsa_format = -1;
+ snd_pcm_access_t  alsa_access = SND_PCM_ACCESS_MMAP_INTERLEAVED;
+@@ -66,14 +65,20 @@
+                snd_pcm_hw_params_t *params,
+                snd_pcm_access_t access)
+ {
+-      int err, dir;
+-      
++      int err;
++
+       /* choose all parameters */
+       err = snd_pcm_hw_params_any(handle,params);
+       if (err < 0) {
+               printf("Access type not available for playback: %s\n", snd_strerror(err));
+               return err;
+       }
++      /* set the access type */
++      err = snd_pcm_hw_params_set_access(handle, params, alsa_access);
++      if (err < 0) {
++              printf("Sample format not available for playback: %s\n", snd_strerror(err));
++              return err;
++      }
+       /* set the sample format */
+       err = snd_pcm_hw_params_set_format(handle, params, alsa_format);
+       if (err < 0) {
+@@ -87,29 +92,38 @@
+               return err;
+       }
+       /* set the stream rate */
+-      err = snd_pcm_hw_params_set_rate_near(handle, params, rate, 0);
++      err = snd_pcm_hw_params_set_rate(handle, params, rate, 0);
+       if (err < 0) {
+               printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
+               return err;
+       }
+-      if (err != rate) {
+-              printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
+-              return -EINVAL;
+-      }
++      err = snd_pcm_hw_params_get_buffer_time_max(params, &buffer_time, NULL);
++        if (err < 0) {
++                printf("Unable to retrieve buffer time: %s\n", snd_strerror(err));
++                return err;
++        }
++        if (buffer_time > BUFFER_TIME_MAX)
++                buffer_time = BUFFER_TIME_MAX;
+       /* set buffer time */
+-      err = snd_pcm_hw_params_set_buffer_time_near(handle, params, buffer_time, &dir);
++      err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, 0);
+       if (err < 0) {
+               printf("Unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror(err));
+               return err;
+       }
+-      buffer_size = snd_pcm_hw_params_get_buffer_size(params);
++        if (period_time * 4 > buffer_time)
++                period_time = buffer_time / 4;
+       /* set period time */
+-      err = snd_pcm_hw_params_set_period_time_near(handle, params, period_time, &dir);
++      err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, NULL);
+       if (err < 0) {
+               printf("Unable to set period time %i for playback: %s\n", period_time, snd_strerror(err));
+               return err;
+       }
+-      period_size = snd_pcm_hw_params_get_period_size(params, &dir);
++        /* retrieve buffer size */
++      err = snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
++        if (err < 0) {
++                printf("Unable to retrieve buffer size: %s\n", snd_strerror(err));
++                return err;
++        }
+       /* write the parameters to device */
+       err = snd_pcm_hw_params(handle, params);
+       if (err < 0) {
+@@ -123,6 +137,7 @@
+ int set_swparams(snd_pcm_t *handle,
+                snd_pcm_sw_params_t *params)
+ {
++        unsigned int start_threshold;
+       int err;
+
+         /* get current swparams */
+@@ -136,13 +151,7 @@
+         if (err < 0) {
+                 printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
+                 return err;
+-                                                                                      }
+-        /* allow transfer when at least period_size samples can be processed */
+-        err = snd_pcm_sw_params_set_avail_min(handle, params, period_size);
+-        if (err < 0) {
+-                printf("Unable to set avail min for playback: %s\n", snd_strerror(err));
+-                return err;
+-                                                                                                      }
++      }
+         /* align all transfers to 1 samples */
+         err = snd_pcm_sw_params_set_xfer_align(handle, params, 1);
+         if (err < 0) {
+@@ -190,7 +199,7 @@
+       rate            = config->speed;
+
+       if ( bitdepth == 0 )
+-              config->precision = bitdepth = 32;
++              config->precision = bitdepth = 16;
+
+       switch (bitdepth)
+       {
+@@ -241,7 +250,7 @@
+               return -1;
+       }
+
+-      buf = malloc(buffer_size);
++      buf = malloc(buffer_size * sample_size);
+       if (buf == NULL) {
+               audio_error="unable to allocate output buffer table";
+               return -1;
+@@ -279,7 +288,7 @@
+ int play(struct audio_play *play)
+ {
+       int err, len;
+-      char *ptr;
++      unsigned char *ptr;
+
+       ptr = buf;
+       len = play->nsamples;
+
index 9ddcdd4d95ffe17d9aabf72053c6eb4a68a70feb..e31d39005e5ca2ca27bbe367545e1b0f27bf57f4 100644 (file)
@@ -9,12 +9,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=gammu
-PKG_VERSION:=1.36.5
+PKG_VERSION:=1.36.6
 PKG_RELEASE:=1
 
 PKG_SOURCE_URL:=http://dl.cihar.com/gammu/releases/
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
-PKG_MD5SUM:=b89d4d90137ccd6bf76a2c24fc3fc99f
+PKG_MD5SUM:=9047f0598602144a99153f5e61104529
 PKG_MAINTAINER:=Vitaly Protsko <villy@sft.ru>
 PKG_LICENCE:=GPL-2.0
 
diff --git a/utils/open2300/Makefile b/utils/open2300/Makefile
new file mode 100644 (file)
index 0000000..2354610
--- /dev/null
@@ -0,0 +1,67 @@
+# 
+# Copyright (C) 2010 segal.ubi.pt
+# Copyright (C) 2014 nunojpg@gmail.com
+# Copyright (C) 2015 dev@localnet.hu
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=open2300
+PKG_VERSION:=1.12
+PKG_RELEASE:=5
+PKG_LICENSE:=GPL-2.0+
+PKG_LICENSE_FILES:=COPYING
+
+PKG_SOURCE_PROTO:=svn
+PKG_SOURCE_URL:=http://www.lavrsen.dk/svn/open2300/trunk
+PKG_SOURCE_VERSION:=r12
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_CHECK_FORMAT_SECURITY:=0
+
+PKG_MAINTAINER:=Gabor SZOLLOSI <dev@localnet.hu>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/open2300
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=WS23XX weather station utilities
+  URL:=http://www.lavrsen.dk/foswiki/bin/view/Open2300
+endef
+
+define Package/open2300/description
+  This is an utility suite used to communicate with and collect data from a WS23XX wheather station.
+endef
+
+MAKE_FLAGS += \
+       CFLAGS="$(TARGET_CFLAGS) -DVERSION=\"$(PKG_VERSION)\""
+
+define Package/open2300/install
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin2300         $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/cw2300          $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/dump2300        $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/fetch2300       $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/histlog2300     $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/history2300     $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/interval2300    $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/light2300       $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/log2300         $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/minmax2300      $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/open2300        $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/wu2300          $(1)/usr/bin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/xml2300         $(1)/usr/bin/
+
+       $(INSTALL_DIR) $(1)/etc
+       $(INSTALL_DATA) ./files/open2300.conf $(1)/etc/
+
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib2300.so.1.11 $(1)/usr/lib/
+       ln -sf /usr/lib/lib2300.so.1.11 $(1)/usr/lib/lib2300.so
+endef
+
+$(eval $(call BuildPackage,open2300))
diff --git a/utils/open2300/files/open2300.conf b/utils/open2300/files/open2300.conf
new file mode 100644 (file)
index 0000000..6414b49
--- /dev/null
@@ -0,0 +1,65 @@
+# open2300.conf
+#
+# Configuration files for open2300 weather station tools
+#
+# Default locations in which the programs will search for this file: 
+# Programs search in this sequence:
+#  1. Path to config file including filename given as parameter (not supported by all tools)
+#  2. ./open2300.conf (current working directory)
+#  3. /jffs/etc/open2300.conf (typical DD-WRT location)
+#  4. /etc/open2300.conf (typical Linux location)
+#
+# All names are case sensitive!!!
+
+
+# Set to your serial port and time zone
+# For Windows use COM1, COM2, COM2 etc
+# For Linux use /dev/ttyS0, /dev/ttyS1 etc
+
+SERIAL_DEVICE                 /dev/tts/1  # /dev/ttyS0, /dev/ttyS1, COM1, COM2 etc
+TIMEZONE                      1           # Hours Relative to UTC. East is positive, west is negative
+
+
+# Units of measure (set them to your preference)
+# The units of measure are ignored by wu2300 and cw2300 because both requires specific units
+
+WIND_SPEED                    m/s         # select MPH (miles/hour), m/s, or km/h
+TEMPERATURE                   C           # Select C or F
+RAIN                          mm          # Select mm or IN
+PRESSURE                      hPa         # Select hPa, mb or INHG
+
+#### Citizens Weather variables (used only by cw2300)
+# Format for latitude is
+# [2 digit degrees][2 digit minutes].[2 decimals minutes - NOT seconds][N for north or S for south]
+# Format for longitude is
+# [3 digit degrees][2 digit minutes].[2 decimals minutes - NOT seconds][E for east or W for west]
+# Use leading zeros to get the format ####.##N (lat) and #####.##E (long)
+
+CITIZEN_WEATHER_ID            CW0000      # CW0000 should be replaced by HAM call or actual CW number
+CITIZEN_WEATHER_LATITUDE      5540.12N    # DDMM.mmN or S - example 55 deg, 40.23 minutes north
+CITIZEN_WEATHER_LONGITUDE     01224.60E   # DDDMM.mmE or W - example 12 deg, 24.60 minutes east
+
+APRS_SERVER   rotate.aprs.net   14580     # These are the APRS servers and ports for
+APRS_SERVER   first.aprs.net    14580     # Citizens Weather reporting.
+APRS_SERVER   second.aprs.net   14580     # They they are tried in the entered order
+APRS_SERVER   third.aprs.net    14580     # you may enter up to 5 alternate servers
+
+
+#### WEATHER UNDERGROUND variables (used only by wu2300)
+
+WEATHER_UNDERGROUND_ID        WUID        # ID received from Weather Underground
+WEATHER_UNDERGROUND_PASSWORD  WUPASSWORD  # Password for Weather Underground
+
+
+### MYSQL Settings (only used by mysql2300)
+
+#MYSQL_HOST              localhost         # Localhost or IP address/host name
+#MYSQL_USERNAME          open2300          # Name of the MySQL user that has access to the database
+#MYSQL_PASSWORD          mysql2300         # Password for the MySQL user
+#MYSQL_DATABASE          open2300          # Named of your database
+#MYSQL_PORT              0                 # TCP/IP Port number. Zero means default
+
+#PGSQL_CONNECT         hostaddr='127.0.0.1'dbname='open2300'user='postgres'password='sql' # Connection string
+#PGSQL_TABLE           weather           # Table name
+#PGSQL_STATION         open2300          # Unique station id
diff --git a/utils/open2300/patches/001-crosscompile.patch b/utils/open2300/patches/001-crosscompile.patch
new file mode 100644 (file)
index 0000000..0953047
--- /dev/null
@@ -0,0 +1,139 @@
+--- a/Makefile
++++ b/Makefile
+@@ -15,87 +15,82 @@
+ prefix = /usr/local
+ exec_prefix = ${prefix}
+ bindir = ${exec_prefix}/bin
++libdir = ${prefix}/lib
+ #########################################
+ CC  = gcc
+-OBJ = open2300.o rw2300.o linux2300.o win2300.o
+-LOGOBJ = log2300.o rw2300.o linux2300.o win2300.o
+-FETCHOBJ = fetch2300.o rw2300.o linux2300.o win2300.o
+-WUOBJ = wu2300.o rw2300.o linux2300.o win2300.o
+-CWOBJ = cw2300.o rw2300.o linux2300.o win2300.o
+-DUMPOBJ = dump2300.o rw2300.o linux2300.o win2300.o
+-HISTOBJ = history2300.o rw2300.o linux2300.o win2300.o
+-HISTLOGOBJ = histlog2300.o rw2300.o linux2300.o win2300.o
+-DUMPBINOBJ = bin2300.o rw2300.o linux2300.o win2300.o
+-XMLOBJ = xml2300.o rw2300.o linux2300.o win2300.o
+-PGSQLOBJ = pgsql2300.o rw2300.o linux2300.o win2300.o
+-LIGHTOBJ = light2300.o rw2300.o linux2300.o win2300.o
+-INTERVALOBJ = interval2300.o rw2300.o linux2300.o win2300.o
+-MINMAXOBJ = minmax2300.o rw2300.o linux2300.o win2300.o
+-MYSQLHISTLOGOBJ = mysqlhistlog2300.o rw2300.o linux2300.o win2300.o
++LIB = lib2300
++LIB_C = rw2300.c linux2300.c
++LIBOBJ = rw2300.o linux2300.o
+ VERSION = 1.11
+ CFLAGS = -Wall -O3 -DVERSION=\"$(VERSION)\"
+-CC_LDFLAGS = -lm
+-CC_WINFLAG = 
+-# For Windows - comment the two line above and un-comment the two lines below.
+-#CC_LDFLAGS = -lm -lwsock32
+-#CC_WINFLAG = -mwindows
++CC_LDFLAGS = -L. -lm -l2300
++LFLAGS = -shared -Wl,-soname
+ INSTALL = install
++MAKE_EXEC = $(CC) $(CFLAGS) $@.c -o $@ $(CC_LDFLAGS)
+ ####### Build rules
+-all: open2300 dump2300 log2300 fetch2300 wu2300 cw2300 history2300 histlog2300 bin2300 xml2300 light2300 interval2300 minmax2300 mysql2300 mysqlhistlog2300
++all: open2300 dump2300 log2300 fetch2300 wu2300 cw2300 history2300 histlog2300 bin2300 xml2300 light2300 interval2300 minmax2300 #mysql2300 mysqlhistlog2300
+-open2300 : $(OBJ)
+-      $(CC) $(CFLAGS) -o $@ $(OBJ) $(CC_LDFLAGS)
+-      
+-dump2300 : $(DUMPOBJ)
+-      $(CC) $(CFLAGS) -o $@ $(DUMPOBJ) $(CC_LDFLAGS)
++lib2300 :
++      $(CC) -c -fPIC $(CFLAGS) $(LIB_C)
++      $(CC) $(LFLAGS),$@.so -o $@.so.$(VERSION) $(LIBOBJ)
++      ln -sf $@.so.$(VERSION) $@.so
++
++open2300 : $(LIB)
++      $(MAKE_EXEC)
+       
+-log2300 : $(LOGOBJ)
+-      $(CC) $(CFLAGS) -o $@ $(LOGOBJ) $(CC_LDFLAGS) $(CC_WINFLAG)
++dump2300 : $(LIB)
++      $(MAKE_EXEC)
+       
+-fetch2300 : $(FETCHOBJ)
+-      $(CC) $(CFLAGS) -o $@ $(FETCHOBJ) $(CC_LDFLAGS)
++log2300 : $(LIB)
++      $(MAKE_EXEC)
+       
+-wu2300 : $(WUOBJ)
+-      $(CC) $(CFLAGS) -o $@ $(WUOBJ) $(CC_LDFLAGS) $(CC_WINFLAG)
++fetch2300 : $(LIB)
++      $(MAKE_EXEC)
++
++srv2300 : $(LIB)
++      $(MAKE_EXEC)
++
++wu2300 : $(LIB)
++      $(MAKE_EXEC)
+       
+-cw2300 : $(CWOBJ)
+-      $(CC) $(CFLAGS) -o $@ $(CWOBJ) $(CC_LDFLAGS) $(CC_WINFLAG)
++cw2300 : $(LIB)
++      $(MAKE_EXEC)
+-history2300 : $(HISTOBJ)
+-      $(CC) $(CFLAGS) -o $@ $(HISTOBJ) $(CC_LDFLAGS)
++history2300 : $(LIB)
++      $(MAKE_EXEC)
+       
+-histlog2300 : $(HISTLOGOBJ)
+-      $(CC) $(CFLAGS) -o $@ $(HISTLOGOBJ) $(CC_LDFLAGS) $(CC_WINFLAG)
++histlog2300 : $(LIB)
++      $(MAKE_EXEC)
+       
+-bin2300 : $(DUMPBINOBJ)
+-      $(CC) $(CFLAGS) -o $@ $(DUMPBINOBJ) $(CC_LDFLAGS)
++bin2300 : $(LIB)
++      $(MAKE_EXEC)
+-xml2300 : $(XMLOBJ)
+-      $(CC) $(CFLAGS) -o $@ $(XMLOBJ) $(CC_LDFLAGS) $(CC_WINFLAG)
++xml2300 : $(LIB)
++      $(MAKE_EXEC)
+-mysql2300:
+-      $(CC) $(CFLAGS) -o mysql2300 mysql2300.c rw2300.c linux2300.c $(CC_LDFLAGS) $(CC_WINFLAG) -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient
++mysql2300: $(LIB)
++      $(CC) $(CFLAGS) $@.c -o $@ -I/usr/include/mysql -L/usr/lib/mysql $(CC_LDFLAGS) -lmysqlclient
+-pgsql2300: $(PGSQLOBJ)
+-      $(CC) $(CFLAGS) -o $@ $(PGSQLOBJ) $(CC_LDFLAGS) $(CC_WINFLAG) -I/usr/include/pgsql -L/usr/lib/pgsql -lpq
++pgsql2300: $(LIB)
++      $(CC) $(CFLAGS) $@.c -o $@ -I/usr/include/pgsql -L/usr/lib/pgsql $(CC_LDFLAGS) -lpq
+-light2300: $(LIGHTOBJ)
+-      $(CC) $(CFLAGS) -o $@ $(LIGHTOBJ) $(CC_LDFLAGS)
++light2300: $(LIB)
++      $(MAKE_EXEC)
+       
+-interval2300: $(INTERVALOBJ)
+-      $(CC) $(CFLAGS) -o $@ $(INTERVALOBJ) $(CC_LDFLAGS)
++interval2300: $(LIB)
++      $(MAKE_EXEC)
+       
+-minmax2300: $(MINMAXOBJ)
+-      $(CC) $(CFLAGS) -o $@ $(MINMAXOBJ) $(CC_LDFLAGS) $(CC_WINFLAG)
++minmax2300: $(LIB)
++      $(MAKE_EXEC)
+       
+-mysqlhistlog2300 :
+-      $(CC) $(CFLAGS) -o mysqlhistlog2300 mysqlhistlog2300.c rw2300.c linux2300.c $(CC_LDFLAGS) $(CC_WINFLAG) -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient
++mysqlhistlog2300 : $(LIB)
++      $(CC) $(CFLAGS) $@.c -o $@ -I/usr/include/mysql -L/usr/lib/mysql $(CC_LDFLAGS) -lmysqlclient
+ install:
diff --git a/utils/swig/Makefile b/utils/swig/Makefile
new file mode 100644 (file)
index 0000000..7b9c4f0
--- /dev/null
@@ -0,0 +1,39 @@
+# 
+# Copyright (C) 2006-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=swig
+PKG_VERSION:=3.0.7
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/$(PKG_NAME)
+PKG_MD5SUM:=7fff46c84b8c630ede5b0f0827e3d90a
+PKG_INSTALL:=1
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=GPL-3.0
+PKG_LICENSE_FILE:=LICENSE
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/swig
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=swig binding generator
+  BUILDONLY:=1
+endef
+
+HOST_CONFIGURE_ARGS+= \
+       --without-pcre
+
+define Package/swig/description
+  tool that generates bindings for various languages
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,swig))
diff --git a/utils/yunbridge/Makefile b/utils/yunbridge/Makefile
new file mode 100644 (file)
index 0000000..ae49232
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2006-2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=yunbridge
+PKG_VERSION:=160
+
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/arduino/YunBridge.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=f2042052115e71ad2c91f77e78d21db8275fcdd6
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/yunbridge
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Arduino YUN bridge library
+  URL:=http://arduino.cc/
+  DEPENDS:=+python
+endef
+
+define Package/yunbridge/description
+  Arduino YUN bridge library
+endef
+
+define Build/Compile
+       true
+endef
+
+define Package/yunbridge/install
+       mkdir -p $(1)/usr/lib/python2.7/bridge
+       $(CP) $(PKG_BUILD_DIR)/bridge/*.py $(1)/usr/lib/python2.7/bridge/
+       $(CP) ./files/* $(1)
+endef
+
+$(eval $(call BuildPackage,yunbridge))
diff --git a/utils/yunbridge/files/etc/config/yunbridge b/utils/yunbridge/files/etc/config/yunbridge
new file mode 100644 (file)
index 0000000..fe8dd28
--- /dev/null
@@ -0,0 +1,6 @@
+config bridge config
+       option socket_timeout 5
+       option secure_rest_api false
+
+       # remove this line to activae the yunbridge
+       option disabled 1
diff --git a/utils/yunbridge/files/etc/init.d/yunbridge b/utils/yunbridge/files/etc/init.d/yunbridge
new file mode 100755 (executable)
index 0000000..4b48220
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2013 OpenWrt.org
+
+# start after and stop before networking
+START=20
+STOP=89
+
+USE_PROCD=1
+
+service_triggers()
+{
+       procd_add_reload_trigger "yunbridge"
+}
+
+start_service()
+{
+       [ "$(uci -q get yunbridge.config.disabled)" = "1" ] && return 0
+       procd_open_instance
+       procd_set_param command "/sbin/yunbridge"
+       procd_set_param respawn
+       procd_close_instance
+}
diff --git a/utils/yunbridge/files/sbin/yunbridge b/utils/yunbridge/files/sbin/yunbridge
new file mode 100755 (executable)
index 0000000..c8e4812
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+stty -F /dev/ttyS0 2500000 clocal cread cs8 -cstopb -parenb
+exec < /dev/ttyS0
+exec > /dev/ttyS0
+exec 2> /dev/ttyS0
+askfirst bin/ash --login
diff --git a/utils/yunbridge/files/usr/bin/pretty-wifi-info.lua b/utils/yunbridge/files/usr/bin/pretty-wifi-info.lua
new file mode 100755 (executable)
index 0000000..d91817a
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/lua
+
+local function get_basic_net_info(network, iface, accumulator)
+  local net = network:get_network(iface)
+  local device = net and net:get_interface()
+
+  if device then
+    accumulator["uptime"] = net:uptime()
+    accumulator["iface"] = device:name()
+    accumulator["mac"] = device:mac()
+    accumulator["rx_bytes"] = device:rx_bytes()
+    accumulator["tx_bytes"] = device:tx_bytes()
+    accumulator["ipaddrs"] = {}
+
+    for _, ipaddr in ipairs(device:ipaddrs()) do
+      accumulator.ipaddrs[#accumulator.ipaddrs + 1] = {
+        addr = ipaddr:host():string(),
+        netmask = ipaddr:mask():string()
+      }
+    end
+  end
+end
+
+local function get_wifi_info(network, iface, accumulator)
+  local net = network:get_wifinet(iface)
+
+  if net then
+    local dev = net:get_device()
+    if dev then
+      accumulator["mode"] = net:active_mode()
+      accumulator["ssid"] = net:active_ssid()
+      accumulator["encryption"] = net:active_encryption()
+      accumulator["quality"] = net:signal_percent()
+    end
+  end
+end
+
+local function collect_wifi_info()
+  local network = require"luci.model.network".init()
+  local accumulator = {}
+  get_basic_net_info(network, "lan", accumulator)
+  get_wifi_info(network, "wlan0", accumulator)
+  return accumulator
+end
+
+local info = collect_wifi_info()
+
+print("Current WiFi configuration")
+if info.ssid then
+  print("SSID: " .. info.ssid)
+end
+if info.mode then
+  print("Mode: " .. info.mode)
+end
+if info.quality then
+  print("Signal: " .. info.quality .. "%")
+end
+if info.encryption then
+  print("Encryption method: " .. info.encryption)
+end
+if info.iface then
+  print("Interface name: " .. info.iface)
+end
+if info.uptime then
+  print("Active for: " .. math.floor(info.uptime / 60) .. " minutes")
+end
+if #info.ipaddrs > 0 then
+  print("IP address: " .. info.ipaddrs[1].addr .. "/" .. info.ipaddrs[1].netmask)
+end
+if info.mac then
+  print("MAC address: " .. info.mac)
+end
+if info.rx_bytes and info.tx_bytes then
+  print("RX/TX: " .. math.floor(info.rx_bytes / 1024) .. "/" .. math.floor(info.tx_bytes / 1024) .. " KBs")
+end
diff --git a/utils/yunbridge/files/usr/lib/lua/luci/controller/arduino/index.lua b/utils/yunbridge/files/usr/lib/lua/luci/controller/arduino/index.lua
new file mode 100644 (file)
index 0000000..8d3b7eb
--- /dev/null
@@ -0,0 +1,414 @@
+--[[
+This file is part of YunWebUI.
+
+YunWebUI is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+As a special exception, you may use this file as part of a free software
+library without restriction.  Specifically, if other files instantiate
+templates or use macros or inline functions from this file, or you compile
+this file and link it with other files to produce an executable, this
+file does not by itself cause the resulting executable to be covered by
+the GNU General Public License.  This exception does not however
+invalidate any other reasons why the executable file might be covered by
+the GNU General Public License.
+
+Copyright 2013 Arduino LLC (http://www.arduino.cc/)
+]]
+
+module("luci.controller.arduino.index", package.seeall)
+
+local function not_nil_or_empty(value)
+  return value and value ~= ""
+end
+
+local function get_first(cursor, config, type, option)
+  return cursor:get_first(config, type, option)
+end
+
+local function set_first(cursor, config, type, option, value)
+  cursor:foreach(config, type, function(s)
+    if s[".type"] == type then
+      cursor:set(config, s[".name"], option, value)
+    end
+  end)
+end
+
+
+local function to_key_value(s)
+  local parts = luci.util.split(s, ":")
+  parts[1] = luci.util.trim(parts[1])
+  parts[2] = luci.util.trim(parts[2])
+  return parts[1], parts[2]
+end
+
+function http_error(code, text)
+  luci.http.prepare_content("text/plain")
+  luci.http.status(code)
+  if text then
+    luci.http.write(text)
+  end
+end
+
+function index()
+  function luci.dispatcher.authenticator.arduinoauth(validator, accs, default)
+    require("luci.controller.arduino.index")
+
+    local user = luci.http.formvalue("username")
+    local pass = luci.http.formvalue("password")
+    local basic_auth = luci.http.getenv("HTTP_AUTHORIZATION")
+
+    if user and validator(user, pass) then
+      return user
+    end
+
+    if basic_auth and basic_auth ~= "" then
+      local decoded_basic_auth = nixio.bin.b64decode(string.sub(basic_auth, 7))
+      user = string.sub(decoded_basic_auth, 0, string.find(decoded_basic_auth, ":") - 1)
+      pass = string.sub(decoded_basic_auth, string.find(decoded_basic_auth, ":") + 1)
+    end
+
+    if user then
+      if #pass ~= 64 and validator(user, pass) then
+        return user
+      elseif #pass == 64 then
+        local uci = luci.model.uci.cursor()
+        uci:load("yunbridge")
+        local stored_encrypted_pass = uci:get_first("yunbridge", "bridge", "password")
+        if pass == stored_encrypted_pass then
+          return user
+        end
+      end
+    end
+
+    luci.http.header("WWW-Authenticate", "Basic realm=\"yunbridge\"")
+    luci.http.status(401)
+
+    return false
+  end
+
+  local function make_entry(path, target, title, order)
+    local page = entry(path, target, title, order)
+    page.leaf = true
+    return page
+  end
+
+  -- web panel
+  local webpanel = entry({ "webpanel" }, alias("webpanel", "go_to_homepage"), _("%s Web Panel") % luci.sys.hostname(), 10)
+  webpanel.sysauth = "root"
+  webpanel.sysauth_authenticator = "arduinoauth"
+
+  make_entry({ "webpanel", "go_to_homepage" }, call("go_to_homepage"), nil)
+
+  --api security level
+  local uci = luci.model.uci.cursor()
+  uci:load("yunbridge")
+  local secure_rest_api = uci:get_first("yunbridge", "bridge", "secure_rest_api")
+  local rest_api_sysauth = false
+  if secure_rest_api == "true" then
+    rest_api_sysauth = webpanel.sysauth
+  end
+
+  --storage api
+  local data_api = node("data")
+  data_api.sysauth = rest_api_sysauth
+  data_api.sysauth_authenticator = webpanel.sysauth_authenticator
+  make_entry({ "data", "get" }, call("storage_send_request"), nil).sysauth = rest_api_sysauth
+  make_entry({ "data", "put" }, call("storage_send_request"), nil).sysauth = rest_api_sysauth
+  make_entry({ "data", "delete" }, call("storage_send_request"), nil).sysauth = rest_api_sysauth
+  local mailbox_api = node("mailbox")
+  mailbox_api.sysauth = rest_api_sysauth
+  mailbox_api.sysauth_authenticator = webpanel.sysauth_authenticator
+  make_entry({ "mailbox" }, call("build_bridge_mailbox_request"), nil).sysauth = rest_api_sysauth
+
+  --plain socket endpoint
+  local plain_socket_endpoint = make_entry({ "arduino" }, call("board_plain_socket"), nil)
+  plain_socket_endpoint.sysauth = rest_api_sysauth
+  plain_socket_endpoint.sysauth_authenticator = webpanel.sysauth_authenticator
+end
+
+function go_to_homepage()
+  luci.http.redirect("/index.html")
+end
+
+local function build_bridge_request(command, params)
+
+  local bridge_request = {
+    command = command
+  }
+
+  if command == "raw" then
+    params = table.concat(params, "/")
+    if not_nil_or_empty(params) then
+      bridge_request["data"] = params
+    end
+    return bridge_request
+  end
+
+  if command == "get" then
+    if not_nil_or_empty(params[1]) then
+      bridge_request["key"] = params[1]
+    end
+    return bridge_request
+  end
+
+  if command == "put" and not_nil_or_empty(params[1]) and params[2] then
+    bridge_request["key"] = params[1]
+    bridge_request["value"] = params[2]
+    return bridge_request
+  end
+
+  if command == "delete" and not_nil_or_empty(params[1]) then
+    bridge_request["key"] = params[1]
+    return bridge_request
+  end
+
+  return nil
+end
+
+local function extract_jsonp_param(query_string)
+  if not not_nil_or_empty(query_string) then
+    return nil
+  end
+
+  local qs_parts = string.split(query_string, "&")
+  for idx, value in ipairs(qs_parts) do
+    if string.find(value, "jsonp") == 1 or string.find(value, "callback") == 1 then
+      return string.sub(value, string.find(value, "=") + 1)
+    end
+  end
+end
+
+local function parts_after(url_part)
+  local url = luci.http.getenv("PATH_INFO")
+  local url_after_part = string.find(url, "/", string.find(url, url_part) + 1)
+  if not url_after_part then
+    return {}
+  end
+  return luci.util.split(string.sub(url, url_after_part + 1), "/")
+end
+
+function storage_send_request()
+  local method = luci.http.getenv("REQUEST_METHOD")
+  local jsonp_callback = extract_jsonp_param(luci.http.getenv("QUERY_STRING"))
+  local parts = parts_after("data")
+  local command = parts[1]
+  if not command or command == "" then
+    luci.http.status(404)
+    return
+  end
+  local params = {}
+  for idx, param in ipairs(parts) do
+    if idx > 1 and not_nil_or_empty(param) then
+      table.insert(params, param)
+    end
+  end
+
+  -- TODO check method?
+  local bridge_request = build_bridge_request(command, params)
+  if not bridge_request then
+    luci.http.status(403)
+    return
+  end
+
+  local uci = luci.model.uci.cursor()
+  uci:load("yunbridge")
+  local socket_timeout = uci:get_first("yunbridge", "bridge", "socket_timeout", 5)
+
+  local sock, code, msg = nixio.connect("127.0.0.1", 5700)
+  if not sock then
+    code = code or ""
+    msg = msg or ""
+    http_error(500, "nil socket, " .. code .. " " .. msg)
+    return
+  end
+
+  sock:setopt("socket", "sndtimeo", socket_timeout)
+  sock:setopt("socket", "rcvtimeo", socket_timeout)
+  sock:setopt("tcp", "nodelay", 1)
+
+  local json = require("luci.json")
+
+  sock:write(json.encode(bridge_request))
+  sock:writeall("\n")
+
+  local response_text = {}
+  while true do
+    local bytes = sock:recv(4096)
+    if bytes and #bytes > 0 then
+      table.insert(response_text, bytes)
+    end
+
+    local json_response = json.decode(table.concat(response_text))
+    if json_response then
+      sock:close()
+      luci.http.status(200)
+      if jsonp_callback then
+        luci.http.prepare_content("application/javascript")
+        luci.http.write(jsonp_callback)
+        luci.http.write("(")
+        luci.http.write_json(json_response)
+        luci.http.write(");")
+      else
+        luci.http.prepare_content("application/json")
+        luci.http.write(json.encode(json_response))
+      end
+      return
+    end
+
+    if not bytes or #response_text == 0 then
+      sock:close()
+      http_error(500, "Empty response")
+      return
+    end
+  end
+
+  sock:close()
+end
+
+function board_plain_socket()
+  local function send_response(response_text, jsonp_callback)
+    if not response_text then
+      luci.http.status(500)
+      return
+    end
+
+    local rows = luci.util.split(response_text, "\r\n")
+    if #rows == 1 or string.find(rows[1], "Status") ~= 1 then
+      luci.http.prepare_content("text/plain")
+      luci.http.status(200)
+      luci.http.write(response_text)
+      return
+    end
+
+    local body_start_at_idx = -1
+    local content_type = "text/plain"
+    for idx, row in ipairs(rows) do
+      if row == "" then
+        body_start_at_idx = idx
+        break
+      end
+
+      local key, value = to_key_value(row)
+      if string.lower(key) == "status" then
+        luci.http.status(tonumber(value))
+      elseif string.lower(key) == "content-type" then
+        content_type = value
+      else
+        luci.http.header(key, value)
+      end
+    end
+
+    local response_body = table.concat(rows, "\r\n", body_start_at_idx + 1)
+    if content_type == "application/json" and jsonp_callback then
+      local json = require("luci.json")
+      luci.http.prepare_content("application/javascript")
+      luci.http.write(jsonp_callback)
+      luci.http.write("(")
+      luci.http.write_json(json.decode(response_body))
+      luci.http.write(");")
+    else
+      luci.http.prepare_content(content_type)
+      luci.http.write(response_body)
+    end
+  end
+
+  local method = luci.http.getenv("REQUEST_METHOD")
+  local jsonp_callback = extract_jsonp_param(luci.http.getenv("QUERY_STRING"))
+  local parts = parts_after("arduino")
+  local params = {}
+  for idx, param in ipairs(parts) do
+    if not_nil_or_empty(param) then
+      table.insert(params, param)
+    end
+  end
+
+  if #params == 0 then
+    luci.http.status(404)
+    return
+  end
+
+  params = table.concat(params, "/")
+
+  local uci = luci.model.uci.cursor()
+  uci:load("yunbridge")
+  local socket_timeout = uci:get_first("yunbridge", "bridge", "socket_timeout", 5)
+
+  local sock, code, msg = nixio.connect("127.0.0.1", 5555)
+  if not sock then
+    code = code or ""
+    msg = msg or ""
+    http_error(500, "Could not connect to YunServer " .. code .. " " .. msg)
+    return
+  end
+
+  sock:setopt("socket", "sndtimeo", socket_timeout)
+  sock:setopt("socket", "rcvtimeo", socket_timeout)
+  sock:setopt("tcp", "nodelay", 1)
+
+  sock:write(params)
+  sock:writeall("\r\n")
+
+  local response_text = sock:readall()
+  sock:close()
+
+  send_response(response_text, jsonp_callback)
+end
+
+function build_bridge_mailbox_request()
+  local method = luci.http.getenv("REQUEST_METHOD")
+  local jsonp_callback = extract_jsonp_param(luci.http.getenv("QUERY_STRING"))
+  local parts = parts_after("mailbox")
+  local params = {}
+  for idx, param in ipairs(parts) do
+    if not_nil_or_empty(param) then
+      table.insert(params, param)
+    end
+  end
+
+  if #params == 0 then
+    luci.http.status(400)
+    return
+  end
+
+  local bridge_request = build_bridge_request("raw", params)
+  if not bridge_request then
+    luci.http.status(403)
+    return
+  end
+
+  local uci = luci.model.uci.cursor()
+  uci:load("yunbridge")
+  local socket_timeout = uci:get_first("yunbridge", "bridge", "socket_timeout", 5)
+
+  local sock, code, msg = nixio.connect("127.0.0.1", 5700)
+  if not sock then
+    code = code or ""
+    msg = msg or ""
+    http_error(500, "nil socket, " .. code .. " " .. msg)
+    return
+  end
+
+  sock:setopt("socket", "sndtimeo", socket_timeout)
+  sock:setopt("socket", "rcvtimeo", socket_timeout)
+  sock:setopt("tcp", "nodelay", 1)
+
+  local json = require("luci.json")
+
+  sock:write(json.encode(bridge_request))
+  sock:writeall("\n")
+  sock:close()
+
+  luci.http.status(200)
+end
diff --git a/utils/yunbridge/files/usr/lib/lua/luci/sha256.lua b/utils/yunbridge/files/usr/lib/lua/luci/sha256.lua
new file mode 100644 (file)
index 0000000..b5e2dea
--- /dev/null
@@ -0,0 +1,199 @@
+--
+--  Code merged by gravityscore at http://pastebin.com/gsFrNjbt
+--
+--  Adaptation of the Secure Hashing Algorithm (SHA-244/256)
+--  Found Here: http://lua-users.org/wiki/SecureHashAlgorithm
+--  
+--  Using an adapted version of the bit library
+--  Found Here: https://bitbucket.org/Boolsheet/bslf/src/1ee664885805/bit.lua
+--  
+
+module("luci.sha256", package.seeall)
+
+local MOD = 2 ^ 32
+local MODM = MOD - 1
+
+local function memoize(f)
+  local mt = {}
+  local t = setmetatable({}, mt)
+  function mt:__index(k)
+    local v = f(k)
+    t[k] = v
+    return v
+  end
+
+  return t
+end
+
+local function make_bitop_uncached(t, m)
+  local function bitop(a, b)
+    local res, p = 0, 1
+    while a ~= 0 and b ~= 0 do
+      local am, bm = a % m, b % m
+      res = res + t[am][bm] * p
+      a = (a - am) / m
+      b = (b - bm) / m
+      p = p * m
+    end
+    res = res + (a + b) * p
+    return res
+  end
+
+  return bitop
+end
+
+local function make_bitop(t)
+  local op1 = make_bitop_uncached(t, 2 ^ 1)
+  local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end)
+  return make_bitop_uncached(op2, 2 ^ (t.n or 1))
+end
+
+local bxor1 = make_bitop({ [0] = { [0] = 0, [1] = 1 }, [1] = { [0] = 1, [1] = 0 }, n = 4 })
+
+local function bxor(a, b, c, ...)
+  local z = nil
+  if b then
+    a = a % MOD
+    b = b % MOD
+    z = bxor1(a, b)
+    if c then z = bxor(z, c, ...) end
+    return z
+  elseif a then return a % MOD
+  else return 0
+  end
+end
+
+local function band(a, b, c, ...)
+  local z
+  if b then
+    a = a % MOD
+    b = b % MOD
+    z = ((a + b) - bxor1(a, b)) / 2
+    if c then z = bit32_band(z, c, ...) end
+    return z
+  elseif a then return a % MOD
+  else return MODM
+  end
+end
+
+local function bnot(x) return (-1 - x) % MOD end
+
+local function rshift1(a, disp)
+  if disp < 0 then return lshift(a, -disp) end
+  return math.floor(a % 2 ^ 32 / 2 ^ disp)
+end
+
+local function rshift(x, disp)
+  if disp > 31 or disp < -31 then return 0 end
+  return rshift1(x % MOD, disp)
+end
+
+local function lshift(a, disp)
+  if disp < 0 then return rshift(a, -disp) end
+  return (a * 2 ^ disp) % 2 ^ 32
+end
+
+local function rrotate(x, disp)
+  x = x % MOD
+  disp = disp % 32
+  local low = band(x, 2 ^ disp - 1)
+  return rshift(x, disp) + lshift(low, 32 - disp)
+end
+
+local k = {
+  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
+}
+
+local function str2hexa(s)
+  return (string.gsub(s, ".", function(c) return string.format("%02x", string.byte(c)) end))
+end
+
+local function num2s(l, n)
+  local s = ""
+  for i = 1, n do
+    local rem = l % 256
+    s = string.char(rem) .. s
+    l = (l - rem) / 256
+  end
+  return s
+end
+
+local function s232num(s, i)
+  local n = 0
+  for i = i, i + 3 do n = n * 256 + string.byte(s, i) end
+  return n
+end
+
+local function preproc(msg, len)
+  local extra = 64 - ((len + 9) % 64)
+  len = num2s(8 * len, 8)
+  msg = msg .. "\128" .. string.rep("\0", extra) .. len
+  assert(#msg % 64 == 0)
+  return msg
+end
+
+local function initH256(H)
+  H[1] = 0x6a09e667
+  H[2] = 0xbb67ae85
+  H[3] = 0x3c6ef372
+  H[4] = 0xa54ff53a
+  H[5] = 0x510e527f
+  H[6] = 0x9b05688c
+  H[7] = 0x1f83d9ab
+  H[8] = 0x5be0cd19
+  return H
+end
+
+local function digestblock(msg, i, H)
+  local w = {}
+  for j = 1, 16 do w[j] = s232num(msg, i + (j - 1) * 4) end
+  for j = 17, 64 do
+    local v = w[j - 15]
+    local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))
+    v = w[j - 2]
+    w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))
+  end
+
+  local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]
+  for i = 1, 64 do
+    local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))
+    local maj = bxor(band(a, b), band(a, c), band(b, c))
+    local t2 = s0 + maj
+    local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))
+    local ch = bxor(band(e, f), band(bnot(e), g))
+    local t1 = h + s1 + ch + k[i] + w[i]
+    h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2
+  end
+
+  H[1] = band(H[1] + a)
+  H[2] = band(H[2] + b)
+  H[3] = band(H[3] + c)
+  H[4] = band(H[4] + d)
+  H[5] = band(H[5] + e)
+  H[6] = band(H[6] + f)
+  H[7] = band(H[7] + g)
+  H[8] = band(H[8] + h)
+end
+
+function sha256(msg)
+  msg = preproc(msg, #msg)
+  local H = initH256({})
+  for i = 1, #msg, 64 do digestblock(msg, i, H) end
+  return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..
+          num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))
+end
\ No newline at end of file
diff --git a/utils/yunbridge/patches/000-scripts.patch b/utils/yunbridge/patches/000-scripts.patch
new file mode 100644 (file)
index 0000000..46f21bd
--- /dev/null
@@ -0,0 +1,18 @@
+--- a/bridge/packet.py
++++ b/bridge/packet.py
+@@ -93,12 +93,12 @@
+     
+   def run(self, data):
+     if data[0] != 'X':
+-      call(['/usr/bin/blink-start', '100'])
++      #call(['/usr/bin/blink-start', '100'])
+       return chr(1)
+     if data[1:4] != '100':
+-      call(['/usr/bin/blink-start', '100'])
++      #call(['/usr/bin/blink-start', '100'])
+       return chr(2)
+-    call(['/usr/bin/blink-stop'])
++    #call(['/usr/bin/blink-stop'])
+     return chr(0) + '160' # send the actual bridge version
+     
+ class PacketReader: