From ee7af5a45bad7adb9cd1bdd416d63b412cbe456e Mon Sep 17 00:00:00 2001 From: TAO Cheng Date: Wed, 29 Oct 2014 21:38:54 +0800 Subject: [PATCH] Add handshaking. --- .../Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.cpp | 149 +++++++----------- .../Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h | 7 +- .../Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc | 5 +- .../UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.cpp | 20 ++- .../UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.h | 1 + .../Hsi/Tools/UsbUtility/UsbUtil/resource.h | 3 +- .../Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo | Bin 150016 -> 150016 bytes 7 files changed, 77 insertions(+), 108 deletions(-) diff --git a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.cpp b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.cpp index 6e6867e..502a3ab 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.cpp +++ b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.cpp @@ -7,12 +7,15 @@ const int WSA_MAJOR_VERSION = 1; const int WSA_MINOR_VERSION = 1; #define WSA_VERSION MAKEWORD(WSA_MAJOR_VERSION, WSA_MINOR_VERSION) #define SOCKADDR_LEN sizeof(SOCKADDR_IN) +const char BufferHeader[4]={0x46,0x49,0x4E,0x53}; +const char HandShaking[]={0x46,0x49,0x4E,0x53,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; int CSo7_TCPIP::m_iReceiveMaxBufSize=1024; int CSo7_TCPIP::m_iSendMaxBufSize=1024; SOCKET CSo7_TCPIP::m_Socket=INVALID_SOCKET; in_addr CSo7_TCPIP::m_SreverIPAddress; +in_addr CSo7_TCPIP::m_ClientIPAddress; u_short CSo7_TCPIP::m_iServerPortNumber=static_cast(0); //================================================================ @@ -85,6 +88,7 @@ TCPIP_RETURN_CODE CSo7_TCPIP::Connect(const HWND& _hWnd,const in_addr& _IPAddres // 填写服务器地址信息 sockaddr_in remote; + m_SreverIPAddress = _IPAddress; remote.sin_addr = _IPAddress; remote.sin_family = AF_INET; remote.sin_port = htons(m_iServerPortNumber); @@ -95,6 +99,7 @@ TCPIP_RETURN_CODE CSo7_TCPIP::Connect(const HWND& _hWnd,const in_addr& _IPAddres errorCode = WSAGetLastError(); rCode=(TCPIP_RETURN_CODE)errorCode; } + GetHostIPAddr(m_ClientIPAddress); } return rCode; } @@ -112,41 +117,41 @@ TCPIP_RETURN_CODE CSo7_TCPIP::DisConnect() //================================================================ TCPIP_RETURN_CODE CSo7_TCPIP::GetHostIPAddr(in_addr& _IPAddress) { - if(m_Socket == INVALID_SOCKET) + static int first = TRUE; + if (first) { - return TCPIP_INVAILD_SOCKET; + if(m_Socket == INVALID_SOCKET) + { + return TCPIP_INVAILD_SOCKET; + } + char HostName[100]; + gethostname(HostName,sizeof(HostName)); + hostent *pAddr; + pAddr=gethostbyname(HostName); + memcpy(&m_ClientIPAddress,pAddr->h_addr_list[0],sizeof(in_addr)); + _IPAddress=m_ClientIPAddress; + first = FALSE; } - char HostName[100]; - gethostname(HostName,sizeof(HostName)); - hostent *pAddr; - pAddr=gethostbyname(HostName); - memcpy(&_IPAddress,pAddr->h_addr_list[0],sizeof(in_addr)); + _IPAddress=m_ClientIPAddress; return TCPIP_CONNECT_OK; } //================================================================ -TCPIP_RETURN_CODE CSo7_TCPIP::Send(int _Addr,int _Data) +TCPIP_RETURN_CODE CSo7_TCPIP::Handshaking() { - _Addr=0; - _Data=0; - if(m_Socket == INVALID_SOCKET) - { - return TCPIP_INVAILD_SOCKET; - } - int i, errorCode, numBytesSent; - unsigned long numDataBytes; - SOCKET s = m_Socket; - m_iBytesSent = 0; - m_iBytesToSend = sizeof(unsigned long) + 1; - numDataBytes = htonl(m_iBytesToSend); - for(i=0;i=m_iBytesToSend) { m_iBytesSent = 0; - clearSendBuf(); + m_ClearSendBuf(); break; } } @@ -267,86 +285,27 @@ void CSo7_TCPIP::m_ProcessSocketWriteEvent(void) void CSo7_TCPIP::m_ProcessSocketReadEvent(SOCKET s) { int bytesReceived=0; - int headerSize = sizeof(unsigned long) + sizeof(char); int errorCode; - if(true) - { - unsigned long *numBytesPtr; - bytesReceived = recv(s, &(m_ReceiveBuf[m_iBytesReceived]), headerSize-m_iBytesReceived, 0); - if(bytesReceived == SOCKET_ERROR) - { - errorCode = WSAGetLastError(); - if (errorCode == WSAEWOULDBLOCK) - { - //have to wait for the next receive event - return; - } - else - { - //showSocketError(errorCode); - return; - } - } - m_iBytesReceived += bytesReceived; - if(m_iBytesReceived < sizeof(unsigned long) + sizeof(char)) - {//like this will ever happen... Have to wait for the next receive event - return; - } - numBytesPtr = (unsigned long*) &(m_ReceiveBuf[0]); - m_iBytesToReceive = ntohl(*numBytesPtr); - m_iBytesReceived = 0; - - //allocate memory for the character or the double array - if(true) - { - if(m_dReceiveDBuf) - {//clean memory because returning - delete [] m_dReceiveDBuf; - m_dReceiveDBuf = NULL; - } - m_iReceiveDBufSize = m_iBytesToReceive/(sizeof(double)); - m_dReceiveDBuf = new double[m_iReceiveDBufSize]; - memset (m_dReceiveDBuf,m_iReceiveDBufSize*sizeof(double),0); // PR#254048 - } - } - - //The header has been received. Now we need to get the data - if(true) - { - bytesReceived = recv(s, &(((char*)m_dReceiveDBuf)[m_iBytesReceived]), - m_iBytesToReceive - m_iBytesReceived, 0); - } + bytesReceived = recv(s, &(m_ReceiveBuf[0]), m_iReceiveMaxBufSize, 0); if(bytesReceived == SOCKET_ERROR) { errorCode = WSAGetLastError(); - if (errorCode == WSAEWOULDBLOCK) - {//have to wait for the next receive event + { + //have to wait for the next receive event return; } else { - if(m_dReceiveDBuf) - {//clean memory because returning - delete [] m_dReceiveDBuf; - m_dReceiveDBuf = NULL; - m_iReceiveDBufSize = 0; - } //showSocketError(errorCode); return; } } m_iBytesReceived += bytesReceived; - if(m_iBytesReceived >= m_iBytesToReceive) - { - //we are done, reset the variables for next data and clean up - m_iBytesReceived = 0; - m_iBytesToReceive = 0; - if(m_dReceiveDBuf) - { - delete [] m_dReceiveDBuf; - m_dReceiveDBuf = NULL; - m_iReceiveDBufSize = 0; - } + if(m_iBytesReceived < sizeof(unsigned long) + sizeof(char)) + {//like this will ever happen... Have to wait for the next receive event + return; } + m_iBytesToReceive = m_iBytesReceived; + m_iBytesReceived = 0; } diff --git a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h index 1b3e57c..455a111 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h +++ b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h @@ -34,6 +34,7 @@ public: TCPIP_RETURN_CODE Recv(int _Addr,int& _Data,bool _bWait); TCPIP_RETURN_CODE DisConnect(); TCPIP_RETURN_CODE GetHostIPAddr(in_addr& _IPAddress); + TCPIP_RETURN_CODE Handshaking(); LRESULT OnSocket(WPARAM wParam, LPARAM lParam); @@ -51,9 +52,11 @@ private: static SOCKET m_Socket; static in_addr m_SreverIPAddress; + static in_addr m_ClientIPAddress; static u_short m_iServerPortNumber; - - void clearSendBuf(); + + TCPIP_RETURN_CODE SendBuffer(); + void m_ClearSendBuf(); int Init_Winsock(); void m_ProcessSocketWriteEvent(); diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc index 9e4f3b7..f7a9ed6 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc @@ -1043,8 +1043,8 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN PUSHBUTTON "Exit",IDCANCEL,292,230,39,14 GROUPBOX "TCP/IP Control",IDC_STATIC,17,12,87,81 - PUSHBUTTON "Connect",IDC_BUTTON_PLC_TCPIP_CONNECT,29,29,63,18 - PUSHBUTTON "Disconnect",IDC_BUTTON_PLC_TCPIP_DISCONNECT,29,64,63,18 + PUSHBUTTON "Connect",IDC_BUTTON_PLC_TCPIP_CONNECT,28,28,63,18 + PUSHBUTTON "Disconnect",IDC_BUTTON_PLC_TCPIP_DISCONNECT,28,70,63,18 EDITTEXT IDC_EDIT_MSG,19,97,265,130,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL PUSHBUTTON "Clear",IDC_BUTTON_PLC_TCPIP_CLEAR_MSG,289,156,39,14 PUSHBUTTON "Read Data",IDC_BUTTON_PLC_TCPIP_READ,203,30,63,18 @@ -1054,6 +1054,7 @@ BEGIN LTEXT "Addr",IDC_STATIC,116,35,16,8 EDITTEXT IDC_EDIT_PLC_TCPIP_Data,141,61,40,14,ES_AUTOHSCROLL LTEXT "Data",IDC_STATIC,116,64,16,8 + PUSHBUTTON "Handshaking",IDC_BUTTON_PLC_TCPIP_HANDSHAKING,28,49,63,18 END diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.cpp b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.cpp index c258f32..6984f47 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.cpp +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.cpp @@ -40,6 +40,7 @@ BEGIN_MESSAGE_MAP(CSo7_Util_PLC_TCPIP, CDialog) ON_BN_CLICKED(IDCANCEL, &CSo7_Util_PLC_TCPIP::OnBnClickedCancel) ON_MESSAGE(WM_SOCKET,&CSo7_Util_PLC_TCPIP::OnSocket) ON_BN_CLICKED(IDCANCEL, &CSo7_Util_PLC_TCPIP::OnBnClickedCancel) + ON_BN_CLICKED(IDC_BUTTON_PLC_TCPIP_HANDSHAKING, &CSo7_Util_PLC_TCPIP::OnBnClickedButtonPlcTcpipHandshaking) END_MESSAGE_MAP() @@ -74,12 +75,18 @@ void CSo7_Util_PLC_TCPIP::OnBnClickedButtonPlcTcpipRead() ; } +void CSo7_Util_PLC_TCPIP::OnBnClickedButtonPlcTcpipHandshaking() +{ + TCPIP_RETURN_CODE rCode=g_pSo7_TCPIP->Handshaking(); + m_csMSG.Format(_T("Handshaking return code:%d."),rCode); + OutputWithScroll(m_csMSG,m_edMSG); +} void CSo7_Util_PLC_TCPIP::OnBnClickedButtonPlcTcpipWrite() { - //TCPIP_RETURN_CODE rCode=g_pSo7_TCPIP->Send(1001,0); - //m_csMSG.Format(_T("Connect return code:%d."),rCode); - //OutputWithScroll(m_csMSG,m_edMSG); + TCPIP_RETURN_CODE rCode=g_pSo7_TCPIP->Send(1001,0); + m_csMSG.Format(_T("Write return code:%d."),rCode); + OutputWithScroll(m_csMSG,m_edMSG); } @@ -119,11 +126,8 @@ void CSo7_Util_PLC_TCPIP::OutputWithScroll(const CString &strNewText,CEdit &edtO LRESULT CSo7_Util_PLC_TCPIP::OnSocket(WPARAM w, LPARAM p) { LRESULT lResult=0; - UNREFERENCED_PARAMETER(w); - UNREFERENCED_PARAMETER(p); - /* if( g_pSo7_TCPIP ) lResult = g_pSo7_TCPIP->OnSocket(w,p); - */ + return( lResult ); -} \ No newline at end of file +} diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.h b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.h index f8d6ddd..6118f4f 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.h +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP.h @@ -28,4 +28,5 @@ public: afx_msg void OnBnClickedButtonPlcTcpipClearMsg(); afx_msg void OnBnClickedCancel(); afx_msg LRESULT OnSocket(WPARAM w, LPARAM p); + afx_msg void OnBnClickedButtonPlcTcpipHandshaking(); }; diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h index 38cd0bd..699d3c5 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h @@ -1053,8 +1053,9 @@ #define IDC_BUTTON_PLC_TCPIP_WRITE 1886 #define IDC_EDIT_PLC_TCPIP_ADDR 1887 #define IDC_EDIT_MSG 1888 -#define IDC_EDIT_PLC_TCPIP_ADDR2 1889 #define IDC_EDIT_PLC_TCPIP_Data 1889 +#define IDC_BUTTON_PLC_TCPIP_CONNECT2 1890 +#define IDC_BUTTON_PLC_TCPIP_HANDSHAKING 1890 #define IDC_BUTTON_DIY_EXIT_BUTTON 32740 #define ID_EDIT_SO7_CONFIG_MOTION 32741 diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo index 13dc108e3d068ae58f7c16d9c358224f178e0094..c3df894b1b2a5aa9814ab8d8fb02641be216c094 100644 GIT binary patch delta 2572 zcmb_ec~q3w6@T~5;taw#EaHYb!zPJd#dOyUTr0F01qwk#iy*qEY z+xy*n$Gy|+-f6CXS#MZSf8pS(%4+=w29uXZs1SnMLm^5j_t~kVYwtrWbv1*79M{1P zYp@_S7j4=8SYnB#%T4ejDvp=mLuZ6Zxo`OlFg0{yL%>f!&h$|#0y}gu4v`>SB2hR* zs)*;W5F?pZiW2c%u|)ikX}S0@f3w9}@glxAY%Jay7Q|$wu2RrbyGxodzuklmy-~R} zY&lTQT!`1Rh)wv)i0NkVXI97b)a2d~z9u985~2`~y)lD4_du^)3N->9jg@awW1w^? zo5L#rOZ?|j+Xy+B+>>AuY{u8(!_X0IQ{0hH%(7Krg=4xYki}@m_KP--VlJr+zi>>$ z^TRXH9hYMU3$Fz{JE8Q(S&YUBWkMJPF373DcT!^z(^gW!Rmj4lJCmUU7v|(u8ba~l z%@8Fsy~Rk`6>x$)OTmbZSuUKFnuqNxBO|jC;}cR-9XT;+*-6`&I1lJp8-p8mxX|5eQ8t`1fFX{>*_B_YCwwYfPW$)f4ZpI-$G_v; z#N%IG+41LAJ!btSQ0Z(52dbSc!;}ThHGsB7AsBMO-f(HWW$49yyY?k`pOnS@VD{DB zQ*KyUn%7HCH>^;Obo3hh#te9<&B4lVI$r>CrpQRuFIffvuD!SgYc2%RwiH>Wyz$X# zAnO!4Uzy(>B8^X^5PDE5?lznBeVkk9d=RAvhAY1Oz^2!-4Yxm-I!@i`yw(}?+h z^8D2R@8y|6PFW9OvXc4NW&=V|gtDk>FQBtA8J!;+$&)3W=q&M9-s-K_HGFXzhCb#y z51GDX`h-an+NWIoa+r=bZG==RH9#_D>R~wE?W?NV4z`mv=+dF}x|Isbz=lV>k+7cP zj=@TLFjQIx2@%awI?3)2XVG&jguMu+o*tNT$_O1gYWBkOw6O<@)FK}^XohZDoi2Zm z>+gi~O&i}V!}kx^sVfNP!D+0$y{|49BB>?_#z3`}edJsN#Z)s1LI$$Y8o3NU(X^>m zlOdE2z6l|iX)vm;OlZ^v=JpqjRia!(i8*4H$PqKhJ4hY{51li?S=F5bEe8D%)=ORE z*c*r5m&&KXR*dR)ut8D0(MS*kwN#t|Hd@RV(cSSpbsvK!9?}HW=Gv-Fw$>lf)TE3eqJHpKZ1!P;!nqC!iO}b2Yj*XvWbd6g#B1^IgzH% zf)KT!09J&-Jk2+t6k=mPVhL&e)f~j~TM4H!gflL=gqJX@sAVLk_ z1UG{HGct02TJoou-S^fc;Rl5mKaC~W0zs;MH@u*S8v|kgY$SEnuz6eiE1Na4fIi*F zp&oe9m>_9oYZJ&@3%8+?W*5NE{nl|MUL|6M=Ceif;~X|Uj#Qftz;qq`tp}b|-V9g6 z-+=%L1~ugfTn3EKD%Ii_q^^1d$vWKF5v6JYlvL6HqtyEi9AK;u4WeyhIE?6soH_tmeC;2>=w3ERDST1~YFoC92U_0=iR4U{!)g5;I9u1n-L07)8B2pL z)L9F@cI)4D@W*BV1N|TeE_kch7oUSKk!nJSU%1B2Pn8)EYQpQJ+L~)~FjrLgc z;s1|uPThqR&t|CkZ^Ic-84c|gXhgU)nH&$HfZBFJEGOGGhK@G0c><9a#@j=fohlYG zvKEUqjID*@rGA_(sUuTYg!^+96<7aFIvB(rXH|T(dQ6OKeK|1 z&b2}oZExiy`vz*u;99?vw!Ppy#U zvabj0720u~3x@R`3^lCCO)r{Do(L}fwrD-J^x3{$-0wfl`sKKzI`~=29UjZk6L>s2 JrEaQ}{{p}uT1fx^ delta 2219 zcmb7Edr*|u6~Di`-!8iZS02k7ba!1~6(?DY^#Kkp%bE~0vX17_4)qb!3{p@O(ovEz zU?P)=#27E-SamWyGE3q_C47dDvMm_NV9ro{AK80FVgBnzMMjThlSMRNTrv%k<6Xj|D55>yL@mQe5c}ezb%%O2{s~wxEJw^324kvRZ51053&jy7OTCpCVHUk< zlPGiqvEolrIrPR!7*(V5Nl-xy?@}{d)u5g^SReK`HjibqV)do;I~LvvQSB)dext{f zECa5q5O+O~SzwjxsIjX=RaVjcOR}t{u(Arq6n0!VRzE5Nvo?!2ecj^Jtn!X*9!8rU z;jd9ZBBvjBNcacy{35G8d!!6v^X%!ODF1y?)sSfgLl~>unY{A#hZ?+Np`LE>ha(`? z9-gXHFdvBsKgk^AgoDFu4)fDDosp+W*29pZ4qH&M}JUvkzHV50lC z_fm5HT?%vnEI(W5_O8NG(Qnj@G=jhm(Ki&d8kU`og+3(hyL{U|W zdhUG(@8~>&mIGYWKIIX=*q$evemPFf>oUQZDfdUK3qCv$PCaKaNeiFOn}AM%yjCh1 zMs!RG%SpT*7Hm7!obIYM9{D=SuZXhdw*$jbX&9p#d-Gg_(S_ zS}@oJ%FW|xYTB*0&~c%P8}CUKF>yzkthNm8G%H_oStsumx1#$+*%iC;o$lForNDh# zE_CnM(APgo-#`At-*VMNhtDEO40b1qeTQP{L>`|mJYCULpUYk9^WSYTh^x14qWyb| zmO6kSI_`EMR*!aFV*WweC21o!sh|B2Z@@)@4Ihb(H{BFaU=l<3Ja0pxhh`%X##ox% zJV1^p91@{3Dbf)q9UEy;05fT;f(3N*8vLCm^c!Lp%0ESHHCxQqu$AoB>{qNxEISoX zo35c)D-Oro78>kBH`a;XRtJU0;>kuEjs@e8PRDGRfE}WC+9dK;VyUpFr{Ex+??W?H zyayY7Q-}y$(qYsFbD@N zBYD6^^_!4n*(j?dTLTM-;l4D@^$JeMMShR3cID)pn0nW;{|_Y=dr#vQ#A=RRctW8i zP1ugpqhwu9qJ>Q|pHU_zG)pFYE!cs+`#Eep2%9A9K?(kTR-*gcbgjD;g$A937QL(~ zI(ONP+u+h%?;x5((Pr+!ryyS&>SdsjoIiJPGcDhXTjw(7~82SecG zI0A>ZE0doyh?>(9$59LzXyU{CJb8LBmlhvGz1DLaP9v47*h0_sVgoJu5)W=qpYuNi za!7bCxc^Od4Ap*y>7vw{s>yTvO^x%Vj`|iLLHpdtr-2sa^XcTB!4v4HmuFJhIW#n0 z!p~@KKF|Aa{|uwv>V_oEIphpTVM>|UH1{A*8$@5LT^F^TyhHHPlvvD=^1gIm)xr~( zOIcYwJ!y!|S^a!jS*{Et$MWK0e}3_jHLEuiFDCCrctw=cFAh1Kdijz-O?&a0*3^pM zfTsNp?@)~eCP{0eJoaVX3BmHX?h0?f}o|%tgYBC~a?CFd(v3lyhhDa*D0~fs*3BTxlI#o+`^LHmoX0w9@ Goc|N7uM)ff