| 115 | } |
| 116 | |
| 117 | bool wifi::commandhelper2::set_wifi_frequency( |
| 118 | const std::string &device, uint32_t freq_mhz, |
| 119 | std::optional<uint32_t> channel_width) { |
| 120 | if (channel_width.has_value()) { |
| 121 | get_logger()->debug("set_wifi_frequency {} {}Mhz {}Mhz", device, freq_mhz, |
| 122 | channel_width.value()); |
| 123 | } else { |
| 124 | get_logger()->debug("set_wifi_frequency {} {}Mhz", device, freq_mhz); |
| 125 | } |
| 126 | int err = 1; |
| 127 | struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); |
| 128 | int rc; |
| 129 | |
| 130 | // Create the socket and connect to it. |
| 131 | struct nl_sock *sckt = nl_socket_alloc(); |
| 132 | genl_connect(sckt); |
| 133 | |
| 134 | // Allocate a new message. |
| 135 | struct nl_msg *mesg = nlmsg_alloc(); |
| 136 | |
| 137 | // Check /usr/include/linux/nl80211.h for a list of commands and attributes. |
| 138 | enum nl80211_commands command = NL80211_CMD_SET_WIPHY; |
| 139 | |
| 140 | // Create the message so it will send a command to the nl80211 interface. |
| 141 | genlmsg_put(mesg, 0, 0, genl_ctrl_resolve(sckt, "nl80211"), 0, 0, command, 0); |
| 142 | |
| 143 | // Add specific attributes to change the frequency of the device. |
| 144 | NLA_PUT_U32(mesg, NL80211_ATTR_IFINDEX, if_nametoindex(device.c_str())); |
| 145 | NLA_PUT_U32(mesg, NL80211_ATTR_WIPHY_FREQ, freq_mhz); |
| 146 | if (channel_width != std::nullopt) { |
| 147 | const uint32_t channel_width_given = channel_width.value(); |
| 148 | auto netlink_channel_width = NL80211_CHAN_WIDTH_20; |
| 149 | switch (channel_width_given) { |
| 150 | case 10: |
| 151 | netlink_channel_width = NL80211_CHAN_WIDTH_10; |
| 152 | case 20: |
| 153 | netlink_channel_width = NL80211_CHAN_WIDTH_20; |
| 154 | break; |
| 155 | case 40: |
| 156 | netlink_channel_width = NL80211_CHAN_WIDTH_40; |
| 157 | break; |
| 158 | default: |
| 159 | get_logger()->debug("Invalid channel width {}, assuming 20Mhz", |
| 160 | channel_width_given); |
| 161 | break; |
| 162 | } |
| 163 | NLA_PUT_U32(mesg, NL80211_ATTR_CHANNEL_WIDTH, channel_width_given); |
| 164 | } |
| 165 | |
| 166 | // Finally send it and receive the amount of bytes sent. |
| 167 | nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); |
| 168 | rc = nl_send_auto(sckt, mesg); |
| 169 | nl_recvmsgs(sckt, cb); |
| 170 | nl_cb_put(cb); |
| 171 | nlmsg_free(mesg); |
| 172 | nl_socket_free(sckt); |
| 173 | return (err >= 0); |
| 174 |
nothing calls this directly
no test coverage detected