2 // This file is part of the aMule Project.
4 // Copyright (c) 2004-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2004-2011 Angel Vidal ( kry@amule.org )
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
34 #include "ECPacket.h" // Needed for CECPacket
35 #include "../../../Logger.h"
36 #include <common/Format.h> // Needed for CFormat
39 #define EC_COMPRESSION_LEVEL Z_DEFAULT_COMPRESSION
40 #define EC_MAX_UNCOMPRESSED 1024
43 #define __attribute__(x)
46 // If your compiler gives errors on these lines, just remove them.
47 int utf8_mbtowc(wchar_t *p
, const unsigned char *s
, int n
) __attribute__((__visibility__("internal")));
48 int utf8_wctomb(unsigned char *s
, wchar_t wc
, int maxlen
) __attribute__((__visibility__("internal")));
49 int utf8_mb_remain(char c
) __attribute__((__pure__
));
51 /*----------=> Import from the Linux kernel <=----------*/
57 * Sample implementation from Unicode home page.
58 * http://www.stonehand.com/unicode/standard/fss-utf.html
68 static const struct utf8_table utf8_table
[] =
70 {0x80, 0x00, 0*6, 0x7F, 0, /* 1 byte sequence */},
71 {0xE0, 0xC0, 1*6, 0x7FF, 0x80, /* 2 byte sequence */},
72 {0xF0, 0xE0, 2*6, 0xFFFF, 0x800, /* 3 byte sequence */},
73 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
74 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
75 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
76 {0, 0, 0, 0, 0, /* end of table */}
79 static int utf8_mbtowc(uint32_t *p
, const unsigned char *s
, int n
)
83 const struct utf8_table
*t
;
88 for (t
= utf8_table
; t
->cmask
; t
++) {
91 if ((c0
& t
->cmask
) == t
->cval
) {
101 c
= (*s
^ 0x80) & 0xFF;
109 static int utf8_wctomb(unsigned char *s
, uint32_t wc
, int maxlen
)
113 const struct utf8_table
*t
;
117 for (t
= utf8_table
; t
->cmask
&& maxlen
; t
++, maxlen
--) {
121 *s
= t
->cval
| (l
>> c
);
125 *s
= 0x80 | ((l
>> c
) & 0x3F);
132 /*----------=> End of Import <=----------*/
134 int utf8_mb_remain(char c
)
137 for (i
= 0; i
< 5; ++i
) {
138 if ((c
& utf8_table
[i
].cmask
) == utf8_table
[i
].cval
) break;
144 void CQueuedData::Write(const void *data
, size_t len
)
146 const size_t canWrite
= std::min(GetRemLength(), len
);
147 wxASSERT(len
== canWrite
);
149 memcpy(m_wr_ptr
, data
, canWrite
);
150 m_wr_ptr
+= canWrite
;
154 void CQueuedData::WriteAt(const void *data
, size_t len
, size_t offset
)
156 wxASSERT(len
+ offset
<= m_data
.size());
157 if (offset
> m_data
.size()) {
159 } else if (offset
+ len
> m_data
.size()) {
160 len
= m_data
.size() - offset
;
163 memcpy(&m_data
[0] + offset
, data
, len
);
167 void CQueuedData::Read(void *data
, size_t len
)
169 const size_t canRead
= std::min(GetUnreadDataLength(), len
);
170 wxASSERT(len
== canRead
);
172 memcpy(data
, m_rd_ptr
, canRead
);
177 uint32
CQueuedData::WriteToSocket(CECSocket
*sock
)
179 wxCHECK_MSG(m_rd_ptr
< m_wr_ptr
, 0,
180 wxT("Reading past written data in WriteToSocket"));
182 uint32 write
= sock
->SocketWrite(m_rd_ptr
, GetUnreadDataLength());
188 uint32
CQueuedData::ReadFromSocket(CECSocket
*sock
, size_t len
)
190 const size_t canWrite
= std::min(GetRemLength(), len
);
191 wxASSERT(len
== canWrite
);
193 uint32 read
= sock
->SocketRead(m_wr_ptr
, canWrite
);
199 size_t CQueuedData::ReadFromSocketAll(CECSocket
*sock
, size_t len
)
201 size_t read_rem
= std::min(GetRemLength(), len
);
202 wxASSERT(read_rem
== len
);
204 // We get here when socket is truly blocking
206 // Give socket a 10 sec chance to recv more data.
207 if ( !sock
->WaitSocketRead(10, 0) ) {
208 AddDebugLogLineN(logEC
, wxT("ReadFromSocketAll: socket is blocking"));
212 wxASSERT(m_wr_ptr
+ read_rem
<= &m_data
[0] + m_data
.size());
213 uint32 read
= sock
->SocketRead(m_wr_ptr
, read_rem
);
217 if (sock
->SocketRealError()) {
218 AddDebugLogLineN(logEC
, wxT("ReadFromSocketAll: socket error"));
223 return len
- read_rem
;
227 size_t CQueuedData::GetLength() const
229 return m_data
.size();
233 size_t CQueuedData::GetDataLength() const
235 const size_t len
= m_wr_ptr
- &m_data
[0];
236 wxCHECK_MSG(len
<= m_data
.size(), m_data
.size(),
237 wxT("Write-pointer past end of buffer"));
243 size_t CQueuedData::GetRemLength() const
245 return m_data
.size() - GetDataLength();
249 size_t CQueuedData::GetUnreadDataLength() const
251 wxCHECK_MSG(m_wr_ptr
>= m_rd_ptr
, 0,
252 wxT("Read position past write position."));
254 return m_wr_ptr
- m_rd_ptr
;
260 // CECSocket API - User interface functions
263 CECSocket::CECSocket(bool use_events
)
264 : m_use_events(use_events
),
265 m_in_ptr(EC_SOCKET_BUFFER_SIZE
),
266 m_out_ptr(EC_SOCKET_BUFFER_SIZE
),
267 m_curr_rx_data(new CQueuedData(EC_SOCKET_BUFFER_SIZE
)),
268 m_curr_tx_data(new CQueuedData(EC_SOCKET_BUFFER_SIZE
)),
271 // setup initial state: 4 flags + 4 length
272 m_bytes_needed(EC_HEADER_SIZE
),
274 m_curr_packet_len(0),
276 m_haveNotificationSupport(false)
279 CECSocket::~CECSocket()
281 while (!m_output_queue
.empty()) {
282 CQueuedData
*data
= m_output_queue
.front();
283 m_output_queue
.pop_front();
288 bool CECSocket::ConnectSocket(uint32_t ip
, uint16_t port
)
290 bool res
= InternalConnect(ip
, port
, !m_use_events
);
291 return !SocketError() && res
;
294 void CECSocket::SendPacket(const CECPacket
*packet
)
296 uint32 len
= WritePacket(packet
);
297 packet
->DebugPrint(false, len
);
301 const CECPacket
*CECSocket::SendRecvPacket(const CECPacket
*packet
)
305 if (m_curr_rx_data
->ReadFromSocketAll(this, EC_HEADER_SIZE
) != EC_HEADER_SIZE
306 || SocketError() // This is a synchronous read, so WouldBlock is an error too.
309 AddDebugLogLineN(logEC
, wxT("SendRecvPacket: error"));
312 if (m_curr_rx_data
->ReadFromSocketAll(this, m_curr_packet_len
) != m_curr_packet_len
315 AddDebugLogLineN(logEC
, wxT("SendRecvPacket: error"));
318 const CECPacket
*reply
= ReadPacket();
319 m_curr_rx_data
->Rewind();
323 std::string
CECSocket::GetLastErrorMsg()
325 int code
= InternalGetLastError();
327 case EC_ERROR_NOERROR
:
328 return "No error happened";
330 return "Invalid operation";
332 return "Input/Output error";
333 case EC_ERROR_INVADDR
:
334 return "Invalid address passed to wxSocket";
335 case EC_ERROR_INVSOCK
:
336 return "Invalid socket (uninitialized)";
337 case EC_ERROR_NOHOST
:
338 return "No corresponding host";
339 case EC_ERROR_INVPORT
:
340 return "Invalid port";
341 case EC_ERROR_WOULDBLOCK
:
342 return "The socket is non-blocking and the operation would block";
343 case EC_ERROR_TIMEDOUT
:
344 return "The timeout for this operation expired";
345 case EC_ERROR_MEMERR
:
346 return "Memory exhausted";
348 ostringstream error_string
;
349 error_string
<< "Error code " << code
<< " unknown.";
350 return error_string
.str();
353 bool CECSocket::SocketRealError()
356 if (InternalError()) {
357 int lastError
= InternalGetLastError();
358 ret
= lastError
!= EC_ERROR_NOERROR
&& lastError
!= EC_ERROR_WOULDBLOCK
;
363 void CECSocket::OnError()
366 cout
<< GetLastErrorMsg() << endl
;
370 void CECSocket::OnLost()
377 void CECSocket::OnConnect()
381 void CECSocket::OnInput()
385 bytes_rx
= m_curr_rx_data
->ReadFromSocket(this, m_bytes_needed
);
386 if (SocketRealError()) {
387 AddDebugLogLineN(logEC
, wxT("OnInput: socket error"));
389 // socket already disconnected in this point
392 m_bytes_needed
-= bytes_rx
;
394 if (m_bytes_needed
== 0) {
398 AddDebugLogLineN(logEC
, wxT("OnInput: header error"));
402 CSmartPtr
<const CECPacket
> packet(ReadPacket());
403 m_curr_rx_data
->Rewind();
405 CSmartPtr
<const CECPacket
> reply(OnPacketReceived(packet
.get(), m_curr_packet_len
));
407 SendPacket(reply
.get());
410 AddDebugLogLineN(logEC
, wxT("OnInput: no packet"));
412 m_bytes_needed
= EC_HEADER_SIZE
;
419 void CECSocket::OnOutput()
421 while (!m_output_queue
.empty()) {
422 CQueuedData
* data
= m_output_queue
.front();
423 data
->WriteToSocket(this);
424 if (!data
->GetUnreadDataLength()) {
425 m_output_queue
.pop_front();
431 AddDebugLogLineN(logEC
, wxT("OnOutput: socket error"));
435 // Now it's just a blocked socket.
436 if ( m_use_events
) {
437 // Event driven logic: return, OnOutput() will be called again later
440 // Syncronous call: wait (for max 10 secs)
441 if ( !WaitSocketWrite(10, 0) ) {
442 // Still not through ?
444 // WouldBlock() is only EAGAIN or EWOULD_BLOCK,
445 // and those shouldn't create an infinite wait.
446 // So give it another chance.
449 AddDebugLogLineN(logEC
, wxT("OnOutput: socket error in sync wait"));
457 // All outstanding data sent to socket
458 // (used for push clients)
460 WriteDoneAndQueueEmpty();
463 bool CECSocket::DataPending()
465 return !m_output_queue
.empty();
472 size_t CECSocket::ReadBufferFromSocket(void *buffer
, size_t required_len
)
474 wxASSERT(required_len
);
476 if (m_curr_rx_data
->GetUnreadDataLength() < required_len
) {
477 // need more data that we have. Looks like nothing will help here
478 AddDebugLogLineN(logEC
, CFormat(wxT("ReadBufferFromSocket: not enough data (%d < %d)"))
479 % m_curr_rx_data
->GetUnreadDataLength() % required_len
);
482 m_curr_rx_data
->Read(buffer
, required_len
);
486 void CECSocket::WriteBufferToSocket(const void *buffer
, size_t len
)
488 unsigned char *wr_ptr
= (unsigned char *)buffer
;
490 size_t curr_free
= m_curr_tx_data
->GetRemLength();
491 if ( len
> curr_free
) {
493 m_curr_tx_data
->Write(wr_ptr
, curr_free
);
496 m_output_queue
.push_back(m_curr_tx_data
.release());
497 m_curr_tx_data
.reset(new CQueuedData(EC_SOCKET_BUFFER_SIZE
));
499 m_curr_tx_data
->Write(wr_ptr
, len
);
507 // ZLib "error handler"
510 static void ShowZError(int zerror
, z_streamp strm
)
512 const char *p
= NULL
;
515 case Z_STREAM_END
: p
= "Z_STREAM_END"; break;
516 case Z_NEED_DICT
: p
= "Z_NEED_DICT"; break;
517 case Z_ERRNO
: p
= "Z_ERRNO"; break;
518 case Z_STREAM_ERROR
: p
= "Z_STREAM_ERROR"; break;
519 case Z_DATA_ERROR
: p
= "Z_DATA_ERROR"; break;
520 case Z_MEM_ERROR
: p
= "Z_MEM_ERROR"; break;
521 case Z_BUF_ERROR
: p
= "Z_BUF_ERROR"; break;
522 case Z_VERSION_ERROR
: p
= "Z_VERSION_ERROR"; break;
524 printf("ZLib operation returned %s\n", p
);
525 printf("ZLib error message: %s\n", strm
->msg
);
526 printf("zstream state:\n\tnext_in=%p\n\tavail_in=%u\n\ttotal_in=%lu\n\tnext_out=%p\n\tavail_out=%u\n\ttotal_out=%lu\n",
527 strm
->next_in
, strm
->avail_in
, strm
->total_in
, strm
->next_out
, strm
->avail_out
, strm
->total_out
);
528 AddDebugLogLineN(logEC
, wxT("ZLib error"));
532 bool CECSocket::ReadHeader()
534 m_curr_rx_data
->Read(&m_rx_flags
, 4);
535 m_rx_flags
= ENDIAN_NTOHL(m_rx_flags
);
536 m_curr_rx_data
->Read(&m_curr_packet_len
, 4);
537 m_curr_packet_len
= ENDIAN_NTOHL(m_curr_packet_len
);
538 m_bytes_needed
= m_curr_packet_len
;
539 // packet bigger that 16Mb looks more like broken request
540 if (m_bytes_needed
> 16*1024*1024) {
541 AddDebugLogLineN(logEC
, CFormat(wxT("ReadHeader: packet too big: %d")) % m_bytes_needed
);
545 m_curr_rx_data
->Rewind();
546 size_t currLength
= m_curr_rx_data
->GetLength();
547 // resize input buffer if
549 if (currLength
< m_bytes_needed
550 // b) way too large (free data again after receiving huge packets)
551 || m_bytes_needed
+ EC_SOCKET_BUFFER_SIZE
* 10 < currLength
) {
552 // Client socket: IsAuthorized() is always true
553 // Server socket: do not allow growing of internal buffers before succesfull login.
554 // Otherwise sending a simple header with bogus length of 16MB-1 will crash an embedded
555 // client with memory exhaustion.
556 if (!IsAuthorized()) {
557 AddDebugLogLineN(logEC
, CFormat(wxT("ReadHeader: resize (%d -> %d) on non autorized socket")) % currLength
% m_bytes_needed
);
561 // Don't make buffer smaller than EC_SOCKET_BUFFER_SIZE
562 size_t bufSize
= m_bytes_needed
;
563 if (bufSize
< EC_SOCKET_BUFFER_SIZE
) {
564 bufSize
= EC_SOCKET_BUFFER_SIZE
;
566 m_curr_rx_data
.reset(new CQueuedData(bufSize
));
568 if (ECLogIsEnabled()) {
569 DoECLogLine(CFormat(wxT("< %d ...")) % m_bytes_needed
);
575 bool CECSocket::ReadNumber(void *buffer
, size_t len
)
577 if (m_rx_flags
& EC_FLAG_UTF8_NUMBERS
) {
580 if (!ReadBuffer(mb
, 1)) return false;
581 int remains
= utf8_mb_remain(mb
[0]);
582 if (remains
) if (!ReadBuffer(&(mb
[1]), remains
)) return false;
583 if (utf8_mbtowc(&wc
, mb
, 6) == -1) return false; // Invalid UTF-8 code sequence
585 case 1: PokeUInt8( buffer
, wc
); break;
586 case 2: RawPokeUInt16( buffer
, wc
); break;
587 case 4: RawPokeUInt32( buffer
, wc
); break;
590 if ( !ReadBuffer(buffer
, len
) ) {
595 RawPokeUInt16( buffer
, ENDIAN_NTOHS( RawPeekUInt16( buffer
) ) );
598 RawPokeUInt32( buffer
, ENDIAN_NTOHL( RawPeekUInt32( buffer
) ) );
605 bool CECSocket::WriteNumber(const void *buffer
, size_t len
)
607 if (m_tx_flags
& EC_FLAG_UTF8_NUMBERS
) {
612 case 1: wc
= PeekUInt8( buffer
); break;
613 case 2: wc
= RawPeekUInt16( buffer
); break;
614 case 4: wc
= RawPeekUInt32( buffer
); break;
615 default: return false;
617 if ((mb_len
= utf8_wctomb(mb
, wc
, 6)) == -1) return false; // Something is terribly wrong...
618 return WriteBuffer(mb
, mb_len
);
623 case 1: PokeUInt8( tmp
, PeekUInt8( buffer
) ); break;
624 case 2: RawPokeUInt16( tmp
, ENDIAN_NTOHS( RawPeekUInt16( buffer
) ) ); break;
625 case 4: RawPokeUInt32( tmp
, ENDIAN_NTOHL( RawPeekUInt32( buffer
) ) ); break;
627 return WriteBuffer(tmp
, len
);
631 bool CECSocket::ReadBuffer(void *buffer
, size_t len
)
633 if (m_rx_flags
& EC_FLAG_ZLIB
) {
634 if ( !m_z
.avail_in
) {
635 // no reason for this situation: all packet should be
637 AddDebugLogLineN(logEC
, wxT("ReadBuffer: ZLib error"));
640 m_z
.avail_out
= (uInt
)len
;
641 m_z
.next_out
= (Bytef
*)buffer
;
642 int zerror
= inflate(&m_z
, Z_SYNC_FLUSH
);
643 if ((zerror
!= Z_OK
) && (zerror
!= Z_STREAM_END
)) {
644 ShowZError(zerror
, &m_z
);
645 AddDebugLogLineN(logEC
, wxT("ReadBuffer: ZLib error"));
650 // using uncompressed buffered i/o
651 size_t read
= ReadBufferFromSocket(buffer
, len
);
655 AddDebugLogLineN(logEC
, CFormat(wxT("ReadBuffer: %d < %d")) % read
% len
);
661 bool CECSocket::WriteBuffer(const void *buffer
, size_t len
)
663 if (m_tx_flags
& EC_FLAG_ZLIB
) {
665 unsigned char *rd_ptr
= (unsigned char *)buffer
;
667 unsigned int remain_in
= EC_SOCKET_BUFFER_SIZE
- m_z
.avail_in
;
668 if ( remain_in
>= len
) {
669 memcpy(m_z
.next_in
+m_z
.avail_in
, rd_ptr
, len
);
670 m_z
.avail_in
+= (uInt
)len
;
673 memcpy(m_z
.next_in
+m_z
.avail_in
, rd_ptr
, remain_in
);
674 m_z
.avail_in
+= remain_in
;
677 // buffer is full, calling zlib
679 m_z
.next_out
= &m_out_ptr
[0];
680 m_z
.avail_out
= EC_SOCKET_BUFFER_SIZE
;
681 int zerror
= deflate(&m_z
, Z_NO_FLUSH
);
682 if ( zerror
!= Z_OK
) {
683 AddDebugLogLineN(logEC
, wxT("WriteBuffer: ZLib error"));
684 ShowZError(zerror
, &m_z
);
687 WriteBufferToSocket(&m_out_ptr
[0],
688 EC_SOCKET_BUFFER_SIZE
- m_z
.avail_out
);
689 } while ( m_z
.avail_out
== 0 );
690 // all input should be used by now
691 wxASSERT(m_z
.avail_in
== 0);
692 m_z
.next_in
= &m_in_ptr
[0];
697 // using uncompressed buffered i/o
698 WriteBufferToSocket(buffer
, len
);
703 bool CECSocket::FlushBuffers()
705 if (m_tx_flags
& EC_FLAG_ZLIB
) {
707 m_z
.next_out
= &m_out_ptr
[0];
708 m_z
.avail_out
= EC_SOCKET_BUFFER_SIZE
;
709 int zerror
= deflate(&m_z
, Z_FINISH
);
710 if ( zerror
== Z_STREAM_ERROR
) {
711 AddDebugLogLineN(logEC
, wxT("FlushBuffers: ZLib error"));
712 ShowZError(zerror
, &m_z
);
715 WriteBufferToSocket(&m_out_ptr
[0],
716 EC_SOCKET_BUFFER_SIZE
- m_z
.avail_out
);
717 } while ( m_z
.avail_out
== 0 );
719 if ( m_curr_tx_data
->GetDataLength() ) {
720 m_output_queue
.push_back(m_curr_tx_data
.release());
721 m_curr_tx_data
.reset(new CQueuedData(EC_SOCKET_BUFFER_SIZE
));
730 uint32
CECSocket::WritePacket(const CECPacket
*packet
)
732 if (SocketRealError()) {
736 // Check if output queue is empty. If not, memorize the current end.
737 std::list
<CQueuedData
*>::iterator outputStart
= m_output_queue
.begin();
738 uint32 outputQueueSize
= m_output_queue
.size();
739 for (uint32 i
= 1; i
< outputQueueSize
; i
++) {
743 uint32_t flags
= 0x20;
745 if (packet
->GetPacketLength() > EC_MAX_UNCOMPRESSED
746 && ((m_my_flags
& EC_FLAG_ZLIB
) > 0)) {
747 flags
|= EC_FLAG_ZLIB
;
749 flags
|= EC_FLAG_UTF8_NUMBERS
;
755 if (flags
& EC_FLAG_ZLIB
) {
760 m_z
.next_in
= &m_in_ptr
[0];
761 int zerror
= deflateInit(&m_z
, EC_COMPRESSION_LEVEL
);
762 if (zerror
!= Z_OK
) {
763 // don't use zlib if init failed
764 flags
&= ~EC_FLAG_ZLIB
;
765 ShowZError(zerror
, &m_z
);
769 uint32_t tmp_flags
= ENDIAN_HTONL(flags
);
770 WriteBufferToSocket(&tmp_flags
, sizeof(uint32
));
772 // preallocate 4 bytes in buffer for packet length
773 uint32_t packet_len
= 0;
774 WriteBufferToSocket(&packet_len
, sizeof(uint32
));
776 packet
->WritePacket(*this);
778 // Finalize zlib compression and move current data to output queue
781 // find the beginning of our data in the output queue
782 if (outputQueueSize
) {
785 outputStart
= m_output_queue
.begin();
787 // now calculate actual size of data
788 for(std::list
<CQueuedData
*>::iterator it
= outputStart
; it
!= m_output_queue
.end(); ++it
) {
789 packet_len
+= (uint32_t)(*it
)->GetDataLength();
791 // header size is not counted
792 packet_len
-= EC_HEADER_SIZE
;
793 // now write actual length at offset 4
794 uint32 packet_len_E
= ENDIAN_HTONL(packet_len
);
795 (*outputStart
)->WriteAt(&packet_len_E
, 4, 4);
797 if (flags
& EC_FLAG_ZLIB
) {
798 int zerror
= deflateEnd(&m_z
);
799 if ( zerror
!= Z_OK
) {
800 AddDebugLogLineN(logEC
, wxT("WritePacket: ZLib error"));
801 ShowZError(zerror
, &m_z
);
808 const CECPacket
*CECSocket::ReadPacket()
810 CECPacket
*packet
= 0;
812 uint32_t flags
= m_rx_flags
;
814 if ( ((flags
& 0x60) != 0x20) || (flags
& EC_FLAG_UNKNOWN_MASK
) ) {
815 // Protocol error - other end might use an older protocol
816 AddDebugLogLineN(logEC
, wxT("ReadPacket: protocol error"));
817 cout
<< "ReadPacket: packet have invalid flags " << flags
<< endl
;
822 if (flags
& EC_FLAG_ZLIB
) {
830 int zerror
= inflateInit(&m_z
);
831 if (zerror
!= Z_OK
) {
832 AddDebugLogLineN(logEC
, wxT("ReadPacket: zlib error"));
833 ShowZError(zerror
, &m_z
);
834 cout
<< "ReadPacket: failed zlib init" << endl
;
840 m_curr_rx_data
->ToZlib(m_z
);
841 packet
= new CECPacket();
843 if (!packet
->ReadFromSocket(*this)) {
844 AddDebugLogLineN(logEC
, wxT("ReadPacket: error in packet read"));
845 cout
<< "ReadPacket: error in packet read" << endl
;
851 if (flags
& EC_FLAG_ZLIB
) {
852 int zerror
= inflateEnd(&m_z
);
853 if ( zerror
!= Z_OK
) {
854 AddDebugLogLineN(logEC
, wxT("ReadPacket: zlib error"));
855 ShowZError(zerror
, &m_z
);
856 cout
<< "ReadPacket: failed zlib free" << endl
;
864 const CECPacket
*CECSocket::OnPacketReceived(const CECPacket
*, uint32
)
868 // File_checked_for_headers