driver_cmd_nl80211.c revision d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6
1b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt/* 2b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt * Driver interaction with extended Linux CFG8021 3b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt * 4b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt * This program is free software; you can redistribute it and/or modify 5b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt * it under the terms of the GNU General Public License version 2 as 6b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt * published by the Free Software Foundation. 7b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt * 8b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 9b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt * license. 10b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt * 11b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt */ 12b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 13b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt#include "driver_nl80211.h" 14b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 15b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt#define WPA_EVENT_DRIVER_STATE "CTRL-EVENT-DRIVER-STATE " 16b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 17b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt#define WPA_PS_ENABLED 0 18b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt#define WPA_PS_DISABLED 1 19b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 20d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidttypedef struct android_wifi_priv_cmd { 21d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt char *buf; 22d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt int used_len; 23d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt int total_len; 24d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt} android_wifi_priv_cmd; 25d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt 26b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidtint send_and_recv_msgs(struct wpa_driver_nl80211_data *drv, struct nl_msg *msg, 27b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt int (*valid_handler)(struct nl_msg *, void *), 28b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt void *valid_data); 29b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 30b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidtstatic int wpa_driver_set_btcoex_state(char state) 31b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt{ 32b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt int ret; 33b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt int fd; 34b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 35b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt fd = open("/sys/devices/platform/bcmdhd/bt_coex_state", O_RDWR, 0); 36b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt if (fd == -1) 37b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt return -1; 38b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 39b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt ret = write(fd, &state, sizeof(state)); 40b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt close(fd); 41b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 42b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: set btcoex state to '%c' result = %d", 43b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt __func__, state, ret); 44b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt return (ret > 0) ? 0 : -1; 45b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt} 46b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 47b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidtstatic int wpa_driver_set_power_save(void *priv, int state) 48b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt{ 49b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt struct i802_bss *bss = priv; 50b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt struct wpa_driver_nl80211_data *drv = bss->drv; 51b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt struct nl_msg *msg; 52b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt int ret = -1; 53b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt enum nl80211_ps_state ps_state; 54b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 55b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt msg = nlmsg_alloc(); 56b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt if (!msg) 57b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt return -1; 58b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 59b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0, 60b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt NL80211_CMD_SET_POWER_SAVE, 0); 61b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 62b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt if (state == WPA_PS_ENABLED) 63b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt ps_state = NL80211_PS_ENABLED; 64b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt else 65b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt ps_state = NL80211_PS_DISABLED; 66b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 67b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); 68b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state); 69b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 70b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt ret = send_and_recv_msgs(drv, msg, NULL, NULL); 71b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt msg = NULL; 72b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt if (ret < 0) 73b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt wpa_printf(MSG_ERROR, "nl80211: Set power mode fail: %d", ret); 74b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidtnla_put_failure: 75b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt nlmsg_free(msg); 76b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt return ret; 77b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt} 78b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 79b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidtstatic int get_power_mode_handler(struct nl_msg *msg, void *arg) 80b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt{ 81b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt struct nlattr *tb[NL80211_ATTR_MAX + 1]; 82b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); 83b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt int *state = (int *)arg; 84b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 85b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), 86b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt genlmsg_attrlen(gnlh, 0), NULL); 87b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 88b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt if (!tb[NL80211_ATTR_PS_STATE]) 89b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt return NL_SKIP; 90b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 91b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt if (state) { 92b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt *state = (int)nla_get_u32(tb[NL80211_ATTR_PS_STATE]); 93b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "nl80211: Get power mode = %d", *state); 94b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt *state = (*state == NL80211_PS_ENABLED) ? 95b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt WPA_PS_ENABLED : WPA_PS_DISABLED; 96b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt } 97b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 98b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt return NL_SKIP; 99b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt} 100b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 101b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidtstatic int wpa_driver_get_power_save(void *priv, int *state) 102b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt{ 103b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt struct i802_bss *bss = priv; 104b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt struct wpa_driver_nl80211_data *drv = bss->drv; 105b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt struct nl_msg *msg; 106b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt int ret = -1; 107b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt enum nl80211_ps_state ps_state; 108b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 109b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt msg = nlmsg_alloc(); 110b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt if (!msg) 111b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt return -1; 112b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 113b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0, 114b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt NL80211_CMD_GET_POWER_SAVE, 0); 115b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 116b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); 117b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 118b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt ret = send_and_recv_msgs(drv, msg, get_power_mode_handler, state); 119b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt msg = NULL; 120b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt if (ret < 0) 121b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt wpa_printf(MSG_ERROR, "nl80211: Get power mode fail: %d", ret); 122b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidtnla_put_failure: 123b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt nlmsg_free(msg); 124b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt return ret; 125b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt} 126b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 127b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidtint wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf, 128b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt size_t buf_len ) 129b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt{ 130b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt struct i802_bss *bss = priv; 131b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt struct wpa_driver_nl80211_data *drv = bss->drv; 132d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt struct ifreq ifr; 133d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt android_wifi_priv_cmd priv_cmd; 134b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt int ret = 0; 135b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 136b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt wpa_msg(drv->ctx, MSG_INFO, "%s: %s", __func__, cmd); 137b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 138b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt if (os_strcasecmp(cmd, "STOP") == 0) { 139b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0); 140b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED"); 141b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt } else if (os_strcasecmp(cmd, "START") == 0) { 142b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1); 143b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED"); 144b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt } else if (os_strcasecmp(cmd, "MACADDR") == 0) { 145b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt u8 macaddr[ETH_ALEN] = {}; 146b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 147b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt ret = linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, macaddr); 148b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt if (!ret) 149b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt ret = os_snprintf(buf, buf_len, 150b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt "Macaddr = " MACSTR "\n", MAC2STR(macaddr)); 151b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt } else if (os_strcasecmp(cmd, "RELOAD") == 0) { 152b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED"); 153b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt } else if (os_strncasecmp(cmd, "POWERMODE ", 10) == 0) { 154b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt int state; 155b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 156b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt state = atoi(cmd + 10); 157b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt ret = wpa_driver_set_power_save(priv, state); 158b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt } else if (os_strncasecmp(cmd, "GETPOWER", 8) == 0) { 159b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt int state = -1; 160b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 161b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt ret = wpa_driver_get_power_save(priv, &state); 162b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt if (!ret && (state != -1)) 163b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt ret = os_snprintf(buf, buf_len, "POWERMODE = %d\n", state); 164b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt } else if (os_strncasecmp(cmd, "BTCOEXMODE ", 11) == 0) { 165b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt char state = cmd[11]; 166b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 167b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt ret = wpa_driver_set_btcoex_state(state); 168d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt } else { /* Use private command */ 169d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt memset(&ifr, 0, sizeof(ifr)); 170d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt memset(&priv_cmd, 0, sizeof(priv_cmd)); 171d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt os_memcpy(buf, cmd, strlen(cmd) + 1); 172d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt os_strncpy(&ifr.ifr_name, bss->ifname, IFNAMSIZ); 173d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt 174d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt priv_cmd.buf = buf; 175d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt priv_cmd.used_len = buf_len; 176d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt priv_cmd.total_len = buf_len; 177d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt ifr.ifr_data = &priv_cmd; 178d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt 179d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt if ((ret = ioctl(drv->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) 180d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: failed to issue private commands\n", __func__); 181d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt else { 182d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt ret = 0; 183d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt if ((os_strcasecmp(cmd, "LINKSPEED") == 0) || 184d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt (os_strcasecmp(cmd, "RSSI") == 0)) 185d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt ret = strlen(buf); 186d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt 187d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s %s len = %d, %d", __func__, buf, ret, strlen(buf)); 188d261d2a4e8c8ba5d52a3f6d24a15404e5a3a49e6Dmitry Shmidt } 189b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt } 190b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt 191b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt return ret; 192b11634b6f66e5ae56fe2212bd5d648157541c6e6Dmitry Shmidt} 193