//
// Created by xajhuang on 2022/5/31.
//

#ifndef VCPE_PROJECT_PPPOE_INFO_H
#define VCPE_PROJECT_PPPOE_INFO_H
#ifdef __cplusplus
extern "C" {
#endif
#include <uthash/uthash.h>
#include "netif/ppp/ppp.h"
#include "misc.h"

#define PPPOE_MAX_TIMEOUT (30)

typedef enum {
    STATUS_TASK_INIT,
    STATUS_TASK_DIAL,
    STATUS_TASK_CONNECTED,
    STATUS_TASK_ERROR,
    STATUS_TASK_DISCONNECTED,
    STATUS_TASK_DELETE,
    STATUS_PPPOE_UPDATE,
} PPPOE_TASK;

typedef enum {
    STATUS_USER_NEW,
    STATUS_USER_DELETE,
    STATUS_USER_MODIFY,
    STATUS_USER_NORMAL,
} USER_STATUS;

typedef struct {
    unsigned int timeout;
    unsigned int count;
} RETRY_WORK;

typedef struct {
    unsigned short sessionId;
    char           clientIp[MAX_IP_V4_STR];
    char           clientGw[MAX_IP_V4_STR];
    char           clientMask[MAX_IP_V4_STR];
    char           clientMac[MAX_MAC_ADDR_STR];
    char           svrBaseMac[MAX_MAC_ADDR_STR];
} PPPOE_SESSION_DATA, *PPPPOE_SESSION_DATA;

typedef struct {
    unsigned int  userid;
    struct netif *nicif;
    struct netif *pppif;
    ppp_pcb      *ppp;

    RETRY_WORK retry;

    PPPOE_SESSION_DATA data;

    PPPOE_TASK status;
} PPPOE_SESSION, *PPPPOE_SESSION;

typedef struct {
    unsigned int   userid;
    unsigned int   vni;
    unsigned short q1;
    unsigned short q2;
    unsigned char  mac_addr[6];
    const char    *pppoe_user;
    const char    *pppoe_passwd;
} USER_PARAMS, *PUSER_PARAMS;

typedef struct {
    unsigned int   vni;
    unsigned short q1;
    unsigned short q2;
} VXLAN_TAG, *PVXLAN_TAG;

typedef struct {
    unsigned char mac_addr[6];
    const char   *pppoe_user;
    const char   *pppoe_passwd;
} USER_INFO, *PUSER_INFO;

typedef struct {
    unsigned int  userid;
    VXLAN_TAG     vxlan;
    unsigned char mac_addr[6];
    USER_INFO     user_info;
    PPPOE_SESSION session;

    USER_STATUS user_status;

    UT_hash_handle hh_id;
    UT_hash_handle hh_vxlan;
    UT_hash_handle hh_mac;
} USER_INFO_CONTEXT, *PUSER_INFO_CONTEXT;

int           pppoe_session_create(PUSER_INFO_CONTEXT pUser);
int           pppoe_session_init();
struct netif *get_rawsocket_if(void);

#ifdef __cplusplus
}
#endif
#endif    //VCPE_PROJECT_PPPOE_INFO_H