fix up hostapd for mac80211
[openwrt/openwrt.git] / package / hostapd / patches / 003-use-nl80211-for-beacons.patch
diff --git a/package/hostapd/patches/003-use-nl80211-for-beacons.patch b/package/hostapd/patches/003-use-nl80211-for-beacons.patch
new file mode 100644 (file)
index 0000000..34fa841
--- /dev/null
@@ -0,0 +1,149 @@
+---
+ hostapd/driver_devicescape.c |  111 +++++++++++++++++++++++++++++++------------
+ 1 file changed, 82 insertions(+), 29 deletions(-)
+
+--- hostap.orig/hostapd/driver_devicescape.c   2007-11-09 13:41:13.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c        2007-11-09 13:41:13.000000000 +0100
+@@ -68,6 +68,8 @@ struct i802_driver_data {
+       struct nl_handle *nl_handle;
+       struct nl_cache *nl_cache;
+       struct genl_family *nl80211;
++      int dtim_period;
++      unsigned int beacon_set:1;
+ };
+@@ -908,37 +910,44 @@ static int i802_bss_remove(void *priv, c
+ }
+-static int i802_set_beacon(const char *ifname, void *priv,
++static int i802_set_beacon(const char *iface, void *priv,
+                          u8 *head, size_t head_len,
+                          u8 *tail, size_t tail_len)
+ {
+       struct i802_driver_data *drv = priv;
+-      struct prism2_hostapd_param *param;
+-      int len, ret = 0;
++      struct nl_msg *msg;
++      u8 cmd = NL80211_CMD_NEW_BEACON;
++      int ret = -1;
+-      param = os_zalloc(sizeof(*param) + head_len + tail_len);
+-      if (param == NULL) {
+-              printf("Failed to alloc memory for beacon ioctl\n");
+-              return -1;
+-      }
+-      len = (&param->u.beacon.data[0] - (u8 *) param) + head_len + tail_len;
+-      param->cmd = PRISM2_HOSTAPD_SET_BEACON;
+-      param->u.beacon.head_len = head_len;
+-      param->u.beacon.tail_len = tail_len;
+-      memcpy(&param->u.beacon.data[0], head, head_len);
+-      memcpy(&param->u.beacon.data[0] + head_len, tail, tail_len);
+-
+-      if (len < (int) sizeof(*param))
+-              len = sizeof(*param);
+-      if (hostapd_ioctl_iface(ifname, drv, param, len)) {
+-              printf("Could not set beacon data to kernel driver.\n");
+-              printf("ifname='%s' head=%p head_len=%d tail=%p tail_len=%d "
+-                     "cmd=%d\n",
+-                     ifname, head, head_len, tail, tail_len, param->cmd);
+-              ret = -1;
+-      }
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
+-      free(param);
++      if (drv->beacon_set)
++              cmd = NL80211_CMD_SET_BEACON;
++
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, cmd, 0);
++      NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, head_len, head);
++      NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, tail_len, tail);
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
++      NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, 1000);
++
++      if (!drv->dtim_period)
++              drv->dtim_period = 2;
++      NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, drv->dtim_period);
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++          nl_wait_for_ack(drv->nl_handle) < 0)
++              goto out;
++
++      ret = 0;
++
++      drv->beacon_set = 1;
++
++ out:
++ nla_put_failure:
++      nlmsg_free(msg);
+       return ret;
+ }
+@@ -985,15 +994,59 @@ static int i802_set_internal_bridge(void
+ static int i802_set_beacon_int(void *priv, int value)
+ {
+       struct i802_driver_data *drv = priv;
+-      return hostap_ioctl_prism2param(drv, PRISM2_PARAM_BEACON_INT, value);
++      struct nl_msg *msg;
++      int ret = -1;
++
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
++
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, NL80211_CMD_SET_BEACON, 0);
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->iface));
++
++      NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, value);
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++          nl_wait_for_ack(drv->nl_handle) < 0)
++              goto out;
++
++      ret = 0;
++
++ out:
++ nla_put_failure:
++      nlmsg_free(msg);
++      return ret;
+ }
+-static int i802_set_dtim_period(const char *ifname, void *priv, int value)
++static int i802_set_dtim_period(const char *iface, void *priv, int value)
+ {
+       struct i802_driver_data *drv = priv;
+-      return hostap_ioctl_prism2param_iface(ifname, drv,
+-                                            PRISM2_PARAM_DTIM_PERIOD, value);
++      struct nl_msg *msg;
++      int ret = -1;
++
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
++
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, NL80211_CMD_SET_BEACON, 0);
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
++
++      drv->dtim_period = value;
++      NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, drv->dtim_period);
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++          nl_wait_for_ack(drv->nl_handle) < 0)
++              goto out;
++
++      ret = 0;
++
++ out:
++ nla_put_failure:
++      nlmsg_free(msg);
++      return ret;
+ }