// SET example

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <string>

int main(int argc, char ** argv) {
    
    const std::string hostname = "192.168.61.222";
    const std::string DEVICE = "8";

    const std::string COMMON_OID_PATH = ".1.3.6.1.4.1.3808.1.1.3.3";
    const std::string COMMON_STATUS_PATH  = ".5.1.1.4."; // .4 = OutletState
    const std::string COMMON_CONTROL_PATH = ".3.1.1.4."; // .4 = OutletControl
    
    netsnmp_session session, *ss;
    netsnmp_pdu *pdu;
    netsnmp_pdu *response;

    oid anOID[MAX_OID_LEN];
    size_t anOID_len;

    netsnmp_variable_list *vars;
    int status;
    int count = 1;

    // Initialize the SNMP library
    init_snmp("snmpdemoapp");

    // Initialize a "session" that defines who we're going to talk to
    snmp_sess_init( &session );
    session.peername = strdup(hostname.c_str());
    session.securityName = strdup("shins");
    session.version=SNMP_VERSION_3;
    session.securityNameLen = strlen(session.securityName);

    // Open the session
    SOCK_STARTUP;
    ss = snmp_open(&session); // establish the session 

    if (!ss) {
        snmp_sess_perror("ack", &session);
        SOCK_CLEANUP;
        exit(1);
    }
    
    ///////////////////////////////////////////////////////////////////////////////////////

    // 1: ON, 2: OFF   
    int value = 2; 

    // Compose the address using CONTROL
    std::string address = COMMON_OID_PATH + COMMON_CONTROL_PATH + DEVICE;
    
    // Create the PDU for the data for our request.
    pdu = snmp_pdu_create(SNMP_MSG_SET);
    anOID_len = MAX_OID_LEN;
    
    if (!snmp_parse_oid(address.c_str(), anOID, &anOID_len)) {
            snmp_perror(address.c_str());
        SOCK_CLEANUP;
        exit(1);
    }

    // Add the value to the PDU
    snmp_pdu_add_variable(pdu, anOID, anOID_len, ASN_INTEGER, (const u_char*)&value, sizeof(value));

    // Send the Request out.
    status = snmp_synch_response(ss, pdu, &response);

    // Process the response.
    if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
        printf("Outlet status set successfully\n");

    ///////////////////////////////////////////////////////////////////////////////////////        
    } else {
        // FAILURE: print what went wrong!

        if (status == STAT_SUCCESS)
            fprintf(stderr, "Error in packet\nReason: %s\n",
                    snmp_errstring(response->errstat));
        else if (status == STAT_TIMEOUT)
            fprintf(stderr, "Timeout: No response from %s.\n",
                    session.peername);
        else
            snmp_sess_perror("snmpdemoapp", ss);

    }

    // Clean up:
    //  1) free the response.
    //  2) close the session.
    if (response)
        snmp_free_pdu(response);
    snmp_close(ss);

    SOCK_CLEANUP;
    return (0);
    
} 
