#include "s7_plc.h"

S7PLC::S7PLC():bConnected_(false)
{
}
S7PLC::~S7PLC()
{
    std::cout<<"plc start delete"<<std::endl;
    disconnect();
    std::cout<<"plc finish delete"<<std::endl;
}

bool S7PLC::getConnection(){
    return bConnected_;
}

bool S7PLC::connect(std::string ip)    
{
    std::lock_guard<std::mutex> lck (mutex_);
    int ret=client_.ConnectTo(ip.c_str(),0,1);
    bConnected_=(ret==0);
    return bConnected_;
}

bool S7PLC::ReadShorts(int DBNumber,int start,int size,short* pdata)
{
    short* plc_data= (short*)malloc(size*sizeof(short));
    bool ret=read_dbs(DBNumber,start*sizeof(short),size*sizeof(short),pdata);
    if(ret)
    {
        reverse_byte(pdata,size*sizeof(short),plc_data);
        for(int i=0;i<size;++i)
            pdata[i]=plc_data[size-i-1];
    }
    free(plc_data);
    return ret;

}
    bool S7PLC::WriteShorts(int DBNumber,int start,int size,short* pdata)
    {
        short* plc_data=(short*)malloc(size*sizeof(short));
        memcpy(plc_data,pdata,size*sizeof(short));
        for(int i=0;i<size;++i)
            plc_data[i]=HTON(plc_data[i]);

        bool ret=write_dbs(DBNumber,start*sizeof(short),size*sizeof(short),plc_data);
        free(plc_data);
        return ret;
    }

 bool S7PLC::read_dbs(int DBNumber,int start,int size,void* pdata)
 {
     std::lock_guard<std::mutex> lck (mutex_);
     usleep(1000* 50);
     if(bConnected_==false)
        return false;
     
     int ret=client_.AsDBRead(DBNumber,start,size,pdata);
     return ret == 0;
 }
 bool S7PLC::write_dbs(int DBNumber, int start, int size, void *pdata)
 {
    std::lock_guard<std::mutex> lck(mutex_);
    usleep(1000*50);
     if(bConnected_==false)
        return false;
     
     int ret = client_.AsDBWrite(DBNumber, start, size, pdata);

     return ret == 0;
 }
 void S7PLC::disconnect()
 {
     std::lock_guard<std::mutex> lck(mutex_);
     client_.Disconnect();
 }

 void S7PLC::reverse_byte(void* pdata,int num_byte,void* out)
 {
     char* pin=(char*)pdata;
     char* pout=(char*)out;
     for(int i=0;i<num_byte;++i)
     {
         pout[i]=pin[num_byte-i-1];
     }
 }