#include "qgftfptargetsim.h" #include #include #include #include #include #include #include "bsk_tftpd.h" #include "bsk_tftp_pfs.h" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" static bsk_download_site_t sites[]= { {"ZynQ", "0x94", 0, 0, 6, { {"BL", bsk_download_partition_t::part_null, 64*1024}, {"MM", bsk_download_partition_t::part_null, 128*1024}, {"APP0", bsk_download_partition_t::part_null, 1*1024*1024}, {"APP1", bsk_download_partition_t::part_null, 1*1024*1024}, {"PL0", bsk_download_partition_t::part_null, 1*1024*1024}, {"PL1", bsk_download_partition_t::part_null, 1*1024*1024} } }, {"ZynQ", "0x95", 0, 0, 7, { {"BL", bsk_download_partition_t::part_null, 64*1024}, {"MM", bsk_download_partition_t::part_null, 128*1024}, {"OPER", bsk_download_partition_t::part_null, 1*1024*1024}, {"PL0", bsk_download_partition_t::part_null, 1*1024*1024}, {"PL1", bsk_download_partition_t::part_null, 1*1024*1024}, {"FPGA0", bsk_download_partition_t::part_null, 0}, {"FPGA1", bsk_download_partition_t::part_null, 0} } }, {"DSP", "0x54", 0, 0, 4, { {"BL", bsk_download_partition_t::part_fsbl|bsk_download_partition_t::part_hidden, 64*1024}, {"MM", bsk_download_partition_t::part_recovery|bsk_download_partition_t::part_hidden, 128*1024}, {"OPER", bsk_download_partition_t::part_operative|bsk_download_partition_t::part_default, 1*1024*1024}, {"APP2", 0, 1*1024*1024} } }, {"DSP", "0x54", 0, 0, 4, { {"BL", bsk_download_partition_t::part_fsbl|bsk_download_partition_t::part_hidden, 64*1024}, {"MM", bsk_download_partition_t::part_recovery|bsk_download_partition_t::part_hidden, 128*1024}, {"OPER", bsk_download_partition_t::part_operative|bsk_download_partition_t::part_default, 1*1024*1024}, {"APP2", 0, 1*1024*1024} } }, {"DSP", "0x54", 0, 0, 4, { {"BL", bsk_download_partition_t::part_fsbl|bsk_download_partition_t::part_hidden, 64*1024}, {"MM", bsk_download_partition_t::part_recovery|bsk_download_partition_t::part_hidden, 128*1024}, {"OPER", bsk_download_partition_t::part_operative|bsk_download_partition_t::part_default, 1*1024*1024}, {"APP2", 0, 1*1024*1024} } }, {"DSP", "0x54", 0, 0, 4, { {"BL", bsk_download_partition_t::part_fsbl|bsk_download_partition_t::part_hidden, 64*1024}, {"MM", bsk_download_partition_t::part_recovery|bsk_download_partition_t::part_hidden, 128*1024}, {"OPER", bsk_download_partition_t::part_operative|bsk_download_partition_t::part_default, 1*1024*1024}, {"APP2", 0, 1*1024*1024} } } }; class QgTftpTargetSim::Implementation { public: QString name; int site_id; QObject* parent; QUdpSocket tftpServer; //static Implementation* gInstance; QHostAddress clientAddress; int clientPort; //int timerId; QTimer storeTimer; QFile storeFile; QByteArray storeBuffer; bsk_download_partition_t* currentParitition; int store_time; int progr_time; bsk_tftpd_context_id_t id; const bsk_tftpd_context_info_t* tftpd_cx; int state; Implementation(const QString& n, int sid, QObject* p): name(n), site_id(sid), parent(p), tftpServer(p) { //gInstance=this; store_time=2*1000; progr_time=2*1000; storeTimer.setSingleShot(true); storeBuffer.reserve(1024*1024); currentParitition=0; state=0; } void processPendingDatagram() { while(tftpServer.hasPendingDatagrams()) { QNetworkDatagram d=tftpServer.receiveDatagram(); //qDebug()<<"RCV:"<name<port<100) n=100; if (n<0) n=-1; } sprintf(buffer, "%d %s", n, msg); return buffer; } static bsk_tftpd_receive_status_t bsk_tftpd_receive_delegate(bsk_tftpd_context_id_t id, bsk_tftpd_receive_delegate_operation_t op, const void* const data, unsigned int block, unsigned int offset, unsigned int size_bytes) { const bsk_tftpd_context_info_t* cx=bsk_tftpd_context_info(id); Implementation* gInstance=reinterpret_cast(cx->cookie); bsk_tftpd_receive_status_t sts={bsk_tftpd_ok, 0}; if (op==bsk_tftpd_open_read_not_supported) { if (strcmp(bsk_tftpd_mfs_status_query, (char*)data)==0) { if (gInstance->state==0) { sts.sts=bsk_tftpd_err_not_found; sts.ack_msg="ready"; } else if (gInstance->state==2) { sts.sts=bsk_tftpd_err_bad_id; sts.ack_msg=gInstance->progr_msg("Erasing"); } else if (gInstance->state==3) { sts.sts=bsk_tftpd_err_bad_id; sts.ack_msg=gInstance->progr_msg("Storing"); } else { sts.sts=bsk_tftpd_err_bad_id; sts.ack_msg="busy"; } } else if (strcmp(bsk_tftpd_mfs_list_query, (char*)data)==0) { sts.sts=bsk_tftpd_err_file_exists; sts.ack_msg=bsk_tftpd_mfs_get_list(id); } else sts.sts=bsk_tftpd_err_not_found; return sts; } if ((op==bsk_tftpd_open_file) && (gInstance->state>0)) { static QString reply_msg; static char cmsg[512]; sts.sts=bsk_tftpd_err_not_found; int remain=gInstance->storeTimer.remainingTime(); float store_completition=100*(5000.0f/(5000.0f-float(remain))); reply_msg=QString::asprintf("%u%% storing", int(store_completition)); strncpy(cmsg, reply_msg.toLatin1().constData(), sizeof cmsg); sts.ack_msg=0; //cmsg; qDebug()<currentParitition=0; bsk_download_partition_t* p=bsk_tftp_mfs_decode_filename(gInstance->site_id, (char*)data, &fname); if (p==bsk_tftp_mfs_invalid_partition) { sts.sts=bsk_tftpd_err_not_found; sts.ack_msg=0; return sts; } gInstance->state=1; if (p) { if (gInstance->storeFile.isOpen()) { qDebug()<<"WARNING:store file is open!!!"; gInstance->storeFile.close(); } //gInstance->storeFile.setFileName(QString("_%1_%2.dat").arg(gInstance->site_id).arg(p->name)); //gInstance->storeFile.open(QIODevice::WriteOnly); gInstance->storeBuffer.clear(); gInstance->storeBuffer.reserve(1024*1024); gInstance->currentParitition=p; } } else if (op==bsk_tftpd_data) { //if (gInstance->storeFile.isOpen()) //{ // gInstance->storeFile.write((char*)data, size_bytes); //} gInstance->storeBuffer.append((char*)data, size_bytes); } else if (op==bsk_tftpd_end) { //if (gInstance->storeFile.isOpen()) //{ // gInstance->storeFile.write((char*)data, size_bytes); // gInstance->storeFile.flush(); //close(); //} if (gInstance->currentParitition) { if (gInstance->storeBuffer.size()>gInstance->currentParitition->max_size) { sts.sts=bsk_tftpd_err_no_space; sts.ack_msg="file too big"; } else { if (size_bytes) gInstance->storeBuffer.append((char*)data, size_bytes); sts.sts=bsk_tftpd_dont_ack; gInstance->storeTimer.start(gInstance->store_time); gInstance->storeFile.setFileName(QString("_%1_%2.dat").arg(gInstance->site_id).arg(gInstance->currentParitition->name)); bool ok=gInstance->storeFile.open(QIODevice::WriteOnly); if (ok) { gInstance->storeFile.write(gInstance->storeBuffer); gInstance->storeFile.close(); gInstance->state=2; } else { sts.sts=bsk_tftpd_err_access; sts.ack_msg="error storing"; } } } else { gInstance->state=0; } } return sts; } static int bsk_tftpd_send_delegate(bsk_tftpd_context_id_t id, unsigned int adr, unsigned int port, const void* const data, unsigned int size) { const bsk_tftpd_context_info_t* cx=bsk_tftpd_context_info(id); Implementation* gInstance=reinterpret_cast(cx->cookie); QHostAddress ha(gInstance->clientAddress); int hp=gInstance->clientPort; if (adr) ha=QHostAddress(adr); if (port) hp=port; qDebug()<<"TFTP: send"<tftpServer.writeDatagram((char*)data, size, ha, hp); //gInstance->clientAddress, gInstance->clientPort); return 0; } }; //QgFtfpTargetSim::Implementation* QgFtfpTargetSim::Implementation::gInstance; QgTftpTargetSim::QgTftpTargetSim(const QString &name, int sid, int port): p_(*new Implementation(name, sid, this)) { bsk_tftpd_mfs_set_site(&sites[0], 3); p_.tftpServer.bind(QHostAddress::LocalHost, port); connect(&p_.tftpServer, &QUdpSocket::readyRead, this, pendingDatagram); char* kn=strdup(name.toLatin1().constData()); p_.id=bsk_tftpd_context_initialize(-1, kn, port, &p_); p_.tftpd_cx=bsk_tftpd_context_info(p_.id); bsk_tftpd_set_log_delegate(p_.id, Implementation::bsk_tftpd_log_delegate); bsk_tftpd_set_receive_delegate(p_.id, Implementation::bsk_tftpd_receive_delegate); bsk_tftpd_set_send_delegate(p_.id, Implementation::bsk_tftpd_send_delegate); connect(&p_.storeTimer, &QTimer::timeout, this, &timerExpired); } QgTftpTargetSim::~QgTftpTargetSim() { delete &p_; } void QgTftpTargetSim::pendingDatagram() { p_.processPendingDatagram(); } void QgTftpTargetSim::setEraseTime(int t) { p_.store_time=t*1000; } void QgTftpTargetSim::setProgTime(int t) { p_.progr_time=t*1000; } void QgTftpTargetSim::timerExpired() { if (p_.state==2) { p_.state=3; p_.storeTimer.start(p_.progr_time); } else if (p_.state==3) { p_.storeTimer.stop(); bsk_tftpd_send_ack(p_.id, bsk_tftpd_ok, 0); if (p_.storeFile.isOpen()) { qDebug()<<"File stored:"<timerId()==p_.timerId) { if (state==2) p_.timerId=0; bsk_tftpd_send_ack(p_.id, bsk_tftpd_ok, 0); } } #endif