LTKCPP-- LLRP Toolkit C Plus Plus Library
|
00001 00002 /* 00003 ***************************************************************************** 00004 * * 00005 * IMPINJ CONFIDENTIAL AND PROPRIETARY * 00006 * * 00007 * This source code is the sole property of Impinj, Inc. Reproduction or * 00008 * utilization of this source code in whole or in part is forbidden without * 00009 * the prior written consent of Impinj, Inc. * 00010 * * 00011 * (c) Copyright Impinj, Inc. 2007,2008. All rights reserved. * 00012 * * 00013 *****************************************************************************/ 00014 00031 #include <assert.h> 00032 00033 #ifdef _WIN32 00034 #include <Ws2tcpip.h> 00035 #define LLRPCLOSESOCKET(X) closesocket(X) 00036 #else 00037 #include <unistd.h> 00038 #include <sys/types.h> 00039 #include <sys/socket.h> 00040 #include <netdb.h> 00041 #define LLRPCLOSESOCKET(X) close(X) 00042 #endif 00043 00044 #include <openssl/ssl.h> 00045 00046 #include "ltkcpp_platform.h" 00047 #include "ltkcpp_base.h" 00048 #include "ltkcpp_frame.h" 00049 #include "ltkcpp_connection.h" 00050 00051 #define LLRP1_TCP_PORT "5084" 00052 #define LLRP1_TLS_PORT "5085" 00053 00054 // Windows defines INVALID_SOCKET the following way, and we must define it the same 00055 // way on Linux: 00056 #ifndef INVALID_SOCKET 00057 #define INVALID_SOCKET (unsigned long)(~0) 00058 #endif // INVALID_SOCKET 00059 00060 // Windows defines SOCKET_ERROR the following way, and we must define it the same 00061 // way on Linux: 00062 #ifndef SOCKET_ERROR 00063 #define SOCKET_ERROR (-1) 00064 #endif 00065 00066 namespace LLRP 00067 { 00068 00087 CConnection::CConnection ( 00088 const CTypeRegistry * pTypeRegistry, 00089 unsigned int nBufferSize) 00090 { 00091 initializeWinsock(); 00092 initializeOpenSSL(); 00093 00094 /* 00095 * Apply default buffer size 00096 */ 00097 if(0 == nBufferSize) 00098 { 00099 nBufferSize = 128u*1024u; 00100 } 00101 00102 /* 00103 * Make sure the buffer size is sane. This is arbitrary. 00104 * The smallest message is 10 bytes, but it ain't anything 00105 * useful. 1024u covers a surprising number of messages. 00106 */ 00107 if(1024u > nBufferSize || 1u*1024u*1024u < nBufferSize) 00108 { 00109 throw "Insane buffer size"; 00110 } 00111 00112 /* 00113 * Capture variables. A NULL m_pBio indicates there 00114 * is no connection yet. 00115 */ 00116 m_pBio = NULL; 00117 m_pTypeRegistry = pTypeRegistry; 00118 m_nBufferSize = nBufferSize; 00119 00120 memset(&m_Recv, 0, sizeof m_Recv); 00121 memset(&m_Send, 0, sizeof m_Send); 00122 00123 /* 00124 * Allocate and check each the recv and send buffers. 00125 */ 00126 m_Recv.pBuffer = new llrp_byte_t[nBufferSize]; 00127 m_Send.pBuffer = new llrp_byte_t[nBufferSize]; 00128 00129 /* 00130 * Zero-fill buffers just so debugger printing is tidy 00131 */ 00132 memset(m_Recv.pBuffer, 0, nBufferSize); 00133 memset(m_Send.pBuffer, 0, nBufferSize); 00134 } 00135 00136 00144 CConnection::~CConnection (void) 00145 { 00146 /* 00147 * Close the connection, if one 00148 */ 00149 closeConnectionToReader(); 00150 00151 /* 00152 * Destruct any messages on the input queue 00153 */ 00154 for ( 00155 std::list<CMessage *>::iterator msg = m_listInputQueue.begin(); 00156 msg != m_listInputQueue.end(); 00157 msg++) 00158 { 00159 delete *msg; 00160 } 00161 00162 /* 00163 * free each the receive and send bufers 00164 */ 00165 delete[] m_Recv.pBuffer; 00166 delete[] m_Send.pBuffer; 00167 00168 shutdownWinsock(); 00169 } 00170 00171 00183 int CConnection::openConnectionToReader(const char * pReaderHostName) 00184 { 00185 return openConnectionToReader(pReaderHostName, E_LLRP_CONNECTION_TYPE_UNSECURE); 00186 } 00187 00199 int CConnection::openSecureConnectionToReader(const char * pReaderHostName) 00200 { 00201 return openConnectionToReader(pReaderHostName, E_LLRP_CONNECTION_TYPE_SSL); 00202 } 00203 00216 int CConnection::openConnectionToReader(const char * pReaderHostName, E_LLRP_CONNECTION_TYPE eType) 00217 { 00218 int rc = -1; 00219 unsigned long hSocket = INVALID_SOCKET; 00220 BIO* pSocketBio = NULL; 00221 00222 /* 00223 * Clear the connect error string 00224 */ 00225 m_pConnectErrorStr = NULL; 00226 00227 /* 00228 * Make sure there isn't already a connection. 00229 */ 00230 if(NULL != m_pBio) 00231 { 00232 m_pConnectErrorStr = "already connected"; 00233 return -1; 00234 } 00235 00236 // Open a raw socket to the reader: 00237 switch (eType) 00238 { 00239 case E_LLRP_CONNECTION_TYPE_SSL: 00240 rc = openSocketConnection(pReaderHostName, LLRP1_TLS_PORT, &hSocket); 00241 break; 00242 case E_LLRP_CONNECTION_TYPE_UNSECURE: 00243 rc = openSocketConnection(pReaderHostName, LLRP1_TCP_PORT, &hSocket); 00244 break; 00245 default: 00246 m_pConnectErrorStr = "Unknown connection type."; 00247 rc = -1; 00248 break; 00249 } 00250 00251 if (rc != 0) 00252 { 00253 // log message should already be set to the appropriate error 00254 // by openSocketConnection 00255 return -1; 00256 } 00257 00258 // Wrap the socket in an OpenSSL 'BIO' 00259 pSocketBio = BIO_new_socket(hSocket, BIO_CLOSE); 00260 if (pSocketBio == NULL) 00261 { 00262 m_pConnectErrorStr = "Failed to register socket with OpenSSL."; 00263 LLRPCLOSESOCKET(hSocket); 00264 00265 return -1; 00266 } 00267 00268 // If we're performing a secured connection, we'll need to create an SSL 00269 // 'BIO' and push that onto the BIO chain. 00270 if (eType == E_LLRP_CONNECTION_TYPE_SSL) 00271 { 00272 BIO* pSslBio = NULL; 00273 int rc = initializeSslBio(&pSslBio); 00274 if (rc != 0) 00275 { 00276 BIO_free_all(pSocketBio); 00277 return -1; 00278 } 00279 00280 BIO_push(pSslBio, pSocketBio); 00281 00282 rc = BIO_do_handshake(pSslBio); 00283 if (rc == 1) 00284 { 00285 this->m_pBio = pSslBio; 00286 } 00287 else 00288 { 00289 m_pConnectErrorStr = "Failed to perform TLS handshake"; 00290 BIO_free_all(pSslBio); 00291 return -1; 00292 } 00293 } 00294 else 00295 { 00296 this->m_pBio = pSocketBio; 00297 } 00298 00299 return 0; 00300 } 00301 00315 int CConnection::openSocketConnection(const char* pkzReaderHostName, const char* pkzPort, unsigned long* phSocket) 00316 { 00317 if (phSocket == NULL) 00318 { 00319 m_pConnectErrorStr = "Internal error."; 00320 return -1; 00321 } 00322 00323 addrinfo* pAddrInfo = NULL; 00324 int rc = getaddrinfo(pkzReaderHostName, pkzPort, NULL, &pAddrInfo); 00325 if (rc != 0) 00326 { 00327 m_pConnectErrorStr = "Failed to resolve host."; 00328 freeaddrinfo(pAddrInfo); 00329 return -1; 00330 } 00331 00332 unsigned long hSocket = socket(pAddrInfo->ai_family, SOCK_STREAM, IPPROTO_TCP); 00333 if (hSocket == INVALID_SOCKET) 00334 { 00335 m_pConnectErrorStr = "Failed to allocate a socket descriptor."; 00336 freeaddrinfo(pAddrInfo); 00337 return -1; 00338 } 00339 00340 rc = connect(hSocket, pAddrInfo->ai_addr, pAddrInfo->ai_addrlen); 00341 if (rc == SOCKET_ERROR) 00342 { 00343 m_pConnectErrorStr = "Failed to connect to host."; 00344 freeaddrinfo(pAddrInfo); 00345 return -1; 00346 } 00347 00348 *phSocket = hSocket; 00349 freeaddrinfo(pAddrInfo); 00350 00351 return rc; 00352 } 00353 00365 int CConnection::initializeSslBio(BIO** ppBio) 00366 { 00367 BIO* pBio = NULL; 00368 long sslOptions = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; 00369 00370 if (ppBio == NULL) 00371 { 00372 m_pConnectErrorStr = "Internal parameter failure"; 00373 return -1; 00374 } 00375 00376 SSL_CTX* pSslCtx = SSL_CTX_new(SSLv23_method()); 00377 if (pSslCtx == NULL) 00378 { 00379 m_pConnectErrorStr = "System SSL context failure"; 00380 return -1; 00381 } 00382 00383 SSL_CTX_set_verify(pSslCtx, SSL_VERIFY_NONE, NULL); 00384 SSL_CTX_set_options(pSslCtx, sslOptions); 00385 00386 pBio = BIO_new_ssl(pSslCtx, 1); // If "client" is non-zero, the SSL bio is initialized in client mode. 00387 SSL_CTX_free(pSslCtx); 00388 if (pBio == NULL) 00389 { 00390 m_pConnectErrorStr = "System SSL socket allocation failure"; 00391 return -1; 00392 } 00393 00394 *ppBio = pBio; 00395 return 0; 00396 } 00397 00408 const char * 00409 CConnection::getConnectError (void) 00410 { 00411 return m_pConnectErrorStr; 00412 } 00413 00414 00425 int 00426 CConnection::closeConnectionToReader (void) 00427 { 00428 SSL* pSsl = NULL; 00429 int rc = -1; 00430 00431 if(NULL == m_pBio) 00432 { 00433 m_pConnectErrorStr = "not connected"; 00434 return -1; 00435 } 00436 00437 BIO_get_ssl(m_pBio, pSsl); 00438 if (pSsl != NULL) 00439 { 00440 BIO_ssl_shutdown(m_pBio); 00441 } 00442 00443 BIO_free_all(m_pBio); 00444 m_pBio = NULL; 00445 00446 rc = shutdownWinsock(); 00447 return rc; 00448 } 00449 00450 00473 CMessage * 00474 CConnection::transact ( 00475 CMessage * pSendMessage, 00476 int nMaxMS) 00477 { 00478 const CTypeDescriptor * pResponseType; 00479 EResultCode lrc; 00480 CMessage * pResponseMessage; 00481 00482 /* 00483 * Determine the response type. The type descriptor 00484 * of the outgoing request message points to the 00485 * type descriptor of the response. Since we are 00486 * totally dependent upon it, fail if there 00487 * is no response type pointer value. 00488 */ 00489 pResponseType = pSendMessage->m_pType->m_pResponseType; 00490 if(NULL == pResponseType) 00491 { 00492 CErrorDetails * pError = &m_Send.ErrorDetails; 00493 00494 pError->clear(); 00495 pError->resultCodeAndWhatStr(RC_MissingResponseType, 00496 "send message has no response type"); 00497 return NULL; 00498 } 00499 00500 /* 00501 * Send the request 00502 */ 00503 lrc = sendMessage(pSendMessage); 00504 if(RC_OK != lrc) 00505 { 00506 return NULL; 00507 } 00508 00509 /* 00510 * Receive the response subject to timeout 00511 */ 00512 pResponseMessage = recvResponse(nMaxMS, 00513 pResponseType, pSendMessage->getMessageID()); 00514 00515 /* 00516 * Whatever recvResponse() returned is the result. 00517 */ 00518 return pResponseMessage; 00519 } 00520 00521 00536 const CErrorDetails * 00537 CConnection::getTransactError (void) 00538 { 00539 const CErrorDetails * pError; 00540 00541 pError = getSendError(); 00542 if(RC_OK == pError->m_eResultCode) 00543 { 00544 pError = getRecvError(); 00545 } 00546 00547 return pError; 00548 } 00549 00550 00566 EResultCode 00567 CConnection::sendMessage ( 00568 CMessage * pMessage) 00569 { 00570 CErrorDetails * pError = &m_Send.ErrorDetails; 00571 CFrameEncoder frameEncoder(m_Send.pBuffer, m_nBufferSize); 00572 00573 /* 00574 * Clear the error details in the send state. 00575 */ 00576 pError->clear(); 00577 00578 /* 00579 * Make sure the socket is open. 00580 */ 00581 if(NULL == m_pBio) 00582 { 00583 pError->resultCodeAndWhatStr(RC_MiscError, "not connected"); 00584 return pError->m_eResultCode; 00585 } 00586 00587 /* 00588 * Encode the message, then check the encoder's ErrorDetails for results. 00589 */ 00590 frameEncoder.encodeElement(pMessage); 00591 00592 /* 00593 * Regardless of what happened capture the error details 00594 * and the number of bytes placed in the buffer. 00595 */ 00596 m_Send.ErrorDetails = frameEncoder.m_ErrorDetails; 00597 m_Send.nBuffer = frameEncoder.getLength(); 00598 00599 /* 00600 * If the encoding appears complete write the frame 00601 * to the connection. NB: this is not ready for 00602 * non-blocking I/O (EWOULDBLOCK). 00603 */ 00604 if (RC_OK == pError->m_eResultCode) 00605 { 00606 int rc = BIO_write(m_pBio, m_Send.pBuffer, (m_Send.nBuffer * sizeof(llrp_byte_t))); 00607 if(rc != (int)m_Send.nBuffer) 00608 { 00609 /* Yikes! */ 00610 pError->resultCodeAndWhatStr(RC_SendIOError, "send IO error"); 00611 } 00612 } 00613 00614 /* 00615 * Done. 00616 */ 00617 return pError->m_eResultCode; 00618 } 00619 00620 00630 const CErrorDetails * 00631 CConnection::getSendError (void) 00632 { 00633 return &m_Send.ErrorDetails; 00634 } 00635 00636 00657 CMessage * 00658 CConnection::recvMessage ( 00659 int nMaxMS) 00660 { 00661 time_t timeLimit = calculateTimeLimit(nMaxMS); 00662 EResultCode lrc; 00663 CMessage * pMessage; 00664 00665 /* 00666 * Make sure the socket is open. 00667 */ 00668 if(NULL == m_pBio) 00669 { 00670 CErrorDetails * pError = &m_Recv.ErrorDetails; 00671 00672 pError->resultCodeAndWhatStr(RC_MiscError, "not connected"); 00673 return NULL; 00674 } 00675 00676 /* 00677 * Loop until victory or some sort of exception happens 00678 */ 00679 for(;;) 00680 { 00681 /* 00682 * Check the input queue to see if there is already 00683 * a message pending. 00684 */ 00685 if(!m_listInputQueue.empty()) 00686 { 00687 pMessage = m_listInputQueue.front(); 00688 m_listInputQueue.pop_front(); 00689 return pMessage; 00690 } 00691 00692 /* 00693 * No message available. Advance the receiver state 00694 * and see if a message is produced. 00695 */ 00696 lrc = recvAdvance(nMaxMS, timeLimit); 00697 if(lrc != RC_OK) 00698 { 00699 return NULL; 00700 } 00701 } 00702 } 00703 00704 00715 const CErrorDetails * 00716 CConnection::getRecvError (void) 00717 { 00718 return &m_Recv.ErrorDetails; 00719 } 00720 00721 00768 CMessage * 00769 CConnection::recvResponse ( 00770 int nMaxMS, 00771 const CTypeDescriptor * pResponseType, 00772 llrp_u32_t ResponseMessageID) 00773 { 00774 time_t timeLimit = calculateTimeLimit(nMaxMS); 00775 const CTypeDescriptor * pErrorMsgType; 00776 EResultCode lrc; 00777 CMessage * pMessage; 00778 00779 /* 00780 * Make sure the socket is open. 00781 */ 00782 if(NULL == m_pBio) 00783 { 00784 CErrorDetails * pError = &m_Recv.ErrorDetails; 00785 00786 pError->resultCodeAndWhatStr(RC_MiscError, "not connected"); 00787 return NULL; 00788 } 00789 00790 /* 00791 * Look up the ERROR_MESSAGE type descriptor now. 00792 */ 00793 pErrorMsgType = m_pTypeRegistry->lookupMessage(100u); 00794 00795 /* 00796 * Loop until victory or some sort of exception happens 00797 */ 00798 for(;;) 00799 { 00800 /* 00801 * Check the input queue to see if the sought 00802 * message is present. 00803 */ 00804 for ( 00805 std::list<CMessage *>::iterator msg = m_listInputQueue.begin(); 00806 msg != m_listInputQueue.end(); 00807 msg++) 00808 { 00809 pMessage = *msg; 00810 00811 /* 00812 * Are we looking for a particular message type? 00813 */ 00814 if(NULL != pResponseType) 00815 { 00816 /* 00817 * See if it is the sought response type or 00818 * an ERROR_MESSAGE. 00819 */ 00820 if(pMessage->m_pType != pResponseType && 00821 pMessage->m_pType != pErrorMsgType) 00822 { 00823 /* Type does not match. Keep looking. */ 00824 continue; 00825 } 00826 } 00827 00828 /* 00829 * Are we looking for a particular message ID? 00830 */ 00831 if(0 != ResponseMessageID) 00832 { 00833 if(pMessage->getMessageID() != ResponseMessageID) 00834 { 00835 /* Message ID does not match. Keep looking. */ 00836 continue; 00837 } 00838 } 00839 00840 /* 00841 * Found it. Unlink it from the queue and return it. 00842 */ 00843 m_listInputQueue.remove(pMessage); 00844 return pMessage; 00845 } 00846 00847 /* 00848 * Sought message is not in the queue. Advance the 00849 * receiver state and see if the message is produced. 00850 */ 00851 lrc = recvAdvance(nMaxMS, timeLimit); 00852 if(lrc != RC_OK) 00853 { 00854 return NULL; 00855 } 00856 00857 /* 00858 * Loop to the top and try again. 00859 */ 00860 } 00861 } 00862 00863 00898 EResultCode 00899 CConnection::recvAdvance ( 00900 int nMaxMS, 00901 time_t timeLimit) 00902 { 00903 CErrorDetails * pError = &m_Recv.ErrorDetails; 00904 00905 /* 00906 * Clear the error details in the receiver state. 00907 */ 00908 pError->clear(); 00909 00910 /* 00911 * Loop until victory or some sort of exception happens 00912 */ 00913 for(;;) 00914 { 00915 /* 00916 * Note that the frame is in progress. 00917 * Existing buffer content, if any, is deemed 00918 * invalid or incomplete. 00919 */ 00920 m_Recv.bFrameValid = FALSE; 00921 00922 /* 00923 * Check to see if we have a frame in the buffer. 00924 * If not, how many more bytes do we need? 00925 * 00926 * LLRP_FrameExtract() status 00927 * 00928 * FRAME_ERROR Impossible situation, like message 00929 * length too small or the like. 00930 * Recovery in this situation is 00931 * unlikely and probably the app 00932 * should drop the connection. 00933 * 00934 * FRAME_READY Frame is complete. Details are 00935 * available for pre-decode decisions. 00936 * 00937 * FRAME_NEED_MORE Need more input bytes to finish the frame. 00938 * The m_nBytesNeeded field is how many more. 00939 */ 00940 m_Recv.FrameExtract = CFrameExtract(m_Recv.pBuffer, m_Recv.nBuffer); 00941 00942 /* 00943 * Framing error? 00944 */ 00945 if(CFrameExtract::FRAME_ERROR == m_Recv.FrameExtract.m_eStatus) 00946 { 00947 pError->resultCodeAndWhatStr(RC_RecvFramingError, 00948 "framing error in message stream"); 00949 break; 00950 } 00951 00952 /* 00953 * Need more bytes? extractRc>0 means we do and extractRc is the 00954 * number of bytes immediately required. 00955 */ 00956 if(CFrameExtract::NEED_MORE == m_Recv.FrameExtract.m_eStatus) 00957 { 00958 unsigned int nRead = m_Recv.FrameExtract.m_nBytesNeeded; 00959 unsigned char * pBufPos = &m_Recv.pBuffer[m_Recv.nBuffer]; 00960 00961 /* 00962 * Before we do anything that might block, 00963 * check to see if the time limit is exceeded. 00964 */ 00965 if(0 != timeLimit) 00966 { 00967 if(time(NULL) > timeLimit) 00968 { 00969 // Timeout 00970 pError->resultCodeAndWhatStr(RC_RecvTimeout, 00971 "timeout"); 00972 break; 00973 } 00974 } 00975 00976 /* 00977 * The frame extractor needs more data, make sure the 00978 * frame size fits in the receive buffer. 00979 */ 00980 if(m_Recv.nBuffer + nRead > m_nBufferSize) 00981 { 00982 pError->resultCodeAndWhatStr(RC_RecvBufferOverflow, 00983 "buffer overflow"); 00984 break; 00985 } 00986 00987 /* 00988 * If this is not a block indefinitely request use select() 00989 * to see if there is data in time. 00990 */ 00991 if (nMaxMS >= 0) 00992 { 00993 fd_set readFdSet = {0}; 00994 timeval timeout = {0}; 00995 int bioSocket = -1; 00996 SSL* pSsl = NULL; 00997 00998 // Check for SSL and error out if it's not null 00999 BIO_get_ssl(m_pBio, &pSsl); 01000 if (pSsl != NULL) 01001 { 01002 pError->resultCodeAndWhatStr(RC_RecvIOError, "Non-blocking I/O not supported over secure connections."); 01003 break; 01004 } 01005 01006 FD_ZERO(&readFdSet); 01007 timeout.tv_sec = nMaxMS / 1000u; 01008 timeout.tv_usec = (nMaxMS % 1000u) * 1000u; 01009 01010 BIO_get_fd(m_pBio, &bioSocket); 01011 if (bioSocket == -1) 01012 { 01013 pError->resultCodeAndWhatStr(RC_RecvIOError, "failed to retrieve socket's file descriptor"); 01014 break; 01015 } 01016 01017 FD_SET(bioSocket, &readFdSet); 01018 01019 int rc = select((bioSocket+1), &readFdSet, NULL, NULL, &timeout); 01020 if (0 > rc) 01021 { 01022 /* Error */ 01023 pError->resultCodeAndWhatStr(RC_RecvIOError, "poll failed"); 01024 break; 01025 } 01026 else if (0 == rc) 01027 { 01028 /* Timeout */ 01029 pError->resultCodeAndWhatStr(RC_RecvTimeout, "timeout"); 01030 break; 01031 } 01032 } 01033 01034 /* 01035 * Call BIO_read, and if no data, but should_retry is true, retry within timeout window 01036 */ 01037 int rc = BIO_read(m_pBio, pBufPos, nRead); 01038 01039 // We will retry on the next go around if need be, checking against the timeout, so only break 01040 // if BIO_should_retry returns false. 01041 if ((0 == rc) && (!BIO_should_retry(m_pBio))) 01042 { 01043 pError->resultCodeAndWhatStr(RC_RecvEOF, 01044 "connection closed by remote"); 01045 break; 01046 } 01047 else if (0 > rc) 01048 { 01049 pError->resultCodeAndWhatStr(RC_RecvIOError, 01050 "recv IO error"); 01051 break; 01052 } 01053 else // We have data! 01054 { 01055 m_Recv.nBuffer += rc; 01056 01057 // Re-run the loop in order to call CFrameExtract's constructor 01058 // again, which will determine if another network read is 01059 // necessary or if the message is now assembled and ready 01060 // for further consumption. 01061 continue; 01062 } 01063 } 01064 01065 /* 01066 * Is the frame ready? 01067 * If a valid frame is present, decode and enqueue it. 01068 */ 01069 if(CFrameExtract::READY == m_Recv.FrameExtract.m_eStatus) 01070 { 01071 /* 01072 * Frame appears complete. Time to try to decode it. 01073 */ 01074 CFrameDecoder decoder(m_pTypeRegistry, m_Recv.pBuffer, m_Recv.nBuffer); 01075 CMessage * pMessage; 01076 01077 /* 01078 * Now ask the nice, brand new decoder to decode the frame. 01079 * It returns NULL for some kind of error. 01080 */ 01081 pMessage = decoder.decodeMessage(); 01082 01083 /* 01084 * Always capture the error details even when it works. 01085 * Whatever happened, we are done with the decoder. 01086 */ 01087 m_Recv.ErrorDetails = decoder.m_ErrorDetails; 01088 01089 /* 01090 * If NULL there was an error. Clean up the 01091 * receive state. Return the error. 01092 */ 01093 if(NULL == pMessage) 01094 { 01095 /* 01096 * Make sure the return is not RC_OK 01097 */ 01098 if(RC_OK == pError->m_eResultCode) 01099 { 01100 pError->resultCodeAndWhatStr(RC_MiscError, 01101 "NULL message but no error"); 01102 } 01103 01104 /* 01105 * All we can do is discard the frame. 01106 */ 01107 m_Recv.nBuffer = 0; 01108 m_Recv.bFrameValid = FALSE; 01109 01110 break; 01111 } 01112 01113 /* 01114 * Yay! It worked. Enqueue the message. 01115 */ 01116 m_listInputQueue.push_back(pMessage); 01117 01118 /* 01119 * Note that the frame is valid. Consult 01120 * Recv.FrameExtract.m_MessageLength. 01121 * Clear the buffer count to be ready for next time. 01122 */ 01123 m_Recv.bFrameValid = TRUE; 01124 m_Recv.nBuffer = 0; 01125 01126 break; 01127 } 01128 01129 /* 01130 * If we get here there was an FrameExtract status 01131 * we didn't expect. 01132 */ 01133 01134 /*NOTREACHED*/ 01135 assert(0); 01136 } 01137 01138 return pError->m_eResultCode; 01139 } 01140 01141 01164 time_t 01165 CConnection::calculateTimeLimit ( 01166 int nMaxMS) 01167 { 01168 if(0 == nMaxMS) 01169 { 01170 /* When just peeking, try for at most one second */ 01171 return time(NULL) + 1; 01172 } 01173 else if(0 < nMaxMS) 01174 { 01175 /* 01176 * Try for a at most a certain period of time. 01177 * 01178 * timeLimit = now + ceil(nMaxMS/1000) + 1 01179 * 01180 * The last +1 compensates for not knowing 01181 * when the next time() tick will happen. 01182 * 01183 * For example, if now is SECONDS.999 seconds 01184 * the next tick will happen in 1 millisecond. 01185 * Suppose nMaxMS is 500ms (1/2 second). 01186 * Even rounding 500ms up to 1 second, the 01187 * time limit without the +1 would be 01188 * SECONDS+1 -- 1ms away. That's too soon. 01189 * 01190 * The extra +1 makes the maximum timeout 01191 * longer than required. But the timeLimit 01192 * is a safeguard anyway and usually the 01193 * timeout will occur when the user wants. 01194 */ 01195 return time(NULL) + ((nMaxMS + 1999u) / 1000u); 01196 } 01197 else 01198 { 01199 /* Try indefinitely */ 01200 return 0; 01201 } 01202 } 01203 01210 void CConnection::initializeOpenSSL() 01211 { 01212 CRYPTO_malloc_init(); // only needed for windows to safely transfer 01213 // data across the dll boundry as the 01214 // mallocs/heaps are not the same. This is a 01215 // no-op on Linux. 01216 01217 SSL_library_init(); // SSL_library_init() always returns "1", 01218 // so it is safe to discard the return value. 01219 01220 SSL_load_error_strings(); 01221 } 01222 01223 01233 int CConnection::initializeWinsock() 01234 { 01235 int rc = 0; 01236 01237 #ifdef _WIN32 01238 WSADATA winsockData = { 0 }; 01239 rc = WSAStartup(MAKEWORD(2, 2), &winsockData); 01240 #endif 01241 01242 return rc; 01243 } 01244 01254 int CConnection::shutdownWinsock() 01255 { 01256 int rc = 0; 01257 01258 #ifdef _WIN32 01259 rc = WSACleanup(); 01260 #endif 01261 01262 return rc; 01263 } 01264 01265 }; /* namespace LLRP */ 01266