[OpenWrt-Devel] [PATCH] ralink: fixbug for mt7530, unused vlan entry will take effect to other vlan.

2014-12-30 Thread xfguo
It will fail when you have an uci network config (swconfig part) like this:

```
config switch
option name 'switch0'
option reset '1'
option enable_vlan '1'

config switch_vlan
option device 'switch0'
option vlan '15'
option vid '1'
option ports '0 6t'

config switch_port
option name 'switch0'
option port '0'
option pvid '1'
```

It will be good until you run:

$ swconfig dev switch0 vlan 1 set vid 333

So it seems that when REG_ESW_VLAN_VAWD1_VALID is unset, it will still take
effect for VTU matching when two VTU entries have a same VID.

Signed-off-by: Xiongfei Guo 
---
 .../files/drivers/net/ethernet/ralink/mt7530.c | 26 ++
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c 
b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c
index 1352b25..27fc51a 100644
--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c
@@ -408,6 +408,22 @@ mt7530_apply_config(struct switch_dev *dev)
u8 etags = priv->vlan_entries[i].etags;
u32 val;
 
+
+   /* vlan port membership */
+   if (member)
+   mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 
REG_ESW_VLAN_VAWD1_IVL_MAC |
+   REG_ESW_VLAN_VAWD1_VTAG_EN | (member << 16) |
+   REG_ESW_VLAN_VAWD1_VALID);
+   else {
+   mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 0);
+
+   /* ignore vid (just set it to 0) when the ports is 
empty,
+* because even the REG_ESW_VLAN_VAWD1_VALID is set to 
disable,
+* it will still take effect to other vlan when they 
have
+* a same vid. */
+   vid = 0;
+   }
+
/* vid of vlan */
val = mt7530_r32(priv, REG_ESW_VLAN_VTIM(i));
if (i % 2 == 0) {
@@ -417,16 +433,8 @@ mt7530_apply_config(struct switch_dev *dev)
val &= 0xfff;
val |= (vid << 12);
}
-   mt7530_w32(priv, REG_ESW_VLAN_VTIM(i), val);
-
-   /* vlan port membership */
-   if (member)
-   mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 
REG_ESW_VLAN_VAWD1_IVL_MAC |
-   REG_ESW_VLAN_VAWD1_VTAG_EN | (member << 16) |
-   REG_ESW_VLAN_VAWD1_VALID);
-   else
-   mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 0);
 
+   mt7530_w32(priv, REG_ESW_VLAN_VTIM(i), val);
/* egress mode */
val = 0;
for (j = 0; j < MT7530_NUM_PORTS; j++) {
-- 
1.9.1
___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


[OpenWrt-Devel] [PATCH] BB: ralink/mt7530: fixbug: unused vlan entry will take effect to other vlan.

2014-12-18 Thread xfguo
It will fail when you have an uci network config like this:

```
config switch
option name 'switch0'
option reset '1'
option enable_vlan '1'

config switch_vlan
option device 'switch0'
option vlan '15'
option vid '1'
option ports '0 6t'

config switch_port
option name 'switch0'
option port '0'
option pvid '1'
```

It will be good until you run:

$ swconfig dev switch0 vlan 1 set vid 333

So it seems that when REG_ESW_VLAN_VAWD1_VALID is unset, it will still take
effect for VTU matching when two VTU entries have a same VID.

Signed-off-by: Xiongfei Guo 
---
 .../files/drivers/net/ethernet/ralink/mt7530.c | 26 ++
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c 
b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c
index 1352b25..27fc51a 100644
--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c
@@ -408,6 +408,22 @@ mt7530_apply_config(struct switch_dev *dev)
u8 etags = priv->vlan_entries[i].etags;
u32 val;
 
+
+   /* vlan port membership */
+   if (member)
+   mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 
REG_ESW_VLAN_VAWD1_IVL_MAC |
+   REG_ESW_VLAN_VAWD1_VTAG_EN | (member << 16) |
+   REG_ESW_VLAN_VAWD1_VALID);
+   else {
+   mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 0);
+
+   /* ignore vid (just set it to 0) when the ports is 
empty,
+* because even the REG_ESW_VLAN_VAWD1_VALID is set to 
disable,
+* it will still take effect to other vlan when they 
have
+* a same vid. */
+   vid = 0;
+   }
+
/* vid of vlan */
val = mt7530_r32(priv, REG_ESW_VLAN_VTIM(i));
if (i % 2 == 0) {
@@ -417,16 +433,8 @@ mt7530_apply_config(struct switch_dev *dev)
val &= 0xfff;
val |= (vid << 12);
}
-   mt7530_w32(priv, REG_ESW_VLAN_VTIM(i), val);
-
-   /* vlan port membership */
-   if (member)
-   mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 
REG_ESW_VLAN_VAWD1_IVL_MAC |
-   REG_ESW_VLAN_VAWD1_VTAG_EN | (member << 16) |
-   REG_ESW_VLAN_VAWD1_VALID);
-   else
-   mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 0);
 
+   mt7530_w32(priv, REG_ESW_VLAN_VTIM(i), val);
/* egress mode */
val = 0;
for (j = 0; j < MT7530_NUM_PORTS; j++) {
-- 
1.9.1
___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


[OpenWrt-Devel] [PATCH] [libubox] uloop: fixbug, 'end' is the keyword of Lua, use 'cancel' replace it.

2014-07-27 Thread xfguo
Signed-off-by: Xiongfei Guo 
---
 lua/uloop.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lua/uloop.c b/lua/uloop.c
index 4abc4c3..2a0a516 100644
--- a/lua/uloop.c
+++ b/lua/uloop.c
@@ -369,7 +369,7 @@ static luaL_reg uloop_func[] = {
{"timer", ul_timer},
{"process", ul_process},
{"fd_add", ul_ufd_add},
-   {"end", ul_end},
+   {"cancel", ul_end},
{NULL, NULL},
 };
 
-- 
1.9.1
___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


[OpenWrt-Devel] [PATCH] ramips: set default vid of each vlan, so it won't need be set explicitly.

2014-07-01 Thread xfguo
Signed-off-by: Xiongfei Guo 
---
 ...8-NET-MIPS-add-ralink-SoC-ethernet-driver.patch | 24 ++
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git 
a/target/linux/ramips/patches-3.10/0118-NET-MIPS-add-ralink-SoC-ethernet-driver.patch
 
b/target/linux/ramips/patches-3.10/0118-NET-MIPS-add-ralink-SoC-ethernet-driver.patch
index c5d6623..6eb624f 100644
--- 
a/target/linux/ramips/patches-3.10/0118-NET-MIPS-add-ralink-SoC-ethernet-driver.patch
+++ 
b/target/linux/ramips/patches-3.10/0118-NET-MIPS-add-ralink-SoC-ethernet-driver.patch
@@ -2814,7 +2814,7 @@ Signed-off-by: John Crispin 
 +#endif
 --- /dev/null
 +++ b/drivers/net/ethernet/ralink/mt7530.c
-@@ -0,0 +1,571 @@
+@@ -0,0 +1,579 @@
 +/*
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License
@@ -2912,15 +2912,15 @@ Signed-off-by: John Crispin 
 +  {
 +  .name = "w",
 +  .pvids = { 1, 1, 1, 1, 2, 1, 1 },
-+  .members = { 0x6f, 0x50 },
-+  .etags = { 0x40, 0x40 },
-+  .vids = { 1, 2 },
++  .members = { 0, 0x6f, 0x50 },
++  .etags = { 0, 0x40, 0x40 },
++  .vids = { 0, 1, 2 },
 +  }, {
 +  .name = "w",
 +  .pvids = { 2, 1, 1, 1, 1, 1, 1 },
-+  .members = { 0x7e, 0x41 },
-+  .etags = { 0x40, 0x40 },
-+  .vids = { 1, 2 },
++  .members = { 0, 0x7e, 0x41 },
++  .etags = { 0, 0x40, 0x40 },
++  .vids = { 0, 1, 2 },
 +  },
 +};
 +
@@ -2961,10 +2961,18 @@ Signed-off-by: John Crispin 
 +mt7530_reset_switch(struct switch_dev *dev)
 +{
 +  struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
++  int i;
 +
 +  memset(priv->port_entries, 0, sizeof(priv->port_entries));
 +  memset(priv->vlan_entries, 0, sizeof(priv->vlan_entries));
 +
++  /* set default vid of each vlan to the same number of vlan, so the vid
++   * won't need be set explicitly.
++   */
++  for (i = 0; i < MT7530_NUM_VLANS; i++) {
++  priv->vlan_entries[i].vid = i;
++  }
++
 +  return 0;
 +}
 +
@@ -3158,7 +3166,7 @@ Signed-off-by: John Crispin 
 +  vid = (u16)val->value.i;
 +
 +  if (vlan < 0 || vlan >= MT7530_NUM_VLANS)
-+  return -EINVAL;
++  return -EINVAL;
 +
 +  if (vid < MT7530_MIN_VID || vid > MT7530_MAX_VID)
 +  return -EINVAL;
-- 
1.9.1
___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


[OpenWrt-Devel] [PATCH] Update MT7530 switch driver.

2014-06-21 Thread xfguo
From: Xiongfei Guo 

- Support set VLAN ID of each vlan.
- Support untag feature.
- Replace register address with C MACRO.
- There are 8 ports for MT7530 actually.

Signed-off-by: Xiongfei Guo 
---
 ...8-NET-MIPS-add-ralink-SoC-ethernet-driver.patch | 268 ++---
 1 file changed, 186 insertions(+), 82 deletions(-)

diff --git 
a/target/linux/ramips/patches-3.10/0118-NET-MIPS-add-ralink-SoC-ethernet-driver.patch
 
b/target/linux/ramips/patches-3.10/0118-NET-MIPS-add-ralink-SoC-ethernet-driver.patch
index 75f78bf..c8ec17c 100644
--- 
a/target/linux/ramips/patches-3.10/0118-NET-MIPS-add-ralink-SoC-ethernet-driver.patch
+++ 
b/target/linux/ramips/patches-3.10/0118-NET-MIPS-add-ralink-SoC-ethernet-driver.patch
@@ -2814,7 +2814,7 @@ Signed-off-by: John Crispin 
 +#endif
 --- /dev/null
 +++ b/drivers/net/ethernet/ralink/mt7530.c
-@@ -0,0 +1,467 @@
+@@ -0,0 +1,571 @@
 +/*
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License
@@ -2851,25 +2851,45 @@ Signed-off-by: John Crispin 
 +#include "mt7530.h"
 +
 +#define MT7530_CPU_PORT   6
-+#define MT7530_NUM_PORTS  7
++#define MT7530_NUM_PORTS  8
 +#define MT7530_NUM_VLANS  16
-+#define MT7530_NUM_VIDS   16
++#define MT7530_MAX_VID4095
++#define MT7530_MIN_VID0
 +
-+#define REG_ESW_VLAN_VTCR 0x90
-+#define REG_ESW_VLAN_VAWD10x94
-+#define REG_ESW_VLAN_VAWD20x98
++/* registers */
++#define REG_ESW_VLAN_VTCR 0x90
++#define REG_ESW_VLAN_VAWD10x94
++#define REG_ESW_VLAN_VAWD20x98
++#define REG_ESW_VLAN_VTIM(x)  (0x100 + 4 * ((x) / 2))
++
++#define REG_ESW_VLAN_VAWD1_IVL_MACBIT(30)
++#define REG_ESW_VLAN_VAWD1_VTAG_ENBIT(28)
++#define REG_ESW_VLAN_VAWD1_VALID  BIT(0)
++
++/* vlan egress mode */
++enum {
++  ETAG_CTRL_UNTAG = 0,
++  ETAG_CTRL_TAG   = 2,
++  ETAG_CTRL_SWAP  = 1,
++  ETAG_CTRL_STACK = 3,
++};
 +
++#define REG_ESW_PORT_PCR(x)   (0x2004 | ((x) << 8))
++#define REG_ESW_PORT_PVC(x)   (0x2010 | ((x) << 8))
++#define REG_ESW_PORT_PPBV1(x) (0x2014 | ((x) << 8))
 +enum {
 +  /* Global attributes. */
 +  MT7530_ATTR_ENABLE_VLAN,
 +};
 +
-+struct mt7530_port {
++struct mt7530_port_entry {
 +  u16 pvid;
 +};
 +
-+struct mt7530_vlan {
-+  u8  ports;
++struct mt7530_vlan_entry {
++  u16 vid;
++  u8  member;
++  u8  etags;
 +};
 +
 +struct mt7530_priv {
@@ -2878,23 +2898,29 @@ Signed-off-by: John Crispin 
 +  struct switch_dev   swdev;
 +
 +  boolglobal_vlan_enable;
-+  struct mt7530_vlan  vlans[MT7530_NUM_VLANS];
-+  struct mt7530_port  ports[MT7530_NUM_PORTS];
++  struct mt7530_vlan_entryvlan_entries[MT7530_NUM_VLANS];
++  struct mt7530_port_entryport_entries[MT7530_NUM_PORTS];
 +};
 +
 +struct mt7530_mapping {
 +  char*name;
-+  u8  pvids[6];
-+  u8  vlans[8];
++  u16 pvids[MT7530_NUM_PORTS];
++  u8  members[MT7530_NUM_VLANS];
++  u8  etags[MT7530_NUM_VLANS];
++  u16 vids[MT7530_NUM_VLANS];
 +} mt7530_defaults[] = {
 +  {
 +  .name = "w",
-+  .pvids = { 1, 1, 1, 1, 2, 1 },
-+  .vlans = { 0, 0x6f, 0x50 },
++  .pvids = { 1, 1, 1, 1, 2, 1, 1 },
++  .members = { 0x6f, 0x50 },
++  .etags = { 0x40, 0x40 },
++  .vids = { 1, 2 },
 +  }, {
 +  .name = "w",
-+  .pvids = { 2, 1, 1, 1, 1, 1 },
-+  .vlans = { 0, 0x7e, 0x41 },
++  .pvids = { 2, 1, 1, 1, 1, 1, 1 },
++  .members = { 0x7e, 0x41 },
++  .etags = { 0x40, 0x40 },
++  .vids = { 1, 2 },
 +  },
 +};
 +
@@ -2921,10 +2947,14 @@ Signed-off-by: John Crispin 
 +
 +  mt7530->global_vlan_enable = 1;
 +
-+  for (i = 0; i < 6; i++)
-+  mt7530->ports[i].pvid = map->pvids[i];
-+  for (i = 0; i < 8; i++)
-+  mt7530->vlans[i].ports = map->vlans[i];
++  for (i = 0; i < MT7530_NUM_PORTS; i++)
++  mt7530->port_entries[i].pvid = map->pvids[i];
++
++  for (i = 0; i < MT7530_NUM_VLANS; i++) {
++  mt7530->vlan_entries[i].member = map->members[i];
++  mt7530->vlan_entries[i].etags = map->etags[i];
++  mt7530->vlan_entries[i].vid = map->vids[i];
++  }
 +}
 +
 +static int
@@ -2932,8 +2962,8 @@ Signed-off-by: John Crispin 
 +{
 +  struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
 +
-+  memset(priv->ports, 0, sizeof(priv->ports));
-+  memset(priv->vlans, 0, sizeof(priv->vlans));
++  memset(priv->port_entries, 0, sizeof(priv->port_entries));
++  memset(priv->vlan_entries, 0, sizeof(priv->vlan_entries));
 +
 +  return 0;
 +}
@@ -2965,6 +2995,7 @@ Signed-off-by: John Crispin 
 +static u32
 +mt7530_r32(struct mt7530_priv *priv, 

[OpenWrt-Devel] [PATCH 1/5] Fix stack overflow bug of uloop lua binding.

2014-06-20 Thread xfguo
The static variable `state` in `lua/uloop.c` should be clean after every 
callback.

Signed-off-by: Xiongfei(Alex) Guo 
---
 lua/uloop.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lua/uloop.c b/lua/uloop.c
index 51f53c2..5922e04 100644
--- a/lua/uloop.c
+++ b/lua/uloop.c
@@ -43,6 +43,7 @@ static void ul_timer_cb(struct uloop_timeout *t)
 
lua_getglobal(state, "__uloop_cb");
lua_rawgeti(state, -1, tout->r);
+   lua_remove(state, -2);
lua_call(state, 0, 0);
 }
 
@@ -133,6 +134,7 @@ static void ul_process_cb(struct uloop_process *p, int ret)
lua_getglobal(state, "__uloop_cb");
lua_rawgeti(state, -1, proc->r);
luaL_unref(state, -2, proc->r);
+   lua_remove(state, -2);
lua_pushinteger(state, ret >> 8);
lua_call(state, 1, 0);
 }
-- 
1.9.1
___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


[OpenWrt-Devel] [PATCH 2/5] Added fd_add method for uloop lua binding.

2014-06-20 Thread xfguo
Use uloop.fd_add like this:

local socket = require "socket"

udp = socket.udp()

uloop.fd_add(
udp, -- socket
function( -- callback function
ufd,-- socket object when register the fd
events  -- uloop events. eg. uloop.ULOOP_READ .
)
local words, msg_or_ip, port_or_nil = ufd:receivefrom()
print('Recv UDP packet from '..msg_or_ip..':'..port_or_nil..' : 
'..words)
end,
uloop.ULOOP_READ -- event you want to listen
)

The `examples/uloop-example.lua` show an example of this work.

Signed-off-by: Xiongfei(Alex) Guo 
---
 examples/uloop-example.lua |  23 ++
 lua/uloop.c| 111 +
 2 files changed, 134 insertions(+)

diff --git a/examples/uloop-example.lua b/examples/uloop-example.lua
index 2da6ebd..ba34ec5 100755
--- a/examples/uloop-example.lua
+++ b/examples/uloop-example.lua
@@ -1,8 +1,14 @@
 #!/usr/bin/env lua
 
+local socket = require "socket"
+
 local uloop = require("uloop")
 uloop.init()
 
+local udp = socket.udp()
+udp:settimeout(0)
+udp:setsockname('*', 8080)
+
 -- timer example 1
 local timer
 function t()
@@ -40,5 +46,22 @@ uloop.timer(
end, 2000
 )
 
+uloop.fd_add(udp, function(ufd, events)
+   local words, msg_or_ip, port_or_nil = ufd:receivefrom()
+   print('Recv UDP packet from '..msg_or_ip..':'..port_or_nil..' : 
'..words)
+end, uloop.ULOOP_READ)
+
+udp_send_timer = uloop.timer(
+   function()
+   local s = socket.udp()
+   local words = 'Hello!'
+   print('Send UDP packet to 127.0.0.1:8080 :'..words)
+   s:sendto(words, '127.0.0.1', 8080)
+   s:close()
+
+   udp_send_timer:set(1000)
+   end, 3000
+)
+
 uloop.run()
 
diff --git a/lua/uloop.c b/lua/uloop.c
index 5922e04..c71d537 100644
--- a/lua/uloop.c
+++ b/lua/uloop.c
@@ -25,6 +25,12 @@
 #include "../uloop.h"
 #include "../list.h"
 
+struct lua_uloop_fd {
+   struct uloop_fd fd;
+   int r;
+   int fd_r;
+};
+
 struct lua_uloop_timeout {
struct uloop_timeout t;
int r;
@@ -44,7 +50,9 @@ static void ul_timer_cb(struct uloop_timeout *t)
lua_getglobal(state, "__uloop_cb");
lua_rawgeti(state, -1, tout->r);
lua_remove(state, -2);
+
lua_call(state, 0, 0);
+
 }
 
 static int ul_timer_set(lua_State *L)
@@ -127,12 +135,95 @@ static int ul_timer(lua_State *L)
return 1;
 }
 
+static void ul_ufd_cb(struct uloop_fd *fd, unsigned int events)
+{
+   struct lua_uloop_fd *ufd = container_of(fd, struct lua_uloop_fd, fd);
+
+   lua_getglobal(state, "__uloop_cb");
+   lua_rawgeti(state, -1, ufd->r);
+   lua_remove(state, -2);
+
+   /* push fd object */
+   lua_getglobal(state, "__uloop_fds");
+   lua_rawgeti(state, -1, ufd->fd_r);
+   lua_remove(state, -2);
+
+   /* push events */
+   lua_pushinteger(state, events);
+
+   lua_call(state, 2, 0);
+}
+
+
+static int get_sock_fd(lua_State* L, int idx) {
+   int fd;
+   if(lua_isnumber(L, idx)) {
+   fd = lua_tonumber(L, idx);
+   } else {
+   luaL_checktype(L, idx, LUA_TUSERDATA);
+   lua_getfield(L, idx, "getfd");
+   if(lua_isnil(L, -1))
+   return luaL_error(L, "socket type missing 'getfd' 
method");
+   lua_pushvalue(L, idx - 1);
+   lua_call(L, 1, 1);
+   fd = lua_tointeger(L, -1);
+   lua_pop(L, 1);
+   }
+   return fd;
+}
+
+static int ul_ufd_add(lua_State *L)
+{
+   struct lua_uloop_fd *ufd;
+   int fd = 0;
+   unsigned int flags = 0;
+   int ref;
+   int fd_ref;
+
+   if (lua_isnumber(L, -1)) {
+   flags = lua_tointeger(L, -1);
+   lua_pop(L, 1);
+   }
+
+   if (!lua_isfunction(L, -1)) {
+   lua_pushstring(L, "invalid arg list");
+   lua_error(L);
+
+   return 0;
+   }
+
+   fd = get_sock_fd(L, -2);
+
+   lua_getglobal(L, "__uloop_cb");
+   lua_pushvalue(L, -2);
+   ref = luaL_ref(L, -2);
+   lua_pop(L, 1);
+
+   lua_getglobal(L, "__uloop_fds");
+   lua_pushvalue(L, -3);
+   fd_ref = luaL_ref(L, -2);
+   lua_pop(L, 1);
+
+   ufd = lua_newuserdata(L, sizeof(*ufd));
+   memset(ufd, 0, sizeof(*ufd));
+
+   ufd->r = ref;
+   ufd->fd.fd = fd;
+   ufd->fd_r = fd_ref;
+   ufd->fd.cb = ul_ufd_cb;
+   if (flags)
+   uloop_fd_add(&ufd->fd, flags);
+
+   return 1;
+}
+
 static void ul_process_cb(struct uloop_process *p, int ret)
 {
struct lua_uloop_process *proc = container_of(p, struct 
lua_uloop_process, p);
 
lua_getglobal(state, "__uloop_cb");
lua_rawgeti(state, -1, proc->r);
+
luaL_unref(state, -2, proc->r);
lua_remove(state, -2);
lua_pushinteger(state, ret >> 8);
@@ -225,6 +316,7 @@ stati

[OpenWrt-Devel] [PATCH 3/5] Support delete a fd event.

2014-06-20 Thread xfguo
When you call the fd_add, it will return an object with `delete` method.
So you can delete that event if you want.

Signed-off-by: Xiongfei(Alex) Guo 
---
 examples/uloop-example.lua | 17 ++---
 lua/uloop.c| 30 ++
 2 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/examples/uloop-example.lua b/examples/uloop-example.lua
index ba34ec5..9b0684e 100755
--- a/examples/uloop-example.lua
+++ b/examples/uloop-example.lua
@@ -46,20 +46,31 @@ uloop.timer(
end, 2000
 )
 
-uloop.fd_add(udp, function(ufd, events)
+udp_ev = uloop.fd_add(udp, function(ufd, events)
local words, msg_or_ip, port_or_nil = ufd:receivefrom()
print('Recv UDP packet from '..msg_or_ip..':'..port_or_nil..' : 
'..words)
+   if words == "Stop!" then
+   udp_ev:delete()
+   end
 end, uloop.ULOOP_READ)
 
+udp_count = 0
 udp_send_timer = uloop.timer(
function()
local s = socket.udp()
-   local words = 'Hello!'
+   local words
+   if udp_count > 3 then
+   words = "Stop!"
+   udp_send_timer:cancel()
+   else
+   words = 'Hello!'
+   udp_send_timer:set(1000)
+   end
print('Send UDP packet to 127.0.0.1:8080 :'..words)
s:sendto(words, '127.0.0.1', 8080)
s:close()
 
-   udp_send_timer:set(1000)
+   udp_count = udp_count + 1
end, 3000
 )
 
diff --git a/lua/uloop.c b/lua/uloop.c
index c71d537..df57b8a 100644
--- a/lua/uloop.c
+++ b/lua/uloop.c
@@ -172,6 +172,24 @@ static int get_sock_fd(lua_State* L, int idx) {
return fd;
 }
 
+static int ul_ufd_delete(lua_State *L)
+{
+   struct lua_uloop_fd *ufd = lua_touserdata(L, 1);
+
+   uloop_fd_delete(&ufd->fd);
+   lua_getglobal(state, "__uloop_cb");
+   luaL_unref(L, -1, ufd->r);
+   lua_getglobal(state, "__uloop_fds");
+   luaL_unref(L, -1, ufd->fd_r);
+
+   return 1;
+}
+
+static const luaL_Reg ufd_m[] = {
+   { "delete", ul_ufd_delete },
+   { NULL, NULL }
+};
+
 static int ul_ufd_add(lua_State *L)
 {
struct lua_uloop_fd *ufd;
@@ -205,6 +223,18 @@ static int ul_ufd_add(lua_State *L)
lua_pop(L, 1);
 
ufd = lua_newuserdata(L, sizeof(*ufd));
+
+   lua_createtable(L, 0, 2);
+   lua_pushvalue(L, -1);
+   lua_setfield(L, -2, "__index");
+   lua_pushcfunction(L, ul_ufd_delete);
+   lua_setfield(L, -2, "__gc");
+   lua_pushvalue(L, -1);
+   lua_setmetatable(L, -3);
+   lua_pushvalue(L, -2);
+   luaI_openlib(L, NULL, ufd_m, 1);
+   lua_pushvalue(L, -2);
+
memset(ufd, 0, sizeof(*ufd));
 
ufd->r = ref;
-- 
1.9.1
___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


[OpenWrt-Devel] [PATCH 4/5] Fix bug of unref resources in Lua binding; fd method delete -> cancel.

2014-06-20 Thread xfguo
Signed-off-by: Xiongfei(Alex) Guo 
---
 examples/uloop-example.lua |  2 +-
 lua/uloop.c| 12 
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/examples/uloop-example.lua b/examples/uloop-example.lua
index 9b0684e..ab85a5d 100755
--- a/examples/uloop-example.lua
+++ b/examples/uloop-example.lua
@@ -50,7 +50,7 @@ udp_ev = uloop.fd_add(udp, function(ufd, events)
local words, msg_or_ip, port_or_nil = ufd:receivefrom()
print('Recv UDP packet from '..msg_or_ip..':'..port_or_nil..' : 
'..words)
if words == "Stop!" then
-   udp_ev:delete()
+   udp_ev:cancel()
end
 end, uloop.ULOOP_READ)
 
diff --git a/lua/uloop.c b/lua/uloop.c
index df57b8a..319942c 100644
--- a/lua/uloop.c
+++ b/lua/uloop.c
@@ -80,7 +80,7 @@ static int ul_timer_free(lua_State *L)
 
uloop_timeout_cancel(&tout->t);
lua_getglobal(state, "__uloop_cb");
-   luaL_unref(L, -1, tout->r);
+   luaL_unref(state, -1, tout->r);
 
return 1;
 }
@@ -177,16 +177,20 @@ static int ul_ufd_delete(lua_State *L)
struct lua_uloop_fd *ufd = lua_touserdata(L, 1);
 
uloop_fd_delete(&ufd->fd);
+
lua_getglobal(state, "__uloop_cb");
-   luaL_unref(L, -1, ufd->r);
+   luaL_unref(state, -1, ufd->r);
+   lua_remove(state, -1);
+
lua_getglobal(state, "__uloop_fds");
-   luaL_unref(L, -1, ufd->fd_r);
+   luaL_unref(state, -1, ufd->fd_r);
+   lua_remove(state, -1);
 
return 1;
 }
 
 static const luaL_Reg ufd_m[] = {
-   { "delete", ul_ufd_delete },
+   { "cancel", ul_ufd_delete },
{ NULL, NULL }
 };
 
-- 
1.9.1
___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


[OpenWrt-Devel] [PATCH 5/5] Fix bug of GC in fd and timeout objects for lua binding.

2014-06-20 Thread xfguo
fd and timeout lua object has a __gc method in its metatable. After the object
is freed and the another new object use the same reference in __uloop_cb and
__uloop_fds, the new object will be freed by the old __gc of the old object
when garbag collecting.

Signed-off-by: Xiongfei(Alex) Guo 
---
 lua/uloop.c | 25 ++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/lua/uloop.c b/lua/uloop.c
index 319942c..e806599 100644
--- a/lua/uloop.c
+++ b/lua/uloop.c
@@ -77,8 +77,15 @@ static int ul_timer_set(lua_State *L)
 static int ul_timer_free(lua_State *L)
 {
struct lua_uloop_timeout *tout = lua_touserdata(L, 1);
-
+   
uloop_timeout_cancel(&tout->t);
+   
+   /* obj.__index.__gc = nil , make sure executing only once*/
+   lua_getfield(L, -1, "__index");
+   lua_pushstring(L, "__gc");
+   lua_pushnil(L);
+   lua_settable(L, -3);
+
lua_getglobal(state, "__uloop_cb");
luaL_unref(state, -1, tout->r);
 
@@ -150,7 +157,6 @@ static void ul_ufd_cb(struct uloop_fd *fd, unsigned int 
events)
 
/* push events */
lua_pushinteger(state, events);
-
lua_call(state, 2, 0);
 }
 
@@ -175,9 +181,15 @@ static int get_sock_fd(lua_State* L, int idx) {
 static int ul_ufd_delete(lua_State *L)
 {
struct lua_uloop_fd *ufd = lua_touserdata(L, 1);
-
+   
uloop_fd_delete(&ufd->fd);
 
+   /* obj.__index.__gc = nil , make sure executing only once*/
+   lua_getfield(L, -1, "__index");
+   lua_pushstring(L, "__gc");
+   lua_pushnil(L);
+   lua_settable(L, -3);
+
lua_getglobal(state, "__uloop_cb");
luaL_unref(state, -1, ufd->r);
lua_remove(state, -1);
@@ -345,12 +357,19 @@ static int ul_run(lua_State *L)
return 1;
 }
 
+static int ul_cancel(lua_State *L)
+{
+   uloop_end();
+   return 1;
+}
+
 static luaL_reg uloop_func[] = {
{"init", ul_init},
{"run", ul_run},
{"timer", ul_timer},
{"process", ul_process},
{"fd_add", ul_ufd_add},
+   {"cancel", ul_cancel},
{NULL, NULL},
 };
 
-- 
1.9.1
___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


[OpenWrt-Devel] [PATCH] uloop lua binding: Added fd_add method; Fix bug of GC and stack overflow.

2014-05-02 Thread xfguo
From: "Xiongfei(Alex) Guo" 

Added fd_add method for uloop lua binding.

  Use uloop.fd_add like this:

local socket = require "socket"

udp = socket.udp()

udp_read_ev = uloop.fd_add(
  udp, -- socket
  function( -- callback function
ufd,-- socket object when register the fd
events  -- uloop events. eg. uloop.ULOOP_READ .
  )
local words, msg_or_ip, port_or_nil = ufd:receivefrom()
print(
  'Recv UDP packet from '..
  msg_or_ip ..':'..port_or_nil..
  ' : '..words
)
  end,
  uloop.ULOOP_READ -- event you want to listen
)

udp_read_ev:cancel() -- cancel it

  The `examples/uloop-example.lua` show an example of this work.

Fix stack overflow bug.
  The static variable `state` in `lua/uloop.c` should be clean after every
  callback.

Fix bug of GC
  fd and timeout lua object has a __gc method in its metatable. After the
  object is freed and if another new object use the same reference number in
  __uloop_cb and __uloop_fds, the new object will be freed by the old __gc
  of the old object when garbag collecting.

Signed-off-by: Xiongfei(Alex) Guo 
---
 examples/uloop-example.lua |   34 +
 lua/uloop.c|  168 +++-
 2 files changed, 201 insertions(+), 1 deletion(-)

diff --git a/examples/uloop-example.lua b/examples/uloop-example.lua
index 2da6ebd..ab85a5d 100755
--- a/examples/uloop-example.lua
+++ b/examples/uloop-example.lua
@@ -1,8 +1,14 @@
 #!/usr/bin/env lua
 
+local socket = require "socket"
+
 local uloop = require("uloop")
 uloop.init()
 
+local udp = socket.udp()
+udp:settimeout(0)
+udp:setsockname('*', 8080)
+
 -- timer example 1
 local timer
 function t()
@@ -40,5 +46,33 @@ uloop.timer(
end, 2000
 )
 
+udp_ev = uloop.fd_add(udp, function(ufd, events)
+   local words, msg_or_ip, port_or_nil = ufd:receivefrom()
+   print('Recv UDP packet from '..msg_or_ip..':'..port_or_nil..' : 
'..words)
+   if words == "Stop!" then
+   udp_ev:cancel()
+   end
+end, uloop.ULOOP_READ)
+
+udp_count = 0
+udp_send_timer = uloop.timer(
+   function()
+   local s = socket.udp()
+   local words
+   if udp_count > 3 then
+   words = "Stop!"
+   udp_send_timer:cancel()
+   else
+   words = 'Hello!'
+   udp_send_timer:set(1000)
+   end
+   print('Send UDP packet to 127.0.0.1:8080 :'..words)
+   s:sendto(words, '127.0.0.1', 8080)
+   s:close()
+
+   udp_count = udp_count + 1
+   end, 3000
+)
+
 uloop.run()
 
diff --git a/lua/uloop.c b/lua/uloop.c
index 51f53c2..5bc0e6c 100644
--- a/lua/uloop.c
+++ b/lua/uloop.c
@@ -25,6 +25,12 @@
 #include "../uloop.h"
 #include "../list.h"
 
+struct lua_uloop_fd {
+   struct uloop_fd fd;
+   int r;
+   int fd_r;
+};
+
 struct lua_uloop_timeout {
struct uloop_timeout t;
int r;
@@ -43,7 +49,10 @@ static void ul_timer_cb(struct uloop_timeout *t)
 
lua_getglobal(state, "__uloop_cb");
lua_rawgeti(state, -1, tout->r);
+   lua_remove(state, -2);
+
lua_call(state, 0, 0);
+
 }
 
 static int ul_timer_set(lua_State *L)
@@ -70,8 +79,15 @@ static int ul_timer_free(lua_State *L)
struct lua_uloop_timeout *tout = lua_touserdata(L, 1);
 
uloop_timeout_cancel(&tout->t);
+
+   /* obj.__index.__gc = nil , make sure executing only once*/
+   lua_getfield(L, -1, "__index");
+   lua_pushstring(L, "__gc");
+   lua_pushnil(L);
+   lua_settable(L, -3);
+
lua_getglobal(state, "__uloop_cb");
-   luaL_unref(L, -1, tout->r);
+   luaL_unref(state, -1, tout->r);
 
return 1;
 }
@@ -126,13 +142,136 @@ static int ul_timer(lua_State *L)
return 1;
 }
 
+static void ul_ufd_cb(struct uloop_fd *fd, unsigned int events)
+{
+   struct lua_uloop_fd *ufd = container_of(fd, struct lua_uloop_fd, fd);
+
+   lua_getglobal(state, "__uloop_cb");
+   lua_rawgeti(state, -1, ufd->r);
+   lua_remove(state, -2);
+
+   /* push fd object */
+   lua_getglobal(state, "__uloop_fds");
+   lua_rawgeti(state, -1, ufd->fd_r);
+   lua_remove(state, -2);
+
+   /* push events */
+   lua_pushinteger(state, events);
+   lua_call(state, 2, 0);
+}
+
+
+static int get_sock_fd(lua_State* L, int idx) {
+   int fd;
+   if(lua_isnumber(L, idx)) {
+   fd = lua_tonumber(L, idx);
+   } else {
+   luaL_checktype(L, idx, LUA_TUSERDATA);
+   lua_getfield(L, idx, "getfd");
+   if(lua_isnil(L, -1))
+   return luaL_error(L, "socket type missing 'getfd' 
method");
+   lua_pushvalue(L, idx - 1);
+   lua_call(L, 1, 1);
+   fd = lua_tointeger(L, -1);
+   lua_pop(L, 1);
+   }
+   return fd;

[OpenWrt-Devel] [PATCH 2/2] uloop: Added fd_add method for uloop lua binding.

2014-04-16 Thread xfguo
Use uloop.fd_add like this:

local socket = require "socket"

udp = socket.udp()

uloop.fd_add(
udp, -- socket
function( -- callback function
ufd,-- socket object when register the fd
events  -- uloop events. eg. uloop.ULOOP_READ .
)
local words, msg_or_ip, port_or_nil = ufd:receivefrom()
print('Recv UDP packet from '..msg_or_ip..':'..port_or_nil..'
: '..words)
end,
uloop.ULOOP_READ -- event you want to listen
)

The `examples/uloop-example.lua` show an example of this work.

Signed-off-by: Xiongfei(Alex) Guo 
---
 examples/uloop-example.lua |   23 +
 lua/uloop.c|  111

 2 files changed, 134 insertions(+), 0 deletions(-)

diff --git a/examples/uloop-example.lua b/examples/uloop-example.lua
index 2da6ebd..ba34ec5 100755
--- a/examples/uloop-example.lua
+++ b/examples/uloop-example.lua
@@ -1,8 +1,14 @@
 #!/usr/bin/env lua

+local socket = require "socket"
+
 local uloop = require("uloop")
 uloop.init()

+local udp = socket.udp()
+udp:settimeout(0)
+udp:setsockname('*', 8080)
+
 -- timer example 1
 local timer
 function t()
@@ -40,5 +46,22 @@ uloop.timer(
end, 2000
 )

+uloop.fd_add(udp, function(ufd, events)
+   local words, msg_or_ip, port_or_nil = ufd:receivefrom()
+   print('Recv UDP packet from '..msg_or_ip..':'..port_or_nil..' : 
'..words)
+end, uloop.ULOOP_READ)
+
+udp_send_timer = uloop.timer(
+   function()
+   local s = socket.udp()
+   local words = 'Hello!'
+   print('Send UDP packet to 127.0.0.1:8080 :'..words)
+   s:sendto(words, '127.0.0.1', 8080)
+   s:close()
+
+   udp_send_timer:set(1000)
+   end, 3000
+)
+
 uloop.run()

diff --git a/lua/uloop.c b/lua/uloop.c
index 5922e04..c71d537 100644
--- a/lua/uloop.c
+++ b/lua/uloop.c
@@ -25,6 +25,12 @@
 #include "../uloop.h"
 #include "../list.h"

+struct lua_uloop_fd {
+   struct uloop_fd fd;
+   int r;
+   int fd_r;
+};
+
 struct lua_uloop_timeout {
struct uloop_timeout t;
int r;
@@ -44,7 +50,9 @@ static void ul_timer_cb(struct uloop_timeout *t)
lua_getglobal(state, "__uloop_cb");
lua_rawgeti(state, -1, tout->r);
lua_remove(state, -2);
+
lua_call(state, 0, 0);
+
 }

 static int ul_timer_set(lua_State *L)
@@ -127,12 +135,95 @@ static int ul_timer(lua_State *L)
return 1;
 }

+static void ul_ufd_cb(struct uloop_fd *fd, unsigned int events)
+{
+   struct lua_uloop_fd *ufd = container_of(fd, struct lua_uloop_fd, fd);
+
+   lua_getglobal(state, "__uloop_cb");
+   lua_rawgeti(state, -1, ufd->r);
+   lua_remove(state, -2);
+
+   /* push fd object */
+   lua_getglobal(state, "__uloop_fds");
+   lua_rawgeti(state, -1, ufd->fd_r);
+   lua_remove(state, -2);
+
+   /* push events */
+   lua_pushinteger(state, events);
+
+   lua_call(state, 2, 0);
+}
+
+
+static int get_sock_fd(lua_State* L, int idx) {
+   int fd;
+   if(lua_isnumber(L, idx)) {
+   fd = lua_tonumber(L, idx);
+   } else {
+   luaL_checktype(L, idx, LUA_TUSERDATA);
+   lua_getfield(L, idx, "getfd");
+   if(lua_isnil(L, -1))
+   return luaL_error(L, "socket type missing 'getfd' 
method");
+   lua_pushvalue(L, idx - 1);
+   lua_call(L, 1, 1);
+   fd = lua_tointeger(L, -1);
+   lua_pop(L, 1);
+   }
+   return fd;
+}
+
+static int ul_ufd_add(lua_State *L)
+{
+   struct lua_uloop_fd *ufd;
+   int fd = 0;
+   unsigned int flags = 0;
+   int ref;
+   int fd_ref;
+
+   if (lua_isnumber(L, -1)) {
+   flags = lua_tointeger(L, -1);
+   lua_pop(L, 1);
+   }
+
+   if (!lua_isfunction(L, -1)) {
+   lua_pushstring(L, "invalid arg list");
+   lua_error(L);
+
+   return 0;
+   }
+
+   fd = get_sock_fd(L, -2);
+
+   lua_getglobal(L, "__uloop_cb");
+   lua_pushvalue(L, -2);
+   ref = luaL_ref(L, -2);
+   lua_pop(L, 1);
+
+   lua_getglobal(L, "__uloop_fds");
+   lua_pushvalue(L, -3);
+   fd_ref = luaL_ref(L, -2);
+   lua_pop(L, 1);
+
+   ufd = lua_newuserdata(L, sizeof(*ufd));
+   memset(ufd, 0, sizeof(*ufd));
+
+   ufd->r = ref;
+   ufd->fd.fd = fd;
+   ufd->fd_r = fd_ref;
+   ufd->fd.cb = ul_ufd_cb;
+   if (flags)
+   uloop_fd_add(&ufd->fd, flags);
+
+   return 1;
+}
+
 static void ul_process_cb(struct uloop_process *p, int ret)
 {
struct lua_uloop_process *proc = container_of(p, struct
lua_uloop_process, p);

lua_getglobal(state, "__uloop_cb");
lua_rawgeti(state, -1, proc->r);
+
luaL_unref(state, -2, proc->r);
lua_remove(state, -2);
lua_pushinteger(state, ret >> 8);
@@ -225,6 +316,7 @@

[OpenWrt-Devel] [PATCH 1/2] uloop: Fix stack overflow bug of uloop lua binding.

2014-04-16 Thread xfguo
The static variable `state` in `lua/uloop.c` should be clean after every
callback.

Signed-off-by: Xiongfei(Alex) Guo 
---
 lua/uloop.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/lua/uloop.c b/lua/uloop.c
index 51f53c2..5922e04 100644
--- a/lua/uloop.c
+++ b/lua/uloop.c
@@ -43,6 +43,7 @@ static void ul_timer_cb(struct uloop_timeout *t)

lua_getglobal(state, "__uloop_cb");
lua_rawgeti(state, -1, tout->r);
+   lua_remove(state, -2);
lua_call(state, 0, 0);
 }

@@ -133,6 +134,7 @@ static void ul_process_cb(struct uloop_process *p, int
ret)
lua_getglobal(state, "__uloop_cb");
lua_rawgeti(state, -1, proc->r);
luaL_unref(state, -2, proc->r);
+   lua_remove(state, -2);
lua_pushinteger(state, ret >> 8);
lua_call(state, 1, 0);
 }
-- 
1.7.1
___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel