40 void XcpHw_ErrorMsg(
char *
const function,
int errorCode);
42 void XcpThrd_EnableAsyncCancellation(
void);
43 bool XcpThrd_IsShuttingDown(
void);
45 void XcpTl_PrintBtDetails(
void);
47 static void XcpTl_Accept(
void);
48 static int XcpTl_ReadHeader(uint16_t *len, uint16_t *counter);
49 static int XcpTl_ReadData(uint8_t *data, uint16_t len);
51 #if XCP_TRANSPORT_LAYER == XCP_ON_ETHERNET 52 static char *Curl_inet_ntop(
int af,
const void *src,
char *buf,
size_t size);
57 static uint8_t XcpTl_RxBuffer[XCP_COMM_BUFLEN];
59 void *XcpTl_Thread(
void *param) {
60 XCP_UNREFERENCED_PARAMETER(param);
61 XcpThrd_EnableAsyncCancellation();
62 XCP_FOREVER { XcpTl_MainFunction(); }
66 void XcpTl_MainFunction(
void) {
71 void *get_in_addr(
struct sockaddr *sa) {
72 if (sa->sa_family == AF_INET) {
73 return &(((
struct sockaddr_in *)sa)->sin_addr);
75 return &(((
struct sockaddr_in6 *)sa)->sin6_addr);
78 static int XcpTl_ReadHeader(uint16_t *len, uint16_t *counter) {
79 uint8_t header_buffer[8];
80 uint8_t bytes_remaining = XCP_ETH_HEADER_SIZE;
85 if (XcpTl_Connection.socketType == SOCK_DGRAM) {
87 recvfrom(XcpTl_Connection.boundSocket, (
char *)header_buffer + offset,
89 (
struct sockaddr *)&XcpTl_Connection.currentAddress, NULL);
90 if (XcpThrd_IsShuttingDown()) {
93 }
else if (XcpTl_Connection.socketType == SOCK_STREAM) {
94 nbytes = recv(XcpTl_Connection.connectedSocket,
95 (
char *)header_buffer + offset, bytes_remaining, 0);
96 if (XcpThrd_IsShuttingDown()) {
103 bytes_remaining -= nbytes;
104 if (bytes_remaining == 0) {
109 *len = XCP_MAKEWORD(header_buffer[offset + 1], header_buffer[offset + 0]);
110 *counter = XCP_MAKEWORD(header_buffer[offset + 3], header_buffer[offset + 2]);
114 static int XcpTl_ReadData(uint8_t *data, uint16_t len) {
115 uint16_t bytes_remaining = len;
120 if (XcpTl_Connection.socketType == SOCK_DGRAM) {
122 XcpTl_Connection.boundSocket, (
char *)data + offset, bytes_remaining,
123 0, (
struct sockaddr *)&XcpTl_Connection.currentAddress, NULL);
124 }
else if (XcpTl_Connection.socketType == SOCK_STREAM) {
125 nbytes = recv(XcpTl_Connection.connectedSocket, (
char *)data + offset,
131 bytes_remaining -= nbytes;
132 if (bytes_remaining == 0) {
140 void XcpTl_RxHandler(
void) {
143 uint16_t counter = 0U;
145 ZeroMemory(XcpTl_RxBuffer, XCP_COMM_BUFLEN);
148 res = XcpTl_ReadHeader(&dlc, &counter);
151 XcpHw_ErrorMsg(
"XcpTl_RxHandler:XcpTl_ReadHeader()", WSAGetLastError());
152 #elif defined(__unix__) 153 XcpHw_ErrorMsg(
"XcpTl_RxHandler:XcpTl_ReadHeader()", errno);
156 }
else if (res == 0) {
157 XcpTl_ReleaseConnection();
160 if (!XcpThrd_IsShuttingDown()) {
162 res = XcpTl_ReadData(&XcpTl_RxBuffer[0], dlc);
165 XcpHw_ErrorMsg(
"XcpTl_RxHandler:XcpTl_ReadData()", WSAGetLastError());
166 #elif defined(__unix__) 167 XcpHw_ErrorMsg(
"XcpTl_RxHandler:XcpTl_ReadData()", errno);
170 }
else if (res == 0) {
171 printf(
"Empty data\n");
175 printf(
"\t[%02u] ", dlc);
176 XcpUtl_Hexdump(XcpTl_RxBuffer, dlc);
178 XCP_ASSERT_LE(dlc, XCP_TRANSPORT_LAYER_CTO_BUFFER_SIZE);
179 XcpUtl_MemCopy(Xcp_CtoIn.data, XcpTl_RxBuffer, dlc);
180 Xcp_DispatchCommand(&Xcp_CtoIn);
182 printf(
"shutting down\n");
187 static void XcpTl_Accept(
void) {
188 socklen_t FromLen = 0;
189 struct sockaddr_storage From;
192 XcpUtl_ZeroMem(XcpTl_RxBuffer, XCP_COMM_BUFLEN);
194 if (XcpTl_Connection.socketType == SOCK_STREAM) {
195 if (!XcpTl_Connection.connected) {
196 FromLen =
sizeof(From);
197 XcpTl_Connection.connectedSocket =
198 accept(XcpTl_Connection.boundSocket,
199 (
struct sockaddr *)&XcpTl_Connection.currentAddress, &FromLen);
200 if (XcpTl_Connection.connectedSocket == INVALID_SOCKET) {
202 err = WSAGetLastError();
203 if (err != WSAEINTR) {
204 XcpHw_ErrorMsg(
"XcpTl_Accept::accept()",
208 #elif defined(__unix__) 209 XcpHw_ErrorMsg(
"XcpTl_Accept::accept()", errno);
217 void XcpTl_TxHandler(
void) {}
219 void XcpTl_SaveConnection(
void) {
220 XcpUtl_MemCopy(&XcpTl_Connection.connectionAddress,
221 &XcpTl_Connection.currentAddress,
222 sizeof(
struct sockaddr_storage));
223 XcpTl_Connection.connected = XCP_TRUE;
226 void XcpTl_ReleaseConnection(
void) { XcpTl_Connection.connected = XCP_FALSE; }
228 bool XcpTl_VerifyConnection(
void) {
229 return memcmp(&XcpTl_Connection.connectionAddress,
230 &XcpTl_Connection.currentAddress,
231 sizeof(
struct sockaddr_storage)) == 0;
234 #if XCP_TRANSPORT_LAYER == XCP_ON_ETHERNET 235 void XcpTl_PrintConnectionInformation(
void) {
238 printf(
"XCPonEth -- Listening on port %u / %s [%s]\n\r", XCP_ETH_DEFAULT_PORT,
239 Xcp_Options.tcp ?
"TCP" :
"UDP", Xcp_Options.ipv6 ?
"IPv6" :
"IPv4");
241 #elif XCP_TRANSPORT_LAYER == XCP_ON_BTH 242 void XcpTl_PrintConnectionInformation(
void) { XcpTl_PrintBtDetails(); }
245 #if XCP_TRANSPORT_LAYER == XCP_ON_ETHERNET