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 #include <poll.h>
00042 #include <unistd.h>
00043 #include <errno.h>
00044 #include <sys/types.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <netinet/tcp.h>
00048 #include <arpa/inet.h>
00049 #include <unistd.h>
00050 #include <netdb.h>
00051 #include <fcntl.h>
00052 #include <time.h>
00053
00054 #include "ltkc_platform.h"
00055 #include "ltkc_base.h"
00056 #include "ltkc_frame.h"
00057 #include "ltkc_connection.h"
00058
00059
00060 #define LLRP1_TCP_PORT (5084u)
00061
00062
00063
00064 static LLRP_tResultCode
00065 recvAdvance (
00066 LLRP_tSConnection * pConn,
00067 int nMaxMS,
00068 time_t timeLimit);
00069
00070 static time_t
00071 calculateTimeLimit (
00072 int nMaxMS);
00073
00074
00075
00094 LLRP_tSConnection *
00095 LLRP_Conn_construct (
00096 const LLRP_tSTypeRegistry * pTypeRegistry,
00097 unsigned int nBufferSize)
00098 {
00099 LLRP_tSConnection * pConn;
00100
00101
00102
00103
00104 if(0 == nBufferSize)
00105 {
00106 nBufferSize = 128u*1024u;
00107 }
00108
00109
00110
00111
00112
00113
00114 if(1024u > nBufferSize || 1u*1024u*1024u < nBufferSize)
00115 {
00116
00117 return NULL;
00118 }
00119
00120
00121
00122
00123 pConn = malloc(sizeof *pConn);
00124 if(NULL == pConn)
00125 {
00126 return pConn;
00127 }
00128 memset(pConn, 0, sizeof *pConn);
00129
00130
00131
00132
00133
00134 pConn->fd = -1;
00135 pConn->pTypeRegistry = pTypeRegistry;
00136 pConn->nBufferSize = nBufferSize;
00137
00138
00139
00140
00141 pConn->Recv.pBuffer = malloc(nBufferSize);
00142 pConn->Send.pBuffer = malloc(nBufferSize);
00143
00144 if(NULL == pConn->Recv.pBuffer || NULL == pConn->Send.pBuffer)
00145 {
00146 LLRP_Conn_destruct(pConn);
00147 return NULL;
00148 }
00149
00150
00151
00152
00153 memset(pConn->Recv.pBuffer, 0, nBufferSize);
00154 memset(pConn->Send.pBuffer, 0, nBufferSize);
00155
00156
00157
00158
00159 return pConn;
00160 }
00161
00162
00174 void
00175 LLRP_Conn_destruct (
00176 LLRP_tSConnection * pConn)
00177 {
00178 if(NULL != pConn)
00179 {
00180
00181
00182
00183 LLRP_Conn_closeConnectionToReader(pConn);
00184
00185
00186
00187
00188 while(NULL != pConn->pInputQueue)
00189 {
00190 LLRP_tSMessage * pMessage;
00191
00192 pMessage = pConn->pInputQueue;
00193 pConn->pInputQueue = pMessage->pQueueNext;
00194
00195 LLRP_Element_destruct((LLRP_tSElement *)pMessage);
00196 }
00197
00198
00199
00200
00201 if(NULL != pConn->Recv.pBuffer)
00202 {
00203 free(pConn->Recv.pBuffer);
00204 }
00205 if(NULL != pConn->Send.pBuffer)
00206 {
00207 free(pConn->Send.pBuffer);
00208 }
00209
00210
00211
00212
00213
00214 memset(pConn, 0, sizeof *pConn);
00215
00216
00217
00218
00219 free(pConn);
00220 }
00221 }
00222
00223
00244 int
00245 LLRP_Conn_openConnectionToReader (
00246 LLRP_tSConnection * pConn,
00247 const char * pReaderHostName)
00248 {
00249 int Sock;
00250 static const struct addrinfo AddrInfoMask =
00251 {
00252 0,
00253 AF_INET,
00254 SOCK_STREAM,
00255 0,
00256 0,
00257 NULL,
00258 NULL,
00259 NULL
00260 };
00261 struct addrinfo * HostAddress;
00262 int Flag;
00263 struct sockaddr_in Sin;
00264 int Rc;
00265
00266
00267
00268
00269 pConn->pConnectErrorStr = NULL;
00270
00271
00272
00273
00274 if(0 <= pConn->fd)
00275 {
00276 pConn->pConnectErrorStr = "already connected";
00277 return -1;
00278 }
00279
00280
00281
00282
00283
00284
00285
00286 if(0 != getaddrinfo(pReaderHostName, NULL, &AddrInfoMask, &HostAddress))
00287 {
00288 pConn->pConnectErrorStr = "host lookup failed";
00289 return -1;
00290 }
00291
00292
00293
00294
00295 memset(&Sin, 0, sizeof Sin);
00296 Sin.sin_family = AF_INET;
00297 Sin.sin_addr = ((struct sockaddr_in *)(HostAddress->ai_addr))->sin_addr;
00298 Sin.sin_port = htons(LLRP1_TCP_PORT);
00299
00300
00301
00302
00303 freeaddrinfo(HostAddress);
00304
00305
00306
00307
00308 Sock = socket(AF_INET, SOCK_STREAM, 0);
00309 if(0 > Sock)
00310 {
00311 pConn->pConnectErrorStr = "socket() failed";
00312 return -3;
00313 }
00314
00315
00316
00317
00318 Rc = connect(Sock, (struct sockaddr *)&Sin, sizeof Sin);
00319 if(0 > Rc)
00320 {
00321
00322 pConn->pConnectErrorStr = "connect() failed";
00323 close(pConn->fd);
00324 return -4;
00325 }
00326
00327
00328
00329
00330
00331 Flag = 1;
00332 setsockopt(Sock, IPPROTO_TCP, TCP_NODELAY, (void*)&Flag, sizeof Flag);
00333
00334
00335
00336
00337 pConn->fd = Sock;
00338
00339
00340
00341
00342 return 0;
00343 }
00344
00345
00359 const char *
00360 LLRP_Conn_getConnectError (
00361 LLRP_tSConnection * pConn)
00362 {
00363 return pConn->pConnectErrorStr;
00364 }
00365
00366
00379 int
00380 LLRP_Conn_closeConnectionToReader (
00381 LLRP_tSConnection * pConn)
00382 {
00383 if(0 > pConn->fd)
00384 {
00385 pConn->pConnectErrorStr = "not connected";
00386 return -1;
00387 }
00388
00389 close(pConn->fd);
00390
00391 pConn->fd = -1;
00392
00393 return 0;
00394 }
00395
00396
00423 LLRP_tSMessage *
00424 LLRP_Conn_transact (
00425 LLRP_tSConnection * pConn,
00426 LLRP_tSMessage * pSendMessage,
00427 int nMaxMS)
00428 {
00429 const LLRP_tSTypeDescriptor * pResponseType;
00430 LLRP_tResultCode lrc;
00431 LLRP_tSMessage * pResponseMessage;
00432
00433
00434
00435
00436
00437
00438
00439
00440 pResponseType = pSendMessage->elementHdr.pType->pResponseType;
00441 if(NULL == pResponseType)
00442 {
00443 LLRP_tSErrorDetails * pError = &pConn->Send.ErrorDetails;
00444
00445 LLRP_Error_clear(pError);
00446 LLRP_Error_resultCodeAndWhatStr(pError,
00447 LLRP_RC_MissingResponseType,
00448 "send message has no response type");
00449 return NULL;
00450 }
00451
00452
00453
00454
00455 lrc = LLRP_Conn_sendMessage(pConn, pSendMessage);
00456 if(LLRP_RC_OK != lrc)
00457 {
00458 return NULL;
00459 }
00460
00461
00462
00463
00464 pResponseMessage = LLRP_Conn_recvResponse(pConn, nMaxMS,
00465 pResponseType, pSendMessage->MessageID);
00466
00467
00468
00469
00470 return pResponseMessage;
00471 }
00472
00473
00489 const LLRP_tSErrorDetails *
00490 LLRP_Conn_getTransactError (
00491 LLRP_tSConnection * pConn)
00492 {
00493 const LLRP_tSErrorDetails * pError;
00494
00495 pError = LLRP_Conn_getSendError(pConn);
00496 if(LLRP_RC_OK == pError->eResultCode)
00497 {
00498 pError = LLRP_Conn_getRecvError(pConn);
00499 }
00500
00501 return pError;
00502 }
00503
00504
00521 LLRP_tResultCode
00522 LLRP_Conn_sendMessage (
00523 LLRP_tSConnection * pConn,
00524 LLRP_tSMessage * pMessage)
00525 {
00526 LLRP_tSErrorDetails * pError = &pConn->Send.ErrorDetails;
00527 LLRP_tSFrameEncoder * pEncoder;
00528
00529
00530
00531
00532 LLRP_Error_clear(pError);
00533
00534
00535
00536
00537 if(0 > pConn->fd)
00538 {
00539 LLRP_Error_resultCodeAndWhatStr(pError,
00540 LLRP_RC_MiscError, "not connected");
00541 return pError->eResultCode;
00542 }
00543
00544
00545
00546
00547
00548
00549 pEncoder = LLRP_FrameEncoder_construct(pConn->Send.pBuffer,
00550 pConn->nBufferSize);
00551
00552
00553
00554
00555 if(NULL == pEncoder)
00556 {
00557 LLRP_Error_resultCodeAndWhatStr(pError,
00558 LLRP_RC_MiscError, "encoder constructor failed");
00559 return pError->eResultCode;
00560 }
00561
00562
00563
00564
00565
00566
00567
00568
00569 LLRP_Encoder_encodeElement(&pEncoder->encoderHdr, &pMessage->elementHdr);
00570
00571
00572
00573
00574
00575 pConn->Send.ErrorDetails = pEncoder->encoderHdr.ErrorDetails;
00576 pConn->Send.nBuffer = pEncoder->iNext;
00577
00578
00579
00580
00581 LLRP_Encoder_destruct(&pEncoder->encoderHdr);
00582
00583
00584
00585
00586
00587
00588 if(LLRP_RC_OK == pError->eResultCode)
00589 {
00590 int rc;
00591
00592 rc = write(pConn->fd, pConn->Send.pBuffer, pConn->Send.nBuffer);
00593 pError->OtherDetail = rc;
00594 if (-1 == rc)
00595 {
00596 pError->tcpErrno = errno;
00597 }
00598 if(rc != pConn->Send.nBuffer)
00599 {
00600
00601 LLRP_Error_resultCodeAndWhatStr(pError,
00602 LLRP_RC_SendIOError, "send IO error");
00603 }
00604 }
00605
00606
00607
00608
00609 return pError->eResultCode;
00610 }
00611
00612
00624 extern const LLRP_tSErrorDetails *
00625 LLRP_Conn_getSendError (
00626 LLRP_tSConnection * pConn)
00627 {
00628 return &pConn->Send.ErrorDetails;
00629 }
00630
00631
00653 LLRP_tSMessage *
00654 LLRP_Conn_recvMessage (
00655 LLRP_tSConnection * pConn,
00656 int nMaxMS)
00657 {
00658 time_t timeLimit = calculateTimeLimit(nMaxMS);
00659 LLRP_tResultCode lrc;
00660 LLRP_tSMessage * pMessage;
00661
00662
00663
00664
00665 if(0 > pConn->fd)
00666 {
00667 LLRP_tSErrorDetails * pError = &pConn->Recv.ErrorDetails;
00668
00669 LLRP_Error_resultCodeAndWhatStr(pError,
00670 LLRP_RC_MiscError, "not connected");
00671 return NULL;
00672 }
00673
00674
00675
00676
00677 for(;;)
00678 {
00679
00680
00681
00682
00683 pMessage = pConn->pInputQueue;
00684 if(NULL != pMessage)
00685 {
00686 pConn->pInputQueue = pMessage->pQueueNext;
00687 return pMessage;
00688 }
00689
00690
00691
00692
00693
00694 lrc = recvAdvance(pConn, nMaxMS, timeLimit);
00695 if(lrc != LLRP_RC_OK)
00696 {
00697 return NULL;
00698 }
00699 }
00700 }
00701
00702
00715 const LLRP_tSErrorDetails *
00716 LLRP_Conn_getRecvError (
00717 LLRP_tSConnection * pConn)
00718 {
00719 return &pConn->Recv.ErrorDetails;
00720 }
00721
00722
00770 LLRP_tSMessage *
00771 LLRP_Conn_recvResponse (
00772 LLRP_tSConnection * pConn,
00773 int nMaxMS,
00774 const LLRP_tSTypeDescriptor * pResponseType,
00775 llrp_u32_t ResponseMessageID)
00776 {
00777 time_t timeLimit = calculateTimeLimit(nMaxMS);
00778 const LLRP_tSTypeDescriptor *pErrorMsgType;
00779 LLRP_tResultCode lrc;
00780 LLRP_tSMessage * pMessage;
00781 LLRP_tSMessage ** ppMessage;
00782
00783
00784
00785
00786 if(0 > pConn->fd)
00787 {
00788 LLRP_tSErrorDetails * pError = &pConn->Recv.ErrorDetails;
00789
00790 LLRP_Error_resultCodeAndWhatStr(pError,
00791 LLRP_RC_MiscError, "not connected");
00792 return NULL;
00793 }
00794
00795
00796
00797
00798 pErrorMsgType = LLRP_TypeRegistry_lookupMessage(
00799 pConn->pTypeRegistry, 100u);
00800
00801
00802
00803
00804 for(;;)
00805 {
00806
00807
00808
00809
00810 for(
00811 ppMessage = &pConn->pInputQueue;
00812 NULL != (pMessage = *ppMessage);
00813 ppMessage = &pMessage->pQueueNext)
00814 {
00815
00816
00817
00818 if(NULL != pResponseType)
00819 {
00820
00821
00822
00823
00824 if(pMessage->elementHdr.pType != pResponseType &&
00825 pMessage->elementHdr.pType != pErrorMsgType)
00826 {
00827
00828 continue;
00829 }
00830 }
00831
00832
00833
00834
00835 if(0 != ResponseMessageID)
00836 {
00837 if(pMessage->MessageID != ResponseMessageID)
00838 {
00839
00840 continue;
00841 }
00842 }
00843
00844
00845 break;
00846 }
00847
00848
00849
00850
00851 if(NULL != pMessage)
00852 {
00853 *ppMessage = pMessage->pQueueNext;
00854 pMessage->pQueueNext = NULL;
00855 return pMessage;
00856 }
00857
00858
00859
00860
00861
00862 lrc = recvAdvance(pConn, nMaxMS, timeLimit);
00863 if(lrc != LLRP_RC_OK)
00864 {
00865 return NULL;
00866 }
00867
00868
00869
00870
00871 }
00872 }
00873
00874
00899 static LLRP_tResultCode
00900 recvAdvance (
00901 LLRP_tSConnection * pConn,
00902 int nMaxMS,
00903 time_t timeLimit)
00904 {
00905 LLRP_tSErrorDetails * pError = &pConn->Recv.ErrorDetails;
00906
00907
00908
00909
00910 LLRP_Error_clear(pError);
00911
00912
00913
00914
00915 for(;;)
00916 {
00917 int rc;
00918
00919
00920
00921
00922
00923
00924 pConn->Recv.bFrameValid = FALSE;
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944 pConn->Recv.FrameExtract =
00945 LLRP_FrameExtract(pConn->Recv.pBuffer, pConn->Recv.nBuffer);
00946
00947
00948
00949
00950 if(LLRP_FRAME_ERROR == pConn->Recv.FrameExtract.eStatus)
00951 {
00952 LLRP_Error_resultCodeAndWhatStr(pError,
00953 LLRP_RC_RecvFramingError, "framing error in message stream");
00954 break;
00955 }
00956
00957
00958
00959
00960
00961 if(LLRP_FRAME_NEED_MORE == pConn->Recv.FrameExtract.eStatus)
00962 {
00963 unsigned int nRead = pConn->Recv.FrameExtract.nBytesNeeded;
00964 unsigned char * pBufPos =
00965 &pConn->Recv.pBuffer[pConn->Recv.nBuffer];
00966
00967
00968
00969
00970
00971 if(0 != timeLimit)
00972 {
00973 if(time(NULL) > timeLimit)
00974 {
00975
00976 LLRP_Error_resultCodeAndWhatStr(pError,
00977 LLRP_RC_RecvTimeout, "timeout");
00978 break;
00979 }
00980 }
00981
00982
00983
00984
00985
00986 if(nMaxMS >= 0)
00987 {
00988 struct pollfd pfd;
00989
00990 pfd.fd = pConn->fd;
00991 pfd.events = POLLIN;
00992 pfd.revents = 0;
00993
00994 rc = poll(&pfd, 1, nMaxMS);
00995 if(0 > rc)
00996 {
00997
00998 LLRP_Error_resultCodeAndWhatStr(pError,
00999 LLRP_RC_RecvIOError, "poll failed");
01000 break;
01001 }
01002 if(0 == rc)
01003 {
01004
01005 LLRP_Error_resultCodeAndWhatStr(pError,
01006 LLRP_RC_RecvTimeout, "timeout");
01007 break;
01008 }
01009 }
01010
01011
01012
01013
01014 rc = read(pConn->fd, pBufPos, nRead);
01015 if(0 > rc)
01016 {
01017
01018
01019
01020
01021
01022
01023 LLRP_Error_resultCodeAndWhatStr(pError,
01024 LLRP_RC_RecvIOError, "recv IO error");
01025 break;
01026 }
01027
01028 if(0 == rc)
01029 {
01030
01031 LLRP_Error_resultCodeAndWhatStr(pError,
01032 LLRP_RC_RecvEOF, "recv end-of-file");
01033 break;
01034 }
01035
01036
01037
01038
01039
01040
01041 pConn->Recv.nBuffer += rc;
01042
01043 continue;
01044 }
01045
01046
01047
01048
01049
01050 if(LLRP_FRAME_READY == pConn->Recv.FrameExtract.eStatus)
01051 {
01052
01053
01054
01055 LLRP_tSFrameDecoder * pDecoder;
01056 LLRP_tSMessage * pMessage;
01057 LLRP_tSMessage ** ppMessageTail;
01058
01059
01060
01061
01062
01063 pDecoder = LLRP_FrameDecoder_construct(pConn->pTypeRegistry,
01064 pConn->Recv.pBuffer, pConn->Recv.nBuffer);
01065
01066
01067
01068
01069 if(pDecoder == NULL)
01070 {
01071
01072 pConn->Recv.nBuffer = 0;
01073 pConn->Recv.bFrameValid = FALSE;
01074 LLRP_Error_resultCodeAndWhatStr(pError,
01075 LLRP_RC_MiscError, "decoder constructor failed");
01076 break;
01077 }
01078
01079
01080
01081
01082
01083
01084
01085
01086 pMessage = LLRP_Decoder_decodeMessage(&pDecoder->decoderHdr);
01087
01088
01089
01090
01091
01092 pConn->Recv.ErrorDetails = pDecoder->decoderHdr.ErrorDetails;
01093
01094
01095
01096
01097 LLRP_Decoder_destruct(&pDecoder->decoderHdr);
01098
01099
01100
01101
01102
01103 if(NULL == pMessage)
01104 {
01105
01106
01107
01108 if(LLRP_RC_OK == pError->eResultCode)
01109 {
01110 LLRP_Error_resultCodeAndWhatStr(pError,
01111 LLRP_RC_MiscError, "NULL message but no error");
01112 }
01113
01114
01115
01116
01117 pConn->Recv.nBuffer = 0;
01118 pConn->Recv.bFrameValid = FALSE;
01119
01120 break;
01121 }
01122
01123
01124
01125
01126 ppMessageTail = &pConn->pInputQueue;
01127 while(NULL != *ppMessageTail)
01128 {
01129 ppMessageTail = &(*ppMessageTail)->pQueueNext;
01130 }
01131
01132 pMessage->pQueueNext = NULL;
01133 *ppMessageTail = pMessage;
01134
01135
01136
01137
01138
01139
01140 pConn->Recv.bFrameValid = TRUE;
01141 pConn->Recv.nBuffer = 0;
01142
01143 break;
01144 }
01145
01146
01147
01148
01149
01150
01151
01152 assert(0);
01153 }
01154
01155 return pError->eResultCode;
01156 }
01157
01158
01182 static time_t
01183 calculateTimeLimit (
01184 int nMaxMS)
01185 {
01186 if(0 == nMaxMS)
01187 {
01188
01189 return time(NULL) + 1;
01190 }
01191 else if(0 < nMaxMS)
01192 {
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213 return time(NULL) + ((nMaxMS + 1999u) / 1000u);
01214 }
01215 else
01216 {
01217
01218 return 0;
01219 }
01220 }