36 #define DEFAULT_FAMILY PF_UNSPEC // Accept either IPv4 or IPv6 37 #define DEFAULT_SOCKTYPE SOCK_STREAM // 39 #define ADDR_LEN sizeof(SOCKADDR_STORAGE) 43 void Xcp_DispatchCommand(Xcp_PduType
const *
const pdu);
45 extern Xcp_PduType Xcp_CtoIn;
46 extern Xcp_PduType Xcp_CtoOut;
48 static boolean Xcp_EnableSocketOption(SOCKET sock,
int option);
51 static boolean Xcp_DisableSocketOption(SOCKET sock,
int option);
54 static boolean Xcp_EnableSocketOption(SOCKET sock,
int option) {
55 #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L 56 const char enable = 1;
58 if (setsockopt(sock, SOL_SOCKET, option, &enable,
sizeof(
int)) < 0) {
62 if (setsockopt(sock, SOL_SOCKET, option, &(
const char){1},
sizeof(int)) < 0) {
70 static boolean Xcp_DisableSocketOption(SOCKET sock,
int option)
72 #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L 73 const char enable = 0;
75 if (setsockopt(sock, SOL_SOCKET, option, &enable,
sizeof(
int)) < 0) {
79 if (setsockopt(sock, SOL_SOCKET, option, &(
const char){0},
sizeof(int)) < 0) {
87 void XcpTl_Init(
void) {
94 SOCKET serverSockets[FD_SETSIZE];
95 int boundSocketNum = -1;
98 DWORD dwTimeAdjustment = 0UL;
99 DWORD dwTimeIncrement = 0UL;
100 BOOL fAdjustmentDisabled = XCP_TRUE;
104 memset(&Hints, 0,
sizeof(Hints));
105 GetSystemTimeAdjustment(&dwTimeAdjustment, &dwTimeIncrement,
106 &fAdjustmentDisabled);
107 if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
108 XcpHw_ErrorMsg(
"XcpTl_Init:WSAStartup()", WSAGetLastError());
112 XcpTl_Connection.socketType = Xcp_Options.tcp ? SOCK_STREAM : SOCK_DGRAM;
113 Hints.ai_family = Xcp_Options.ipv6 ? PF_INET6 : PF_INET;
114 Hints.ai_socktype = XcpTl_Connection.socketType;
115 Hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
116 ret = getaddrinfo(Address, Port, &Hints, &AddrInfo);
118 XcpHw_ErrorMsg(
"XcpTl_Init::getaddrinfo()", WSAGetLastError());
122 for (idx = 0, AI = AddrInfo; AI != NULL; AI = AI->ai_next, ++idx) {
123 if (idx == FD_SETSIZE) {
124 printf(
"getaddrinfo returned more addresses than we could use.\n");
127 if ((AI->ai_family != PF_INET) && (AI->ai_family != PF_INET6)) {
131 socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol);
132 if (serverSockets[idx] == INVALID_SOCKET) {
133 XcpHw_ErrorMsg(
"XcpTl_Init::socket()", WSAGetLastError());
136 if (bind(serverSockets[idx], AI->ai_addr, AI->ai_addrlen) != 0) {
137 XcpHw_ErrorMsg(
"XcpTl_Init::bind()", WSAGetLastError());
141 memcpy(&XcpTl_Connection.localAddress, AI->ai_addr,
142 sizeof(SOCKADDR_STORAGE));
145 if (XcpTl_Connection.socketType == SOCK_STREAM) {
146 if (listen(serverSockets[idx], 1) == SOCKET_ERROR) {
147 XcpHw_ErrorMsg(
"XcpTl_Init::listen()", WSAGetLastError());
151 boundSocketNum = idx;
152 XcpTl_Connection.boundSocket = serverSockets[boundSocketNum];
156 freeaddrinfo(AddrInfo);
157 if (boundSocketNum == -1) {
159 "Fatal error: unable to serve on any address.\nPerhaps" 160 " a server is already running on port %u / %s [%s]?\n",
161 XCP_ETH_DEFAULT_PORT, Xcp_Options.tcp ?
"TCP" :
"UDP",
162 Xcp_Options.ipv6 ?
"IPv6" :
"IPv4");
166 if (!Xcp_EnableSocketOption(XcpTl_Connection.boundSocket, SO_REUSEADDR)) {
167 XcpHw_ErrorMsg(
"XcpTl_Init:setsockopt(SO_REUSEADDR)", WSAGetLastError());
171 ioctlsocket(XcpTl_Connection.boundSocket, FIONBIO, &ul);
175 void XcpTl_DeInit(
void) {
176 closesocket(XcpTl_Connection.boundSocket);
180 void XcpTl_Send(uint8_t
const *buf, uint16_t len) {
181 XCP_TL_ENTER_CRITICAL();
182 if (XcpTl_Connection.socketType == SOCK_DGRAM) {
183 if (sendto(XcpTl_Connection.boundSocket, (
char const *)buf, len, 0,
184 (SOCKADDR
const *)(SOCKADDR_STORAGE
const *)&XcpTl_Connection
186 ADDR_LEN) == SOCKET_ERROR) {
187 XcpHw_ErrorMsg(
"XcpTl_Send:sendto()", WSAGetLastError());
189 }
else if (XcpTl_Connection.socketType == SOCK_STREAM) {
190 if (send(XcpTl_Connection.connectedSocket, (
char const *)buf, len, 0) ==
192 XcpHw_ErrorMsg(
"XcpTl_Send:send()", WSAGetLastError());
193 closesocket(XcpTl_Connection.connectedSocket);
196 XCP_TL_LEAVE_CRITICAL();