#ifndef PROT_SLAVE_H #define PROT_SLAVE_H #include "QObject" #include "base/base.h" #include "QList" #include "interface/codec.h" #include "interface/interface.h" #include "base/mycfg.h" #include "QThread" #include "QTimer" class HandleSlave : public QObject { Q_OBJECT public: HandleSlave() { busy = 0; addr = 0; cmd=0; timer_=nullptr; timer_retry_=nullptr; times_retry=0; } virtual ~HandleSlave() { if(timer_!=nullptr){ delete timer_; } if(timer_retry_!=nullptr){ delete timer_retry_; } } public: virtual int start(myarray data) = 0; virtual int dolater(int cmd, myarray data) = 0; virtual void timeout(){timer_->stop();}; int busy; int addr; int cmd; protected: // 发送数据到从机 int send_data(int cmd,myarray data,int times){ this->cmd=cmd; this->data_send=data; this->times_retry=times; if(timer_retry_==nullptr){ timer_retry_=new QTimer(); connect(timer_,&QTimer::timeout,this,&HandleSlave::timeout_retry); } timer_retry_->start(60); return 0; } // 发送操作结束信号 int end(int ack,myarray data){ emit end_signal(addr,ack,data); return 0; } // 开始超时计时器,此计时器用于整个操作的超时 void timeout_start(int ms){ if(timer_==nullptr){ timer_=new QTimer(); connect(timer_,&QTimer::timeout,this,&HandleSlave::timeout); } timer_->start(ms); } // 停止超时计时器,此方法同时停止重发计时器 void timeout_stop(){ if(timer_!=nullptr){ timer_->stop(); } timeout_stop_retry(); } // 停止数据回复超时重试计时器 void timeout_stop_retry(){ if(timer_retry_!=nullptr){ timer_retry_->stop(); } times_retry=0; } private: // 重试回调 void timeout_retry(){ if(times_retry>0){ times_retry--; emit send_data_signal(addr,cmd,data_send); }else{ timer_retry_->stop(); } } private: QTimer *timer_; QTimer *timer_retry_; int times_retry; myarray data_send; signals: void send_data_signal(int addr, int cmd, myarray data); void end_signal(int addr,int ack,myarray data); }; class HandleBoardCast : public QObject { Q_OBJECT public: HandleBoardCast() { busy = 0; addr = 0; cmd=0; timer_=nullptr; timer_retry_=nullptr; times_retry=0; addr_response=0; } virtual ~HandleBoardCast() { if(timer_!=nullptr){ delete timer_; } if(timer_retry_!=nullptr){ delete timer_retry_; } } public: virtual int start(myarray data) = 0; virtual int dolater(int cmd, myarray data) = 0; virtual void timeout(){timer_->stop();}; int busy; int addr; int addr_response; int cmd; public: // 判断是否所有从机都返回 bool check_response(){ return (addr^addr_response)==0?true:false; } // 把地址列表转化为bit void trun_list_to_bit(QList addrs){ addr=0; foreach(int adr,addrs){ addr|=1<<(adr-1); } } protected: // 发送数据到从机 int send_data(int cmd,myarray data,int times){ this->cmd=cmd; this->data_send=data; this->times_retry=times; if(timer_retry_==nullptr){ timer_retry_=new QTimer(); connect(timer_,&QTimer::timeout,this,&HandleBoardCast::timeout_retry); } timer_retry_->start(300); return 0; } // 发送操作结束信号 int end(int ack,myarray data){ emit end_signal(0x1f,ack,data); return 0; } // 开始超时计时器,此计时器用于整个操作的超时 void timeout_start(int ms){ if(timer_==nullptr){ timer_=new QTimer(); connect(timer_,&QTimer::timeout,this,&HandleBoardCast::timeout); } timer_->start(ms); } // 停止超时计时器,此方法同时停止重发计时器 void timeout_stop(){ if(timer_!=nullptr){ timer_->stop(); } timeout_stop_retry(); } // 停止数据回复超时重试计时器 void timeout_stop_retry(){ if(timer_retry_!=nullptr){ timer_retry_->stop(); } times_retry=0; } private: // 重试回调 void timeout_retry(){ if(times_retry>0){ times_retry--; myarray s; int addr_retry=addr^addr_response; // 这里重发只重发没有收到回应的从机 s.append(addr_retry&0xff); s.append((addr_retry>>8)&0xff); s.append((addr_retry>>16)&0xff); s.append(data_send); emit send_data_signal(0x1f,cmd,s); }else{ timer_retry_->stop(); } } private: QTimer *timer_; QTimer *timer_retry_; int times_retry; myarray data_send; signals: void send_data_signal(int addr, int cmd, myarray data); void end_signal(int addr,int ack,myarray data); }; class prot_slave : public QObject { Q_OBJECT public: prot_slave() { if_ = nullptr; codec_ = nullptr; broadcast_=nullptr; } ~prot_slave() {} void init(); bool set_slave_handle(int addr, HandleSlave *handle); bool set_boardcast_handle(QList addrs,HandleBoardCast *handle); protected slots: void send_data_slot(int addr, int cmd, myarray data); protected: InterFace *if_; Codec *codec_; QList slaves; HandleBoardCast *broadcast_; }; prot_slave *protSlave(); #endif // PROT_SLAVE_H