blob: 238ab163f298260d4e0c9c23d1c3645c5b77cba7 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/******************************************************************************
2*(C) Copyright 2011 Marvell International Ltd.
3* All Rights Reserved
4******************************************************************************/
5/*--------------------------------------------------------------------------------------------------------------------
6 * -------------------------------------------------------------------------------------------------------------------
7 *
8 * Filename: tcp_api.c
9 *
10 * Description: The APIs to handle TCP operations.
11 *
12 * History:
13 * Aug, 13 2012 - Haili Wang(hlw@marvell.com) Creation of file
14 *
15 * Notes:
16 *
17 ******************************************************************************/
18
19#include <sys/types.h>
20#include <sys/socket.h>
21#include <sys/ioctl.h>
22#include <net/if.h>
23#include <unistd.h>
24#include <stdlib.h>
25#include <string.h>
26#include <fcntl.h>
27#include <errno.h>
28#include <termios.h>
29#include <arpa/inet.h>
30#include "linux_types.h"
31#include "utlEventHandler.h"
32#include "pxa_dbg.h"
33
34#include "tcp_api.h"
35#include "tcp_state_machine.h"
36#include "sulog_lib.h"
37
38static struct sulog_data *p_usr_data = NULL;
39
40void SetUserData(void *data)
41{
42 p_usr_data = (struct sulog_data *) data;
43}
44
45static int tcpfd = -1;
46static int sockfd = -1;
47
48static utlEventHandlerId_T tcpHandler;
49static utlEventHandlerId_T acceptedHandler;
50//static DIAG_COM_RX_Packet_Info RxPacket;
51static unsigned char RxBuffer[TTY_MAX_LENGTH];
52static int RxOffset = 0;
53
54int ifc_init(void);
55int ifc_init(void) { return 0;}
56void ifc_close(void);
57void ifc_close(void) {}
58int ifc_up(const char *name);
59int ifc_up(const char *name __attribute__ ((unused))) { return 0; }
60int ifc_set_addr(const char *name, unsigned addr);
61int ifc_set_addr(const char *name __attribute__ ((unused)), unsigned addr __attribute__ ((unused))) { return 0; }
62int ifc_set_mask(const char *name, unsigned mask);
63int ifc_set_mask(const char *name __attribute__ ((unused)), unsigned mask __attribute__ ((unused))) { return 0; }
64
65static utlReturnCode_T ReceiveDataFromTCP(const utlEventHandlerType_T handler_type UNUSED,
66 const utlEventHandlerType_T event_type UNUSED,
67 const int fd,
68 const utlRelativeTime_P2c period_p UNUSED,
69 void *arg_p UNUSED)
70{
71 int dwBytesTransferred, offset;
72 UINT8* transferBuffer = RxBuffer;
73 offset = RxOffset;
74 if ((dwBytesTransferred = read(fd, transferBuffer + offset, sizeof(RxBuffer) - offset)) > 0)
75 {
76
77 DBGMSG("----Data received from TCP:%d, len:%d\n", fd, dwBytesTransferred);
78 handle_sulog_cmd_data(p_usr_data, transferBuffer, &offset, dwBytesTransferred);
79 if ((unsigned) offset + 4 > sizeof(RxBuffer))
80 {
81 DBGMSG("----offset %d too large, reset to 0\n", offset);
82 offset = 0;
83 }
84 RxOffset = offset;
85 return utlSUCCESS;
86 }
87
88 else if(dwBytesTransferred == 0)
89 {
90 DBGMSG("***** TCP Connection closed by peer *****\r\n");
91 TCPDisconnect();
92 return utlSUCCESS;
93 }
94
95 else
96 {
97 if(errno == ECONNRESET)
98 {
99 DBGMSG("***** TCP Connection reset by peer *****\r\n");
100 TCPDisconnect();
101 return utlSUCCESS;
102 }
103 ERRMSG("***** TCP Read failed:%d,%s. *****\r\n", dwBytesTransferred,strerror(errno));
104 return utlFAILED;
105 }
106 return utlSUCCESS;
107}
108
109
110int createListenSocket(void)
111{
112 int addr_reuse = 1;
113 F_ENTER();
114 while(sockfd < 0)
115 {
116 sockfd = socket(AF_INET, SOCK_STREAM, 0);
117 if(sockfd < 0)
118 {
119 ERRMSG("create tcp socket error:%s\n", strerror(errno));
120 }
121 }
122 if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &addr_reuse, sizeof(addr_reuse)) < 0)
123 {
124 ERRMSG("setsockopt : %s", strerror(errno));
125 }
126 F_LEAVE();
127 return sockfd;
128}
129
130int configInterface(void)
131{
132 // ifconfig rndis0 192.168.1.101 netmask 255.255.255.0 up
133 in_addr_t addr, netmask;
134
135 if(p_usr_data == NULL || p_usr_data->network_settings.is_local)
136 return 0;
137
138 addr = inet_addr(p_usr_data->network_settings.diag_ip);
139 netmask = inet_addr(p_usr_data->network_settings.diag_netmask);
140
141 ifc_init();
142 if(ifc_up(p_usr_data->network_settings.net_dev))
143 {
144 ERRMSG("failed to turn on interface");
145 ifc_close();
146 return -1;
147 }
148 if(ifc_set_addr(p_usr_data->network_settings.net_dev, addr))
149 {
150 ERRMSG("failed to set ipaddr");
151 ifc_close();
152 return -1;
153 }
154
155 if(ifc_set_mask(p_usr_data->network_settings.net_dev, netmask))
156 {
157 ERRMSG("failed to set netmask");
158 ifc_close();
159 return -1;
160 }
161
162 ifc_close();
163 return 0;
164}
165
166
167
168static int acceptTCPSocket(void)
169{
170 struct sockaddr_in peer_addr;
171 int addr_size = 0;
172 int ret;
173 int flags;
174
175 ret = accept(sockfd, (struct sockaddr *)&peer_addr, (socklen_t*)&addr_size);
176 if( ret < 0)
177 {
178 ERRMSG("accept tcp socket on %s:%d error:%s\n", p_usr_data ? p_usr_data->network_settings.diag_ip : NULL, p_usr_data ? p_usr_data->network_settings.port : 0, strerror(errno));
179 }
180 else
181 {
182 DBGMSG("client %s:%d is accepted!\n", inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port));
183 tcpfd = ret;
184 memset(RxBuffer, 0, sizeof(RxBuffer));
185 RxOffset = 0;
186 tcpHandler = utlSetFdEventHandler(utlEVENT_HANDLER_TYPE_READ, utlEVENT_HANDLER_PRIORITY_MEDIUM, tcpfd, ReceiveDataFromTCP, NULL);
187 /* Since blocking write behavior is preferred,
188 * undo O_NONBLOCK flag set in utlSetFdEventHandler
189 */
190 if ((flags = fcntl(tcpfd, F_GETFL)) != -1)
191 {
192 flags &= ~O_NONBLOCK;
193 if(fcntl(tcpfd, F_SETFL, flags) == -1)
194 {
195 ERRMSG("F_SETFL error: %s", strerror(errno));
196 }
197 }
198 else
199 {
200 ERRMSG("F_GETFL error: %s", strerror(errno));
201 }
202 }
203 return ret;
204}
205
206static utlReturnCode_T AcceptClient(const utlEventHandlerType_T handler_type UNUSED,
207 const utlEventHandlerType_T event_type UNUSED,
208 const int fd UNUSED,
209 const utlRelativeTime_P2c period_p UNUSED,
210 void *arg_p UNUSED)
211{
212 if (acceptTCPSocket() < 0)
213 {
214 return utlFAILED;
215 }
216 else
217 {
218 TCPAccept();
219 return utlSUCCESS;
220 }
221}
222
223int prepareListenSocket(void)
224{
225 struct sockaddr_in serv_addr;
226 int ret;
227
228 if (p_usr_data == NULL)
229 {
230 return -1;
231 }
232
233 memset(&serv_addr,0,sizeof(serv_addr));
234 serv_addr.sin_family = AF_INET;
235 serv_addr.sin_port = htons(p_usr_data->network_settings.port);
236 serv_addr.sin_addr.s_addr = inet_addr(p_usr_data->network_settings.diag_ip);
237
238 ret = bind(sockfd,(const struct sockaddr*)&serv_addr,sizeof(serv_addr));
239 if(ret < 0)
240 {
241 ERRMSG("bind tcp socket on %s:%d error:%s\n", p_usr_data->network_settings.diag_ip, p_usr_data->network_settings.port,strerror(errno));
242 }
243 else
244 {
245 ret = listen(sockfd, 1);
246 if(ret < 0)
247 {
248 ERRMSG("listen to tcp socket on %s:%d error:%s\n", p_usr_data->network_settings.diag_ip, p_usr_data->network_settings.port,strerror(errno));
249 }
250 else
251 {
252 acceptedHandler = utlSetFdEventHandler(utlEVENT_HANDLER_TYPE_READ, utlEVENT_HANDLER_PRIORITY_MEDIUM, sockfd, AcceptClient, NULL);
253 }
254 }
255 return ret;
256}
257
258
259void closeListenSocket(void)
260{
261 F_ENTER();
262 utlDeleteEventHandler(acceptedHandler);
263 close(sockfd);
264 sockfd = -1;
265}
266
267void closeDataSocket(void)
268{
269 F_ENTER();
270 utlDeleteEventHandler(tcpHandler);
271 close(tcpfd);
272 tcpfd = -1;
273#if 0
274 free(RxPacket.buffer);
275#endif
276}
277
278int SendTCPdata(const unsigned char * data, unsigned len)
279{
280 if(tcpfd > 0)
281 {
282 ssize_t count = len;
283 int ret, retry = 5;
284 while (count > 0)
285 {
286 ret = send(tcpfd, data, count, MSG_NOSIGNAL);
287 if (ret == count)
288 {
289 count = 0;
290 break; /* send all bytes successfully */
291 }
292 else if (ret >= 0)
293 {
294 data += ret;
295 count -= ret;
296 if(--retry == 0)
297 {
298 ERRMSG("tcp send incomplete: %d of %d bytes sent\n", len - count, len);
299 break;
300 }
301 continue;
302 }
303 else if (ret < 0)
304 {
305 ERRMSG("tcp send error: %s\n", strerror(errno));
306 return -1;
307 }
308 }
309 return len - count;
310 }
311 else
312 return -1;
313}
314
315void InitTCP(void)
316{
317 F_ENTER();
318 InitTCPMachine();
319 F_LEAVE();
320}
321
322static int IsNetIfUp(void)
323{
324 struct ifreq ifr;
325 int s, err;
326
327 if ((s = socket( AF_INET, SOCK_DGRAM, 0)) < 0)
328 {
329 err = errno;
330 ERRMSG("%s:socket error:%s", __func__, strerror(err));
331 return -1;
332 }
333 ifr.ifr_name[0] = '\0';
334 if (p_usr_data)
335 {
336 strncat(ifr.ifr_name, p_usr_data->network_settings.net_dev, IFNAMSIZ - 1);
337 }
338 if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
339 {
340 err = errno;
341 ERRMSG("%s:%s", __func__, strerror(err));
342 close(s);
343 return -1;
344 }
345 close(s);
346 s = ifr.ifr_flags & IFF_UP ? 1 : 0;
347 DBGMSG("net interface %s is %s", ifr.ifr_name, s ? "up" : "down");
348 return s;
349}
350
351void handleTCPUevent(int status)
352{
353 if (p_usr_data && !p_usr_data->network_settings.is_local && status == 0) //remove
354 {
355 if(IsNetIfUp() == 0)
356 {
357 TCPDisconnect();
358 }
359 }
360}