00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00039 #include <assert.h>
00040
00041
00042 #ifdef linux
00043 #include <poll.h>
00044 #include <unistd.h>
00045 #include <errno.h>
00046 #include <sys/types.h>
00047 #include <sys/socket.h>
00048 #include <netinet/in.h>
00049 #include <netinet/tcp.h>
00050 #include <arpa/inet.h>
00051 #include <unistd.h>
00052 #include <netdb.h>
00053 #include <fcntl.h>
00054 #include <time.h>
00055 #endif
00056 #ifdef WIN32
00057 #define WIN32_LEAN_AND_MEAN
00058 #include <windows.h>
00059 #include <winsock2.h>
00060 #include <ws2tcpip.h>
00061 #include <time.h>
00062 #endif
00063
00064 #include "ltkcpp_platform.h"
00065 #include "ltkcpp_base.h"
00066 #include "ltkcpp_frame.h"
00067 #include "ltkcpp_connection.h"
00068
00069
00070 #define LLRP1_TCP_PORT (5084u)
00071
00072
00073 namespace LLRP
00074 {
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #ifdef linux
00089 class CPlatformSocket
00090 {
00091 public:
00092 int m_sock;
00093
00094 CPlatformSocket(int sock);
00095 };
00096
00097 CPlatformSocket::CPlatformSocket (int sock)
00098 {
00099 m_sock = sock;
00100 }
00101
00102 #endif
00103 #ifdef WIN32
00104 class CPlatformSocket
00105 {
00106 public:
00107 SOCKET m_sock;
00108
00109 CPlatformSocket(SOCKET sock);
00110 };
00111
00112 CPlatformSocket::CPlatformSocket (SOCKET sock)
00113 {
00114 m_sock = sock;
00115 }
00116
00117 #endif
00118
00119
00138 CConnection::CConnection (
00139 const CTypeRegistry * pTypeRegistry,
00140 unsigned int nBufferSize)
00141 {
00142
00143
00144
00145 if(0 == nBufferSize)
00146 {
00147 nBufferSize = 128u*1024u;
00148 }
00149
00150
00151
00152
00153
00154
00155 if(1024u > nBufferSize || 1u*1024u*1024u < nBufferSize)
00156 {
00157 throw "Insane buffer size";
00158 }
00159
00160
00161
00162
00163
00164 m_pPlatformSocket = NULL;
00165 m_pTypeRegistry = pTypeRegistry;
00166 m_nBufferSize = nBufferSize;
00167
00168 memset(&m_Recv, 0, sizeof m_Recv);
00169 memset(&m_Send, 0, sizeof m_Send);
00170
00171
00172
00173
00174 m_Recv.pBuffer = new llrp_byte_t[nBufferSize];
00175 m_Send.pBuffer = new llrp_byte_t[nBufferSize];
00176
00177
00178
00179
00180 memset(m_Recv.pBuffer, 0, nBufferSize);
00181 memset(m_Send.pBuffer, 0, nBufferSize);
00182
00183 #ifdef WIN32
00184
00185
00186
00187 {
00188 WSADATA SocketLibraryInitData;
00189 WSAStartup(0xFFFF, &SocketLibraryInitData);
00190 }
00191 #endif
00192
00193
00194
00195
00196 }
00197
00198
00206 CConnection::~CConnection (void)
00207 {
00208
00209
00210
00211 closeConnectionToReader();
00212
00213
00214
00215
00216 for (
00217 std::list<CMessage *>::iterator msg = m_listInputQueue.begin();
00218 msg != m_listInputQueue.end();
00219 msg++)
00220 {
00221 delete *msg;
00222 }
00223
00224
00225
00226
00227 delete[] m_Recv.pBuffer;
00228 delete[] m_Send.pBuffer;
00229
00230 #ifdef WIN32
00231
00232
00233
00234 {
00235 WSACleanup();
00236 }
00237 #endif
00238
00239 }
00240
00241
00260 int
00261 CConnection::openConnectionToReader (
00262 const char * pReaderHostName)
00263 {
00264 #ifdef linux
00265 int Sock;
00266 #endif
00267 #ifdef WIN32
00268 SOCKET Sock;
00269 #endif
00270 struct addrinfo aiHints;
00271 struct addrinfo * aiList;
00272 int Flag;
00273 struct sockaddr_in Sin;
00274 int rc;
00275
00276
00277
00278
00279 m_pConnectErrorStr = NULL;
00280
00281
00282
00283
00284 if(NULL != m_pPlatformSocket)
00285 {
00286 m_pConnectErrorStr = "already connected";
00287 return -1;
00288 }
00289
00290
00291
00292
00293
00294
00295
00296 memset(&aiHints, 0, sizeof(aiHints));
00297 aiHints.ai_family = AF_INET;
00298 aiList = NULL;
00299
00300 rc = getaddrinfo(pReaderHostName, NULL, &aiHints, &aiList);
00301 if(0 != rc)
00302 {
00303 m_pConnectErrorStr = "host lookup failed";
00304 return -1;
00305 }
00306
00307
00308
00309
00310 memset(&Sin, 0, sizeof Sin);
00311 Sin.sin_family = AF_INET;
00312 Sin.sin_addr = ((struct sockaddr_in *)(aiList->ai_addr))->sin_addr;
00313 Sin.sin_port = htons(LLRP1_TCP_PORT);
00314
00315
00316
00317
00318 freeaddrinfo(aiList);
00319
00320
00321
00322
00323 Sock = socket(AF_INET, SOCK_STREAM, 0);
00324 #ifdef linux
00325 if(0 > Sock)
00326 #endif
00327 #ifdef WIN32
00328 if(NULL == Sock)
00329 #endif
00330 {
00331 m_pConnectErrorStr = "socket() failed";
00332 return -3;
00333 }
00334
00335
00336
00337
00338 rc = connect(Sock, (struct sockaddr *)&Sin, sizeof Sin);
00339 if(0 > rc)
00340 {
00341
00342 m_pConnectErrorStr = "connection failed";
00343 #ifdef linux
00344 close(Sock);
00345 #endif
00346 #ifdef WIN32
00347 closesocket(Sock);
00348 #endif
00349 return -4;
00350 }
00351
00352
00353
00354
00355
00356 Flag = 1;
00357
00358 #ifdef linux
00359 setsockopt(Sock, IPPROTO_TCP, TCP_NODELAY, (void*)&Flag, sizeof Flag);
00360 #endif
00361 #ifdef WIN32
00362 setsockopt(Sock, IPPROTO_TCP, TCP_NODELAY, (char*)&Flag, sizeof Flag);
00363 #endif
00364
00365
00366
00367
00368 m_pPlatformSocket = new CPlatformSocket(Sock);
00369
00370
00371
00372
00373 return 0;
00374 }
00375
00376
00387 const char *
00388 CConnection::getConnectError (void)
00389 {
00390 return m_pConnectErrorStr;
00391 }
00392
00393
00404 int
00405 CConnection::closeConnectionToReader (void)
00406 {
00407 if(NULL == m_pPlatformSocket)
00408 {
00409 m_pConnectErrorStr = "not connected";
00410 return -1;
00411 }
00412
00413 #ifdef linux
00414 close(m_pPlatformSocket->m_sock);
00415 m_pPlatformSocket->m_sock = -1;
00416 #endif
00417 #ifdef WIN32
00418 closesocket(m_pPlatformSocket->m_sock);
00419 m_pPlatformSocket->m_sock = NULL;
00420 #endif
00421
00422 delete m_pPlatformSocket;
00423 m_pPlatformSocket = NULL;
00424 return 0;
00425 }
00426
00427
00450 CMessage *
00451 CConnection::transact (
00452 CMessage * pSendMessage,
00453 int nMaxMS)
00454 {
00455 const CTypeDescriptor * pResponseType;
00456 EResultCode lrc;
00457 CMessage * pResponseMessage;
00458
00459
00460
00461
00462
00463
00464
00465
00466 pResponseType = pSendMessage->m_pType->m_pResponseType;
00467 if(NULL == pResponseType)
00468 {
00469 CErrorDetails * pError = &m_Send.ErrorDetails;
00470
00471 pError->clear();
00472 pError->resultCodeAndWhatStr(RC_MissingResponseType,
00473 "send message has no response type");
00474 return NULL;
00475 }
00476
00477
00478
00479
00480 lrc = sendMessage(pSendMessage);
00481 if(RC_OK != lrc)
00482 {
00483 return NULL;
00484 }
00485
00486
00487
00488
00489 pResponseMessage = recvResponse(nMaxMS,
00490 pResponseType, pSendMessage->getMessageID());
00491
00492
00493
00494
00495 return pResponseMessage;
00496 }
00497
00498
00513 const CErrorDetails *
00514 CConnection::getTransactError (void)
00515 {
00516 const CErrorDetails * pError;
00517
00518 pError = getSendError();
00519 if(RC_OK == pError->m_eResultCode)
00520 {
00521 pError = getRecvError();
00522 }
00523
00524 return pError;
00525 }
00526
00527
00543 EResultCode
00544 CConnection::sendMessage (
00545 CMessage * pMessage)
00546 {
00547 CErrorDetails * pError = &m_Send.ErrorDetails;
00548 CFrameEncoder * pEncoder;
00549
00550
00551
00552
00553 pError->clear();
00554
00555
00556
00557
00558 if(NULL == m_pPlatformSocket)
00559 {
00560 pError->resultCodeAndWhatStr(RC_MiscError, "not connected");
00561 return pError->m_eResultCode;
00562 }
00563
00564
00565
00566
00567
00568 pEncoder = new CFrameEncoder(m_Send.pBuffer, m_nBufferSize);
00569
00570
00571
00572
00573 if(NULL == pEncoder)
00574 {
00575 pError->resultCodeAndWhatStr(RC_MiscError,
00576 "encoder constructor failed");
00577 return pError->m_eResultCode;
00578 }
00579
00580
00581
00582
00583
00584 pEncoder->encodeElement(pMessage);
00585
00586
00587
00588
00589
00590 m_Send.ErrorDetails = pEncoder->m_ErrorDetails;
00591 m_Send.nBuffer = pEncoder->getLength();
00592
00593
00594
00595
00596 delete pEncoder;
00597
00598
00599
00600
00601
00602
00603 if(RC_OK == pError->m_eResultCode)
00604 {
00605 int rc;
00606
00607 rc = send(m_pPlatformSocket->m_sock, (char*)m_Send.pBuffer,
00608 m_Send.nBuffer, 0);
00609 if(rc != (int)m_Send.nBuffer)
00610 {
00611
00612 pError->resultCodeAndWhatStr(RC_SendIOError, "send IO error");
00613 }
00614 }
00615
00616
00617
00618
00619 return pError->m_eResultCode;
00620 }
00621
00622
00632 const CErrorDetails *
00633 CConnection::getSendError (void)
00634 {
00635 return &m_Send.ErrorDetails;
00636 }
00637
00638
00659 CMessage *
00660 CConnection::recvMessage (
00661 int nMaxMS)
00662 {
00663 time_t timeLimit = calculateTimeLimit(nMaxMS);
00664 EResultCode lrc;
00665 CMessage * pMessage;
00666
00667
00668
00669
00670 if(NULL == m_pPlatformSocket)
00671 {
00672 CErrorDetails * pError = &m_Recv.ErrorDetails;
00673
00674 pError->resultCodeAndWhatStr(RC_MiscError, "not connected");
00675 return NULL;
00676 }
00677
00678
00679
00680
00681 for(;;)
00682 {
00683
00684
00685
00686
00687 if(!m_listInputQueue.empty())
00688 {
00689 pMessage = m_listInputQueue.front();
00690 m_listInputQueue.pop_front();
00691 return pMessage;
00692 }
00693
00694
00695
00696
00697
00698 lrc = recvAdvance(nMaxMS, timeLimit);
00699 if(lrc != RC_OK)
00700 {
00701 return NULL;
00702 }
00703 }
00704 }
00705
00706
00717 const CErrorDetails *
00718 CConnection::getRecvError (void)
00719 {
00720 return &m_Recv.ErrorDetails;
00721 }
00722
00723
00770 CMessage *
00771 CConnection::recvResponse (
00772 int nMaxMS,
00773 const CTypeDescriptor * pResponseType,
00774 llrp_u32_t ResponseMessageID)
00775 {
00776 time_t timeLimit = calculateTimeLimit(nMaxMS);
00777 const CTypeDescriptor * pErrorMsgType;
00778 EResultCode lrc;
00779 CMessage * pMessage;
00780
00781
00782
00783
00784 if(NULL == m_pPlatformSocket)
00785 {
00786 CErrorDetails * pError = &m_Recv.ErrorDetails;
00787
00788 pError->resultCodeAndWhatStr(RC_MiscError, "not connected");
00789 return NULL;
00790 }
00791
00792
00793
00794
00795 pErrorMsgType = m_pTypeRegistry->lookupMessage(100u);
00796
00797
00798
00799
00800 for(;;)
00801 {
00802
00803
00804
00805
00806 for (
00807 std::list<CMessage *>::iterator msg = m_listInputQueue.begin();
00808 msg != m_listInputQueue.end();
00809 msg++)
00810 {
00811 pMessage = *msg;
00812
00813
00814
00815
00816 if(NULL != pResponseType)
00817 {
00818
00819
00820
00821
00822 if(pMessage->m_pType != pResponseType &&
00823 pMessage->m_pType != pErrorMsgType)
00824 {
00825
00826 continue;
00827 }
00828 }
00829
00830
00831
00832
00833 if(0 != ResponseMessageID)
00834 {
00835 if(pMessage->getMessageID() != ResponseMessageID)
00836 {
00837
00838 continue;
00839 }
00840 }
00841
00842
00843
00844
00845 m_listInputQueue.remove(pMessage);
00846 return pMessage;
00847 }
00848
00849
00850
00851
00852
00853 lrc = recvAdvance(nMaxMS, timeLimit);
00854 if(lrc != RC_OK)
00855 {
00856 return NULL;
00857 }
00858
00859
00860
00861
00862 }
00863 }
00864
00865
00896 EResultCode
00897 CConnection::recvAdvance (
00898 int nMaxMS,
00899 time_t timeLimit)
00900 {
00901 CErrorDetails * pError = &m_Recv.ErrorDetails;
00902
00903
00904
00905
00906 pError->clear();
00907
00908
00909
00910
00911 for(;;)
00912 {
00913 int rc;
00914
00915
00916
00917
00918
00919
00920 m_Recv.bFrameValid = FALSE;
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940 m_Recv.FrameExtract = CFrameExtract(m_Recv.pBuffer, m_Recv.nBuffer);
00941
00942
00943
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
00954
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
00963
00964
00965 if(0 != timeLimit)
00966 {
00967 if(time(NULL) > timeLimit)
00968 {
00969
00970 pError->resultCodeAndWhatStr(RC_RecvTimeout,
00971 "timeout");
00972 break;
00973 }
00974 }
00975
00976
00977
00978
00979
00980 if(nMaxMS >= 0)
00981 {
00982 #ifdef linux
00983 struct pollfd pfd;
00984
00985 pfd.fd = m_pPlatformSocket->m_sock;
00986 pfd.events = POLLIN;
00987 pfd.revents = 0;
00988
00989 rc = poll(&pfd, 1, nMaxMS);
00990 #endif
00991 #ifdef WIN32
00992 fd_set readfds;
00993 struct timeval timeout;
00994
00995 timeout.tv_sec = nMaxMS / 1000u;
00996 timeout.tv_usec = (nMaxMS % 1000u) * 1000u;
00997
00998 FD_ZERO(&readfds);
00999 FD_SET(m_pPlatformSocket->m_sock, &readfds);
01000 rc = select(-1, &readfds, NULL, NULL, &timeout);
01001
01002 #endif
01003 if(0 > rc)
01004 {
01005
01006 pError->resultCodeAndWhatStr(RC_RecvIOError,
01007 "poll failed");
01008 break;
01009 }
01010 if(0 == rc)
01011 {
01012
01013 pError->resultCodeAndWhatStr(RC_RecvTimeout,
01014 "timeout");
01015 break;
01016 }
01017 }
01018
01019
01020
01021
01022 rc = recv(m_pPlatformSocket->m_sock, (char*)pBufPos, nRead, 0);
01023 if(0 > rc)
01024 {
01025
01026
01027
01028
01029
01030
01031 pError->resultCodeAndWhatStr(RC_RecvIOError,
01032 "recv IO error");
01033 break;
01034 }
01035
01036 if(0 == rc)
01037 {
01038
01039 pError->resultCodeAndWhatStr(RC_RecvEOF,
01040 "recv end-of-file");
01041 break;
01042 }
01043
01044
01045
01046
01047
01048
01049 m_Recv.nBuffer += rc;
01050
01051 continue;
01052 }
01053
01054
01055
01056
01057
01058 if(CFrameExtract::READY == m_Recv.FrameExtract.m_eStatus)
01059 {
01060
01061
01062
01063 CFrameDecoder * pDecoder;
01064 CMessage * pMessage;
01065
01066
01067
01068
01069
01070 pDecoder = new CFrameDecoder(m_pTypeRegistry,
01071 m_Recv.pBuffer, m_Recv.nBuffer);
01072
01073
01074
01075
01076 if(pDecoder == NULL)
01077 {
01078
01079 m_Recv.nBuffer = 0;
01080 m_Recv.bFrameValid = FALSE;
01081 pError->resultCodeAndWhatStr(RC_MiscError,
01082 "decoder constructor failed");
01083 break;
01084 }
01085
01086
01087
01088
01089
01090 pMessage = pDecoder->decodeMessage();
01091
01092
01093
01094
01095
01096 m_Recv.ErrorDetails = pDecoder->m_ErrorDetails;
01097
01098
01099
01100
01101 delete pDecoder;
01102
01103
01104
01105
01106
01107 if(NULL == pMessage)
01108 {
01109
01110
01111
01112 if(RC_OK == pError->m_eResultCode)
01113 {
01114 pError->resultCodeAndWhatStr(RC_MiscError,
01115 "NULL message but no error");
01116 }
01117
01118
01119
01120
01121 m_Recv.nBuffer = 0;
01122 m_Recv.bFrameValid = FALSE;
01123
01124 break;
01125 }
01126
01127
01128
01129
01130 m_listInputQueue.push_back(pMessage);
01131
01132
01133
01134
01135
01136
01137 m_Recv.bFrameValid = TRUE;
01138 m_Recv.nBuffer = 0;
01139
01140 break;
01141 }
01142
01143
01144
01145
01146
01147
01148
01149 assert(0);
01150 }
01151
01152 return pError->m_eResultCode;
01153 }
01154
01155
01178 time_t
01179 CConnection::calculateTimeLimit (
01180 int nMaxMS)
01181 {
01182 if(0 == nMaxMS)
01183 {
01184
01185 return time(NULL) + 1;
01186 }
01187 else if(0 < nMaxMS)
01188 {
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209 return time(NULL) + ((nMaxMS + 1999u) / 1000u);
01210 }
01211 else
01212 {
01213
01214 return 0;
01215 }
01216 }
01217
01218 };
01219