#include "usbservice.h" #include #include #include #include #include "stringex.hpp" #include #include #include "usbdevice.h" #include "regsaccess.h" #include "usbtransmit.h" #include "usbreceive.h" #include "usbnotify.h" #include "applog.h" static const std::string loggername = "UsbService"; typedef struct { int Command; int Data; int Length; } USBCB; #define USB_REQ_GET_FPGA_REGS 0x40 #define USB_REQ_SET_FPGA_REGS 0x41 #define USB_REQ_GET_MOTOR_REGS 0x42 #define USB_REQ_SET_MOTOR_REGS 0x43 #define USB_REQ_ACCES_DEV_LOG 0x50 #define USB_REQ_GET_DEV_STATUS 0x60 #define USB_REQ_GET_DEV_CONFIGURATION 0x61 #define USB_REQ_SET_DEV_CONFIGURATION 0x62 #define USB_REQ_GET_DEV_REGS 0x63 #define USB_REQ_SET_DEV_REGS 0x64 #define USB_REQ_GET_DEV_LOG 0x65 #define USB_REQ_SET_DEV_LOG 0x66 static bool read_regs(unsigned int *regs, int regindex, int creg, std::shared_ptr ®sacess) { int index; for (int i = 0; i < creg; i++) { index = regindex + i; if (!regsacess->read(index, *(regs + i))) { LOG_ERROR(string_format("read error %d=%08x\n", index, regs[i])); return false; } LOG_TRACE(string_format("read %d=%08x\n", index, regs[i])); } return true; } static bool write_regs(unsigned int *regs, int regindex, int creg, std::shared_ptr ®sacess) { int index; for (int i = 0; i < creg; i++) { index = regindex + i; if (!regsacess->write(index, *(regs + i))) { LOG_ERROR(string_format("wirte error %d=%08x\n", index, regs[i])); return false; } LOG_TRACE(string_format("wirte %d=%08x\n", index, regs[i])); } return true; } UsbService::UsbService(std::shared_ptr fgparegs, std::shared_ptr motorregs, std::shared_ptr scannerregs) { LOG_INIT(); this->fgparegs = fgparegs; this->motorregs = motorregs; this->devregs = scannerregs; auto ctrl_handle = [&](int fd, struct usb_ctrlrequest *setup, unsigned char *buffer) -> bool { if (!(setup->bRequestType & USB_TYPE_VENDOR) || (setup->bRequestType & USB_RECIP_MASK) != USB_RECIP_DEVICE) return false; static std::string logstring; unsigned int *regs = (unsigned int *)buffer; int creg = 0; if (!(setup->wLength % 4)) creg = setup->wLength / 4; int regindex = setup->wValue; switch (setup->bRequest) { case USB_REQ_GET_FPGA_REGS: if ((setup->bRequestType & USB_DIR_IN) && creg && this->fgparegs) { if (!read_regs(regs, regindex, creg, this->fgparegs)) return false; ::write(fd, buffer, setup->wLength); return true; } break; case USB_REQ_SET_FPGA_REGS: if (!(setup->bRequestType & USB_DIR_IN) && creg && this->fgparegs) { ::read(fd, buffer, setup->wLength); if (!write_regs(regs, regindex, creg, this->fgparegs)) return false; return true; } break; case USB_REQ_GET_MOTOR_REGS: if ((setup->bRequestType & USB_DIR_IN) && creg && this->motorregs) { if (!read_regs(regs, regindex, creg, this->motorregs)) return false; ::write(fd, buffer, setup->wLength); return true; } break; case USB_REQ_SET_MOTOR_REGS: if (!(setup->bRequestType & USB_DIR_IN) && creg && this->motorregs) { ::read(fd, buffer, setup->wLength); if (!write_regs(regs, regindex, creg, this->motorregs)) return false; return true; } break; case USB_REQ_GET_DEV_REGS: if ((setup->bRequestType & USB_DIR_IN) && creg && this->devregs) { //printf("ctrl read USB_REQ_GET_DEV_REGS addr = %d ->start \n",regindex); if (!read_regs(regs, regindex, creg, this->devregs)) return false; ::write(fd, buffer, setup->wLength); //printf("ctrl read USB_REQ_GET_DEV_REGS addr = %d ->end\n",regindex); return true; } break; case USB_REQ_SET_DEV_REGS: if (!(setup->bRequestType & USB_DIR_IN) && creg && this->devregs) { //printf("ctrl write USB_REQ_SET_DEV_REGS addr = %d ->start\n",regindex); ::read(fd, buffer, setup->wLength); if (!write_regs(regs, regindex, creg, this->devregs)) return false; //printf("ctrl write USB_REQ_SET_DEV_REGS addr = %d ->end\n",regindex); return true; } break; case USB_REQ_ACCES_DEV_LOG: if (setup->wLength != 64) return false; if (!(setup->bRequestType & USB_DIR_IN)) { ::read(fd, buffer, setup->wLength); buffer[64 - 1] = 0; logstring = (char *)buffer; return true; } else { memset(buffer, 0, 64); if (!logstring.empty()) memcpy(buffer, logstring.data(), logstring.size()); ::write(fd, buffer, setup->wLength); return true; } break; case USB_REQ_GET_DEV_LOG: if ((setup->wLength == 4) && (setup->bRequestType & USB_DIR_IN) && log_get_level(logstring, regindex, *((int *)regs))) { ::write(fd, buffer, setup->wLength); return true; } break; case USB_REQ_SET_DEV_LOG: if ((setup->wLength == 4) && !(setup->bRequestType & USB_DIR_IN)) { ::read(fd, buffer, setup->wLength); return log_set_level(logstring, regindex, *((int *)regs)); } break; default: break; } return false; }; auto connected_call = [this](bool connected) { notify()->clear(); if (m_usbconnect) m_usbconnect(connected); LOG_TRACE(string_format("connect status:%s", connected ? "connected" : "disconnect")); }; usb.reset(new UsbDevice(ctrl_handle, connected_call)); } UsbService::~UsbService() { } std::shared_ptr UsbService::transmiter() { // if(transmit.get()) // { // transmit.reset(); // } // transmit.reset(new UsbTransmit(usb)); // return transmit; return transmit ? transmit : (transmit = std::shared_ptr(new UsbTransmit(usb))); } std::shared_ptr UsbService::receiver() { // if(receiv.get()) // { // receiv.reset(); // } // receiv.reset(new UsbReceive(usb)); // return receiv; return receiv ? receiv : (receiv = std::shared_ptr(new UsbReceive(usb))); } void UsbService::set_scannerregs(std::shared_ptr scannerregs) { this->devregs = scannerregs; } std::shared_ptr UsbService::notify() { return noti ? noti : (noti = std::shared_ptr(new UsbNotify(usb))); } void UsbService::set_onconnect_call(std::function usbhotplugcall) { m_usbconnect = usbhotplugcall; }