diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index f3632d7..3b3d018 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -281,6 +281,8 @@ set(SLIC3R_GUI_SOURCES Utils/PrintHost.hpp Utils/Bonjour.cpp Utils/Bonjour.hpp + Utils/UdpLinkServer.cpp + Utils/UdpLinkServer.hpp Utils/PresetUpdater.cpp Utils/PresetUpdater.hpp Utils/Process.cpp diff --git a/src/slic3r/GUI/BonjourDialog.cpp b/src/slic3r/GUI/BonjourDialog.cpp index 060643c..65cf7af 100644 --- a/src/slic3r/GUI/BonjourDialog.cpp +++ b/src/slic3r/GUI/BonjourDialog.cpp @@ -20,6 +20,91 @@ #include "slic3r/GUI/format.hpp" #include "slic3r/Utils/Bonjour.hpp" +// B29 +#include "slic3r/Utils/UdpLinkServer.hpp" +#include +#include + +const int MAX_BUF_LEN = 255; +#define GET_HOST_COMMAND "mkswifi\r\n" +#define CLIENT_PORT 11121 +#define SERVER_PORT 8989 + +// B29 + +typedef struct tagDeviceInfo +{ + unsigned short usFunction; + unsigned short usVersionFlag; + unsigned int uiCompanyId; + char szDeviceSerialNo[24]; + unsigned short usServicePort; + char szExtend[38]; +} DeviceInfo; + +// B29 + +typedef struct tagWorkThreadParameter +{ + boost::asio::io_service *pIoService; + UdpLinkServer * pUdpService; +} WorkThreadParameter; + +bool g_WorkThreadExit = false; +int g_nBroastDataSendInteral = 3000; +DeviceInfo g_diDeviceInfo = {0}; +std::vector get_reply; +// B29 + +unsigned int __stdcall WorkThreadFunByDeviceServiceProcess(PVOID pParam) +{ + int nn = 0; + int nDataSize = sizeof(DeviceInfo); + WorkThreadParameter *pAllParameter = (WorkThreadParameter *) pParam; + while (true) { + if (g_WorkThreadExit) { + break; + } + + pAllParameter->pUdpService->SendData((char *) GET_HOST_COMMAND, nDataSize, true); + pAllParameter->pIoService->poll(); + // break; + for (nn = g_nBroastDataSendInteral; nn > 0; nn -= 200) { + if (g_WorkThreadExit) { + break; + } + Sleep(200); + } + } + return 0; +} +// B29 + +static void WINAPI BroastDeviceInfoRecvDataCallback(const boost::system::error_code &error, + char * pData, + int nDataLength, + char * pPeerIp, + unsigned short usPeerPort, + DWORD dwUserData1, + DWORD dwUserData2) +{ + SYSTEMTIME sm; + GetLocalTime(&sm); + char szInfo[256] = {0}; + DeviceInfo *pDeviceInfo = (DeviceInfo *) pData; + //sprintf(szInfo, "%s %s:%d time:%04d-%02d-%0d %02d:%02d:%02d\n", pData, pPeerIp, usPeerPort, sm.wYear, sm.wMonth, sm.wDay, sm.wHour, + // sm.wMinute, sm.wSecond); + //printf(szInfo); + int i = 0; + for (i = 0; i < get_reply.size(); i++) + if (get_reply[i] == pData) + break; + if (i == get_reply.size()) + get_reply.push_back(pData); +} + + + namespace Slic3r { @@ -72,8 +157,9 @@ BonjourDialog::BonjourDialog(wxWindow *parent, Slic3r::PrinterTechnology tech) list->SetSingleStyle(wxLC_SINGLE_SEL); list->SetSingleStyle(wxLC_SORT_DESCENDING); - list->AppendColumn(_(L("Address")), wxLIST_FORMAT_LEFT, 5 * em); - list->AppendColumn(_(L("Hostname")), wxLIST_FORMAT_LEFT, 10 * em); + //B29 + list->AppendColumn(_(L("Address")), wxLIST_FORMAT_LEFT, 10 * em); + list->AppendColumn(_(L("Hostname")), wxLIST_FORMAT_LEFT, 15 * em); list->AppendColumn(_(L("Service name")), wxLIST_FORMAT_LEFT, 20 * em); if (tech == ptFFF) { list->AppendColumn(_(L("OctoPrint version")), wxLIST_FORMAT_LEFT, 5 * em); @@ -91,9 +177,15 @@ BonjourDialog::BonjourDialog(wxWindow *parent, Slic3r::PrinterTechnology tech) Bind(EVT_BONJOUR_REPLY, &BonjourDialog::on_reply, this); - Bind(EVT_BONJOUR_COMPLETE, [this](wxCommandEvent &) { - this->timer_state = 0; - }); + // B29 + Bind(EVT_BONJOUR_COMPLETE, [this](wxCommandEvent &) { + this->timer_state = 0; + g_WorkThreadExit = true; + for (int n = 0; n < get_reply.size(); n++) { + auto item = list->InsertItem(0, get_reply[n].substr(get_reply[n].find_last_of(",") + 1)); + list->SetItem(item, 1, get_reply[n].substr(get_reply[n].find("mkswifi:") + 8, get_reply[n].find(",") - 8)); + } + }); Bind(wxEVT_TIMER, &BonjourDialog::on_timer, this); GUI::wxGetApp().UpdateDlgDarkUI(this); @@ -114,6 +206,22 @@ bool BonjourDialog::show_and_lookup() timer->Start(1000); on_timer_process(); + // B29 + g_WorkThreadExit = false; + boost::asio::io_service ioService; + UdpLinkServer usUdpService(8989, true); + usUdpService.SetRecvDataCallback(true, BroastDeviceInfoRecvDataCallback, 0, 0); + usUdpService.Start(ioService); + g_diDeviceInfo.usFunction = 1; + g_diDeviceInfo.usVersionFlag = 0x0001; + strcpy(g_diDeviceInfo.szDeviceSerialNo, "ABCDEFG111111111"); + g_diDeviceInfo.usServicePort = 8989; + + WorkThreadParameter wtpWorkThreadParameter; + wtpWorkThreadParameter.pIoService = &ioService; + wtpWorkThreadParameter.pUdpService = &usUdpService; + boost::thread thrd(WorkThreadFunByDeviceServiceProcess, &wtpWorkThreadParameter); + // The background thread needs to queue messages for this dialog // and for that it needs a valid pointer to it (mandated by the wxWidgets API). // Here we put the pointer under a shared_ptr and protect it by a mutex, diff --git a/src/slic3r/Utils/UdpLinkServer.cpp b/src/slic3r/Utils/UdpLinkServer.cpp new file mode 100644 index 0000000..1f66f48 --- /dev/null +++ b/src/slic3r/Utils/UdpLinkServer.cpp @@ -0,0 +1,166 @@ +//#include "StdAfx.h" +#include "UdpLinkServer.hpp" +#include + +UdpLinkServer::UdpLinkServer(unsigned short usPort, bool bBroadcast) +{ + m_bStop = false; + m_bBroadcast = bBroadcast; + m_usPort = usPort; + m_sockUdp = NULL; + m_bAutoRecvData = true; + m_pfuncRecvDataCallback = NULL; + m_dwRecvDataCallbackUserData1 = 0; + m_dwRecvDataCallbackUserData2 = 0; +} + +UdpLinkServer::~UdpLinkServer(void) +{ + if (m_sockUdp != NULL) { + m_sockUdp->close(); + delete m_sockUdp; + m_sockUdp = NULL; + } +} + +void UdpLinkServer::SetRecvDataCallback(bool bAutoRecvData, RecvDataCallback pfunc, DWORD dwUserData1, DWORD dwUserData2) +{ + m_bAutoRecvData = bAutoRecvData; + m_pfuncRecvDataCallback = pfunc; + m_dwRecvDataCallbackUserData1 = dwUserData1; + m_dwRecvDataCallbackUserData2 = dwUserData2; +} + +int UdpLinkServer::Start(boost::asio::io_service &ioService) +{ + try { + if (m_bBroadcast) { + m_sockUdp = new udp::socket(ioService, udp::endpoint(udp::v4(), 0)); + m_sockUdp->set_option(boost::asio::socket_base::reuse_address(true)); + m_sockUdp->set_option(boost::asio::socket_base::broadcast(true)); + m_endpointBroadcast = udp::endpoint(boost::asio::ip::address_v4::broadcast(), m_usPort); + } else { + m_sockUdp = new udp::socket(ioService, udp::endpoint(udp::v4(), m_usPort)); + if (!m_sockUdp->is_open()) { + return -1; + } + m_sockUdp->set_option(boost::asio::socket_base::reuse_address(true)); + } + + } catch (boost::exception &e) { + return -1; + } + + m_bStop = false; + if (m_bAutoRecvData) { + RecvDataProcess(m_pfuncRecvDataCallback, m_dwRecvDataCallbackUserData1, m_dwRecvDataCallbackUserData2); + } + return 0; +} + +int UdpLinkServer::Stop() +{ + m_bStop = true; + + return 0; +} + +bool UdpLinkServer::IsStop() { return m_bStop; } + +udp::endpoint &UdpLinkServer::GetBroadcastEndPoint() { return m_endpointBroadcast; } + +void UdpLinkServer::SendDataCallbackOuter(const boost::system::error_code &error, + std::size_t bytes_transferred, + DWORD dwUserData1, + DWORD dwUserData2) +{ + int i = 0; +} + +int UdpLinkServer::SendDataEx( + udp::endpoint endpointRemote, char *pBuffer, int nBufferSize, SendDataCallback pfunc, DWORD dwUserData1, DWORD dwUserData2) +{ + m_sockUdp->async_send_to(boost::asio::buffer(pBuffer, nBufferSize), endpointRemote, + boost::bind(&UdpLinkServer::handleSendDataInner, this, pfunc, dwUserData1, dwUserData2, + boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + + return 0; +} + +int UdpLinkServer::SendData(char *pBuffer, int nBufferSize, bool bAsync) +{ + if (!m_bBroadcast) { + if (bAsync) { + m_sockUdp->async_send_to(boost::asio::buffer(pBuffer, nBufferSize), m_endpointRemote, + boost::bind(&UdpLinkServer::handleSendData, this, pBuffer, nBufferSize, + boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + } else { + m_sockUdp->send_to(boost::asio::buffer(pBuffer, nBufferSize), m_endpointRemote); + } + } else { + if (bAsync) { + m_sockUdp->async_send_to(boost::asio::buffer(pBuffer, nBufferSize), m_endpointBroadcast, + boost::bind(&UdpLinkServer::handleSendData, this, pBuffer, nBufferSize, + boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + } else { + m_sockUdp->send_to(boost::asio::buffer(pBuffer, nBufferSize), m_endpointBroadcast); + } + } + + return 0; +} + +void UdpLinkServer::RecvDataProcess(RecvDataCallback pfunc, DWORD dwUserData1, DWORD dwUserData2) +{ + m_sockUdp->async_receive_from(boost::asio::buffer(m_recvBuf), m_endpointRemote, + boost::bind(&UdpLinkServer::handleRecvData, this, boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred, pfunc, dwUserData1, dwUserData2)); +} + +void UdpLinkServer::handleRecvDataByManual(RecvDataCallback pfunc, DWORD dwUserData1, DWORD dwUserData2) +{ + if (IsStop()) + return; + + RecvDataProcess(pfunc, dwUserData1, dwUserData2); +} + +void UdpLinkServer::handleRecvData( + const boost::system::error_code &error, std::size_t bytes_transferred, RecvDataCallback pfunc, DWORD dwUserData1, DWORD dwUserData2) +{ + if (IsStop()) + return; + + if (!error || error == boost::asio::error::message_size) { + if (bytes_transferred > UDP_DATA_PACKAGE_MAX_LENGTH) { + return; + } + + if (pfunc != NULL) { + pfunc(error, m_recvBuf.data(), bytes_transferred, (char *) m_endpointRemote.address().to_string().c_str(), + m_endpointRemote.port(), dwUserData1, dwUserData2); + } + + RecvDataProcess(pfunc, dwUserData1, dwUserData2); + } else { + if (pfunc != NULL) { + pfunc(error, NULL, bytes_transferred, NULL, 0, dwUserData1, dwUserData2); + } + } +} + +void UdpLinkServer::handleSendData(char *pBuffer, int nBufferSize, const boost::system::error_code &error, std::size_t bytes_transferred) +{ + int n = 0; +} +void UdpLinkServer::handleSendDataInner( + SendDataCallback pfunc, DWORD dwUserData1, DWORD dwUserData2, const boost::system::error_code &error, std::size_t bytes_transferred) +{ + //if (error != NULL) { + printf("%s", boost::system::system_error(error).what()); + //} + //if (pfunc != NULL) { + pfunc(error, bytes_transferred, dwUserData1, dwUserData2); + //} + int n = 0; +} diff --git a/src/slic3r/Utils/UdpLinkServer.hpp b/src/slic3r/Utils/UdpLinkServer.hpp new file mode 100644 index 0000000..20c800e --- /dev/null +++ b/src/slic3r/Utils/UdpLinkServer.hpp @@ -0,0 +1,87 @@ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +using boost::asio::ip::udp; + +#define UDP_DATA_PACKAGE_MAX_LENGTH 1024 + +typedef void(CALLBACK *SendDataCallback)(const boost::system::error_code &error, + std::size_t bytes_transferred, + DWORD dwUserData1, + DWORD dwUserData2); +typedef void(CALLBACK *RecvDataCallback)(const boost::system::error_code &error, + char * pData, + int nDataLength, + char * pPeerIp, + unsigned short usPeerPort, + DWORD dwUserData1, + DWORD dwUserData2); + +class UdpLinkServer +{ +public: + UdpLinkServer(unsigned short usPort, bool bBroadcast); + virtual ~UdpLinkServer(void); + + typedef boost::function< + void *(const boost::system::error_code &error, std::size_t bytes_transferred, DWORD dwUserData1, DWORD dwUserData2)> + SendDataCallbackHandler; + + void SetRecvDataCallback(bool bAutoRecvData, RecvDataCallback pfunc, DWORD dwUserData1, DWORD dwUserData2); + + int Start(boost::asio::io_service &ioService); + + int Stop(); + + int SendDataEx( + udp::endpoint endpointRemote, char *pBuffer, int nBufferSize, SendDataCallback pfunc, DWORD dwUserData1, DWORD dwUserData2); + + int SendData(char *pBuffer, int nBufferSize, bool bAsync); + + udp::endpoint &GetBroadcastEndPoint(); + + void handleRecvDataByManual(RecvDataCallback pfunc = NULL, DWORD dwUserData1 = 0, DWORD dwUserData2 = 0); + void handleSendData(char *pBuffer, int nBufferSize, const boost::system::error_code &error, std::size_t bytes_transferred); + void handleSendDataInner(SendDataCallback pfunc, + DWORD dwUserData1, + DWORD dwUserData2, + const boost::system::error_code &error, + std::size_t bytes_transferred); + // void handleSendData(boost::shared_ptr strMessage,const boost::system::error_code& error,std::size_t bytes_transferred); + + static void WINAPI SendDataCallbackOuter(const boost::system::error_code &error, + std::size_t bytes_transferred, + DWORD dwUserData1, + DWORD dwUserData2); + +protected: + void RecvDataProcess(RecvDataCallback pfunc, DWORD dwUserData1, DWORD dwUserData2); + void handleRecvData(const boost::system::error_code &error, + std::size_t bytes_transferred, + RecvDataCallback pfunc, + DWORD dwUserData1, + DWORD dwUserData2); + + bool IsStop(); + +private: + udp::socket * m_sockUdp; + udp::endpoint m_endpointRemote; + udp::endpoint m_endpointBroadcast; + boost::array m_recvBuf; + bool m_bStop; + bool m_bBroadcast; + unsigned short m_usPort; + bool m_bAutoRecvData; + RecvDataCallback m_pfuncRecvDataCallback; + DWORD m_dwRecvDataCallbackUserData1; + DWORD m_dwRecvDataCallbackUserData2; +}; \ No newline at end of file