/*
#
# wifi连接接口
#   说明：通过进程间通信与wpa_supplicant进行交互实现wifi连接
#   注意：使用该接口的应用运行前要确保wpa_supplicant应用已经启动
# 并且能明确进程间通信地址。
#
*/
#ifndef __WPA_CLIENT_H__
#define __WPA_CLIENT_H__
#include <string>
#include <sys/un.h>
#include "common/global.hpp"

namespace wifi {
const std::string WPA_PATH = "/var/run/wpa_supplicant/wlan2"; //进程间通信地址加上网络接口额名称
struct WPAContext {
    int s;
    struct sockaddr_un local;
    struct sockaddr_un dest;
};

enum ConnectStatus { STEP_SCAN = 0, STEP_CONNECT_AP_OK, STEP_DHCP_IP, STEP_SUCCESS };
class MXDHCP { // dhcp ip地址的工具类，实现方法不算特别合理。可以根据具体情况进行更改
public:
    MXDHCP();
    ~MXDHCP();
    bool Start(const std::string& net_interface);
    bool GetDHCPStatus();

private:
    bool CheckString(char* buf, int len);
    FILE* pstream;
};

class WPAClient {
public:
    WPAClient(const std::string& wpa_control_path = WPA_PATH);
    ~WPAClient();
    bool GetInitStatus() { return wpa_context_ != NULL; }                   //获取wpa进程间通信是否建立连接
    int GetWiFiRssi();                                                      //获取wifi信号强度，需要在连接成功之后调用
    std::string GetCurrentSSID();                                           //获取当前连接的wifi的名称
    bool ConnectWiFi(const std::string& ssid, const std::string& password); //连接加密wifi，传入wifi名称和密码
    bool ConnectWiFiWithNoPassword(const std::string& ssid);                //连接无加密的wifi，传入wifi名称即可
    bool ConnectWiFiWithLast();                                             //直接连接上次已保存的wifi
    bool GetConnectStatus();                                                //获取wifi连接状态
    std::string GetNetSsid();
    void wifiup(); // mlan0 up
    bool CleanWifi();
    bool ReconnectWiFi(); //重新连接WIFI
protected:
    bool Init();
    struct WPAContext* Open(const std::string& path);
    void Close(struct WPAContext* context);
    bool Request(struct WPAContext* context, const std::string& cmd, std::string& reply);
    bool CheckCommandWithOk(const std::string cmd);
    bool AddWiFi(int& id);
    bool SetScanSSID(int id);
    bool SetSSID(const std::string& ssid, int id);
    bool SetPassword(const std::string& password, int id);
    bool SetProtocol(int id, int en_crypt);
    bool CleanAllWiFi();
    bool EnableWiFi(int id);
    void SetConnStatus(ConnectStatus status);
    int GetConnStatus();

protected:
    struct WPAContext* wpa_context_;
    std::string wpa_control_path_;
    MXDHCP dhcp_;

private:
    int step_;
};
}
#endif // __WPA_CLIENT_H__
