1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: 系统适配层网络Socket接口实现(此文件为DEMO,需集成方适配修改)
15 */
16
17 #include "hilink_socket_adapter.h"
18 #include <stddef.h>
19 #include <stdbool.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "securec.h"
23 #ifdef HILINK_SDK_BUILD_IN
24 #ifndef _LINUX_OS_
25 #include "lwip.h"
26 #else
27 #include <sys/socket.h>
28 #include <sys/types.h>
29 #include <netinet/in.h>
30 #include <netdb.h>
31 #include <arpa/inet.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #endif
35 #else
36 /* 在此处引入平台socket接口头文件 */
37 #include "lwip/pbuf.h"
38 #include "lwip/dns.h"
39 #include "lwip/inet.h"
40 #include "lwip/sockets.h"
41 #endif /* HILINK_SDK_BUILD_IN */
42 #include "hilink_network_adapter.h"
43 #include "hilink_str_adapter.h"
44 #include "hilink_sal_defines.h"
45 #include "hilink_mem_adapter.h"
46
47 #define MS_PER_SEC 1000
48 #define US_PER_MS 1000
49 #define MAX_IP_LEN 40
50 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
51 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
52 #define IPV6_ADDR_LEN 28
53 #define MAX_ADDR_LEN IPV6_ADDR_LEN
54 #define MAX_DNS_RES_NUM 10
55
56 typedef struct AddrInfoInner {
57 HiLinkAddrInfo hiAddr;
58 struct addrinfo *addr;
59 } AddrInfoInner;
60
61 typedef struct {
62 HiLinkSocketOption option;
63 int (*setOptionFunc)(int fd, const void *value, unsigned int len);
64 } OptionItem;
65
66 typedef struct {
67 int hiType;
68 int sockType;
69 } HiLinkSocketTypePair;
70
71 static const HiLinkSocketTypePair AF_MAP[] = {
72 {HILINK_SOCKET_DOMAIN_AF_INET, AF_INET},
73 {HILINK_SOCKET_DOMAIN_AF_INET6, AF_INET6},
74 {HILINK_SOCKET_DOMAIN_UNSPEC, AF_UNSPEC},
75 };
76
77 static const HiLinkSocketTypePair AP_MAP[] = {
78 {HILINK_SOCKET_PROTO_IP, IPPROTO_IP},
79 {HILINK_SOCKET_PROTO_TCP, IPPROTO_TCP},
80 {HILINK_SOCKET_PROTO_UDP, IPPROTO_UDP},
81 };
82
83 static const HiLinkSocketTypePair AS_MAP[] = {
84 {HILINK_SOCKET_TYPE_STREAM, SOCK_STREAM},
85 {HILINK_SOCKET_TYPE_DGRAM, SOCK_DGRAM},
86 {HILINK_SOCKET_TYPE_RAW, SOCK_RAW},
87 };
88
HiLinkAiFamily2Socket(int af)89 static int HiLinkAiFamily2Socket(int af)
90 {
91 for (unsigned int i = 0; i < ARRAY_SIZE(AF_MAP); ++i) {
92 if (AF_MAP[i].hiType == af) {
93 return AF_MAP[i].sockType;
94 }
95 }
96 return af;
97 }
98
SocketAiFamily2HiLink(int af)99 static int SocketAiFamily2HiLink(int af)
100 {
101 for (unsigned int i = 0; i < ARRAY_SIZE(AF_MAP); ++i) {
102 if (AF_MAP[i].sockType == af) {
103 return AF_MAP[i].hiType;
104 }
105 }
106 return af;
107 }
108
HiLinkAiProtocal2Socket(int ap)109 static int HiLinkAiProtocal2Socket(int ap)
110 {
111 for (unsigned int i = 0; i < ARRAY_SIZE(AP_MAP); ++i) {
112 if (AP_MAP[i].hiType == ap) {
113 return AP_MAP[i].sockType;
114 }
115 }
116 return ap;
117 }
118
SocketAiProtocal2HiLink(int ap)119 static int SocketAiProtocal2HiLink(int ap)
120 {
121 for (unsigned int i = 0; i < ARRAY_SIZE(AP_MAP); ++i) {
122 if (AP_MAP[i].sockType == ap) {
123 return AP_MAP[i].hiType;
124 }
125 }
126 return ap;
127 }
128
HiLinkAiSocktype2Socket(int as)129 static int HiLinkAiSocktype2Socket(int as)
130 {
131 for (unsigned int i = 0; i < ARRAY_SIZE(AS_MAP); ++i) {
132 if (AS_MAP[i].hiType == as) {
133 return AS_MAP[i].sockType;
134 }
135 }
136 return as;
137 }
138
SocketAiSocktype2HiLink(int as)139 static int SocketAiSocktype2HiLink(int as)
140 {
141 for (unsigned int i = 0; i < ARRAY_SIZE(AS_MAP); ++i) {
142 if (AS_MAP[i].sockType == as) {
143 return AS_MAP[i].hiType;
144 }
145 }
146 return as;
147 }
148
GetHiLinkAddrInfo(HiLinkAddrInfo * out,struct addrinfo * in,int level,int maxLevel)149 static void GetHiLinkAddrInfo(HiLinkAddrInfo *out, struct addrinfo *in, int level, int maxLevel)
150 {
151 if ((level > maxLevel) || (in == NULL) || (out == NULL)) {
152 return;
153 }
154
155 out->aiFlags = in->ai_flags;
156 out->aiFamily = SocketAiFamily2HiLink(in->ai_family);
157 out->aiProtocol = SocketAiProtocal2HiLink(in->ai_protocol);
158 out->aiSocktype = SocketAiSocktype2HiLink(in->ai_socktype);
159 out->aiAddrlen = in->ai_addrlen;
160 out->aiAddr = (HiLinkSockaddr *)in->ai_addr;
161 out->aiCanonname = in->ai_canonname;
162
163 if (in->ai_next != NULL) {
164 out->aiNext = (HiLinkAddrInfo *)HILINK_Malloc(sizeof(HiLinkAddrInfo));
165 if (out->aiNext == NULL) {
166 HILINK_SAL_WARN("malloc error\r\n");
167 } else {
168 (void)memset_s(out->aiNext, sizeof(HiLinkAddrInfo), 0, sizeof(HiLinkAddrInfo));
169 /* 递归函数,+1表示递归深度+1 */
170 GetHiLinkAddrInfo(out->aiNext, in->ai_next, level + 1, maxLevel);
171 }
172 }
173
174 return;
175 }
176
FreeHiLinkAddrInfo(HiLinkAddrInfo * addr)177 static void FreeHiLinkAddrInfo(HiLinkAddrInfo *addr)
178 {
179 if (addr->aiNext != NULL) {
180 FreeHiLinkAddrInfo(addr->aiNext);
181 addr->aiNext = NULL;
182 }
183 HILINK_Free(addr);
184 }
185
FreeAddrInfoInner(AddrInfoInner * addrInner)186 static void FreeAddrInfoInner(AddrInfoInner *addrInner)
187 {
188 if (addrInner->addr != NULL) {
189 freeaddrinfo(addrInner->addr);
190 addrInner->addr = NULL;
191 }
192
193 FreeHiLinkAddrInfo((HiLinkAddrInfo *)addrInner);
194 }
195
GetAddrInfoInner(struct addrinfo * addr)196 static HiLinkAddrInfo *GetAddrInfoInner(struct addrinfo *addr)
197 {
198 if (addr == NULL) {
199 return NULL;
200 }
201 AddrInfoInner *addrInner = (AddrInfoInner *)HILINK_Malloc(sizeof(AddrInfoInner));
202 if (addrInner == NULL) {
203 HILINK_SAL_WARN("malloc error\r\n");
204 freeaddrinfo(addr);
205 return NULL;
206 }
207 (void)memset_s(addrInner, sizeof(AddrInfoInner), 0, sizeof(AddrInfoInner));
208 /* 递归函数,1代表第一层 */
209 GetHiLinkAddrInfo(&addrInner->hiAddr, addr, 1, MAX_DNS_RES_NUM);
210 addrInner->addr = addr;
211 return (HiLinkAddrInfo *)addrInner;
212 }
213
HILINK_GetAddrInfo(const char * nodename,const char * servname,const HiLinkAddrInfo * hints,HiLinkAddrInfo ** result)214 int HILINK_GetAddrInfo(const char *nodename, const char *servname,
215 const HiLinkAddrInfo *hints, HiLinkAddrInfo **result)
216 {
217 if ((nodename == NULL) || (result == NULL)) {
218 HILINK_SAL_WARN("invalid param");
219 return HILINK_SAL_PARAM_INVALID;
220 }
221
222 struct addrinfo *resInfo = NULL;
223 struct addrinfo *hintsInfoP = NULL;
224 struct addrinfo hintsInfo;
225
226 HILINK_SAL_DEBUG_LIMITED("get addrinfo %s\r\n", nodename);
227 if (hints != NULL) {
228 if (memcpy_s(&hintsInfo, sizeof(struct addrinfo), hints, sizeof(HiLinkAddrInfo)) != EOK) {
229 HILINK_SAL_ERROR("memcpy error");
230 return HILINK_SAL_MEMCPY_ERR;
231 }
232 hintsInfo.ai_family = HiLinkAiFamily2Socket(hintsInfo.ai_family);
233 hintsInfo.ai_protocol = HiLinkAiProtocal2Socket(hintsInfo.ai_protocol);
234 hintsInfo.ai_socktype = HiLinkAiSocktype2Socket(hintsInfo.ai_socktype);
235 hintsInfoP = &hintsInfo;
236 }
237
238 int ret = getaddrinfo(nodename, servname, hintsInfoP, &resInfo);
239 if ((ret != 0) || (resInfo == NULL)) {
240 HILINK_SAL_ERROR_LIMITED("getaddrinfo failed, ret %d\r\n", ret);
241 return HILINK_SAL_DNS_ERR;
242 }
243
244 *result = GetAddrInfoInner(resInfo);
245 return HILINK_SAL_OK;
246 }
247
HILINK_FreeAddrInfo(HiLinkAddrInfo * addrInfo)248 void HILINK_FreeAddrInfo(HiLinkAddrInfo *addrInfo)
249 {
250 if (addrInfo == NULL) {
251 HILINK_SAL_WARN("invalid param");
252 return;
253 }
254 FreeAddrInfoInner((AddrInfoInner *)addrInfo);
255 return;
256 }
257
HILINK_Socket(HiLinkSocketDomain domain,HiLinkSocketType type,HiLinkSocketProto proto)258 int HILINK_Socket(HiLinkSocketDomain domain, HiLinkSocketType type, HiLinkSocketProto proto)
259 {
260 int af = HiLinkAiFamily2Socket(domain);
261 int st = HiLinkAiSocktype2Socket(type);
262 int ap = HiLinkAiProtocal2Socket(proto);
263
264 return socket(af, st, ap);
265 }
266
HILINK_Close(int fd)267 void HILINK_Close(int fd)
268 {
269 (void)lwip_close(fd);
270 return;
271 }
272
SetFcntl(int fd,bool isBlock)273 static int SetFcntl(int fd, bool isBlock)
274 {
275 int flags = lwip_fcntl(fd, F_GETFL, 0);
276 if (flags < 0) {
277 HILINK_SAL_WARN("fcntl get failed, ret %d\r\n", flags);
278 return HILINK_SAL_FCNTL_ERR;
279 }
280 if (isBlock) {
281 flags &= (~O_NONBLOCK);
282 } else {
283 flags |= O_NONBLOCK;
284 }
285 if (lwip_fcntl(fd, F_SETFL, flags) < 0) {
286 HILINK_SAL_WARN("fcntl set failed\r\n");
287 return HILINK_SAL_FCNTL_ERR;
288 }
289 return HILINK_SAL_OK;
290 }
291
SetSocketOptionNonblock(int fd,const void * value,unsigned int len)292 static int SetSocketOptionNonblock(int fd, const void *value, unsigned int len)
293 {
294 (void)value;
295 (void)len;
296
297 return SetFcntl(fd, false);
298 }
299
SetSocketOptionBlock(int fd,const void * value,unsigned int len)300 static int SetSocketOptionBlock(int fd, const void *value, unsigned int len)
301 {
302 (void)value;
303 (void)len;
304
305 return SetFcntl(fd, true);
306 }
307
SetSocketTimeout(int fd,unsigned int timeout,bool isRead)308 static int SetSocketTimeout(int fd, unsigned int timeout, bool isRead)
309 {
310 struct timeval tv;
311 int flag = isRead ? SO_RCVTIMEO : SO_SNDTIMEO;
312
313 tv.tv_sec = timeout / MS_PER_SEC;
314 tv.tv_usec = timeout % MS_PER_SEC * US_PER_MS;
315 if (setsockopt(fd, SOL_SOCKET, flag, &tv, sizeof(struct timeval)) != 0) {
316 HILINK_SAL_WARN("set [%d][%u] failed\r\n", flag, timeout);
317 return HILINK_SAL_SET_SOCK_OPT_ERR;
318 }
319 return HILINK_SAL_OK;
320 }
321
SetSocketOptionReadTimeouot(int fd,const void * value,unsigned int len)322 static int SetSocketOptionReadTimeouot(int fd, const void *value, unsigned int len)
323 {
324 if (len < sizeof(unsigned int)) {
325 HILINK_SAL_WARN("invalid param");
326 return HILINK_SAL_PARAM_INVALID;
327 }
328 unsigned int timeout = *(const unsigned int *)value;
329
330 return SetSocketTimeout(fd, timeout, true);
331 }
332
SetSocketOptionSendTimeouot(int fd,const void * value,unsigned int len)333 static int SetSocketOptionSendTimeouot(int fd, const void *value, unsigned int len)
334 {
335 if (len < sizeof(unsigned int)) {
336 HILINK_SAL_WARN("invalid param");
337 return HILINK_SAL_PARAM_INVALID;
338 }
339 unsigned int timeout = *(const unsigned int *)value;
340
341 return SetSocketTimeout(fd, timeout, false);
342 }
343
SetSocketOptionEnableReuseAddr(int fd,const void * value,unsigned int len)344 static int SetSocketOptionEnableReuseAddr(int fd, const void *value, unsigned int len)
345 {
346 (void)value;
347 (void)len;
348 int opt = 1;
349 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) != 0) {
350 HILINK_SAL_WARN("set reuse addr failed\r\n");
351 return HILINK_SAL_SET_SOCK_OPT_ERR;
352 }
353 return HILINK_SAL_OK;
354 }
355
SetSocketOptionDisableReuseAddr(int fd,const void * value,unsigned int len)356 static int SetSocketOptionDisableReuseAddr(int fd, const void *value, unsigned int len)
357 {
358 (void)value;
359 (void)len;
360 int opt = 0;
361 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) != 0) {
362 HILINK_SAL_WARN("close reuse addr failed\r\n");
363 return HILINK_SAL_SET_SOCK_OPT_ERR;
364 }
365 return HILINK_SAL_OK;
366 }
367
SetSocketMultiGroup(int fd,const char * multicastIp,bool isAdd)368 static int SetSocketMultiGroup(int fd, const char *multicastIp, bool isAdd)
369 {
370 struct ip_mreq group;
371 (void)memset_s(&group, sizeof(struct ip_mreq), 0, sizeof(struct ip_mreq));
372 group.imr_multiaddr.s_addr = HILINK_InetAddr(multicastIp);
373 char localIp[MAX_IP_LEN] = {0};
374 if ((HILINK_GetLocalIp(localIp, sizeof(localIp)) != 0) ||
375 (HILINK_Strlen(localIp) == 0) || (HILINK_Strcmp(localIp, "0.0.0.0") == 0)) {
376 group.imr_interface.s_addr = HILINK_Htonl(INADDR_ANY);
377 HILINK_SAL_NOTICE("use any addr\r\n");
378 } else {
379 group.imr_interface.s_addr = HILINK_InetAddr(localIp);
380 }
381
382 HILINK_SAL_NOTICE("SetSocketMultiGroup get ip[%s]\r\n", localIp);
383 int flag = isAdd ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
384 if (setsockopt(fd, IPPROTO_IP, flag, (void *)&group, sizeof(group)) < 0) {
385 HILINK_SAL_WARN("set opt %d failed\r\n", flag);
386 return HILINK_SAL_SET_SOCK_OPT_ERR;
387 }
388 return HILINK_SAL_OK;
389 }
390
SetSocketOptionAddMultiGroup(int fd,const void * value,unsigned int len)391 static int SetSocketOptionAddMultiGroup(int fd, const void *value, unsigned int len)
392 {
393 if (HILINK_Strlen((const char *)value) > len) {
394 HILINK_SAL_WARN("invalid param");
395 return HILINK_SAL_PARAM_INVALID;
396 }
397 return SetSocketMultiGroup(fd, (const char *)value, true);
398 }
399
SetSocketOptionDropMultiGroup(int fd,const void * value,unsigned int len)400 static int SetSocketOptionDropMultiGroup(int fd, const void *value, unsigned int len)
401 {
402 if (HILINK_Strlen((const char *)value) > len) {
403 HILINK_SAL_WARN("invalid param");
404 return HILINK_SAL_PARAM_INVALID;
405 }
406 return SetSocketMultiGroup(fd, (const char *)value, false);
407 }
408
SetSocketOptionEnableBroadcast(int fd,const void * value,unsigned int len)409 static int SetSocketOptionEnableBroadcast(int fd, const void *value, unsigned int len)
410 {
411 (void)value;
412 (void)len;
413 int opt = 1;
414 if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (const char *)&opt, sizeof(opt)) != 0) {
415 HILINK_SAL_WARN("set broadcast failed\r\n");
416 return HILINK_SAL_SET_SOCK_OPT_ERR;
417 }
418 return HILINK_SAL_OK;
419 }
420
SetSocketOptionDisableBroadcast(int fd,const void * value,unsigned int len)421 static int SetSocketOptionDisableBroadcast(int fd, const void *value, unsigned int len)
422 {
423 (void)value;
424 (void)len;
425 int opt = 0;
426 if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (const char *)&opt, sizeof(opt)) != 0) {
427 HILINK_SAL_WARN("close broadcast failed\r\n");
428 return HILINK_SAL_SET_SOCK_OPT_ERR;
429 }
430 return HILINK_SAL_OK;
431 }
432
SetSocketOptionEnableMultiLoop(int fd,const void * value,unsigned int len)433 static int SetSocketOptionEnableMultiLoop(int fd, const void *value, unsigned int len)
434 {
435 (void)value;
436 (void)len;
437 int opt = 1;
438 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const char *)&opt, sizeof(opt)) != 0) {
439 HILINK_SAL_WARN("set loop failed\r\n");
440 return HILINK_SAL_SET_SOCK_OPT_ERR;
441 }
442 return HILINK_SAL_OK;
443 }
444
SetSocketOptionDisableMultiLoop(int fd,const void * value,unsigned int len)445 static int SetSocketOptionDisableMultiLoop(int fd, const void *value, unsigned int len)
446 {
447 (void)value;
448 (void)len;
449 int opt = 0;
450 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const char *)&opt, sizeof(opt)) != 0) {
451 HILINK_SAL_WARN("close loop failed\r\n");
452 return HILINK_SAL_SET_SOCK_OPT_ERR;
453 }
454 return HILINK_SAL_OK;
455 }
456
SetSocketOptionSendBuffer(int fd,const void * value,unsigned int len)457 static int SetSocketOptionSendBuffer(int fd, const void *value, unsigned int len)
458 {
459 if (len < sizeof(unsigned int)) {
460 HILINK_SAL_WARN("invalid param");
461 return HILINK_SAL_PARAM_INVALID;
462 }
463 unsigned int bufferLen = *(unsigned int *)value;
464 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *)&bufferLen, sizeof(bufferLen)) < 0) {
465 HILINK_SAL_WARN("set sendbuf %u failed\r\n", bufferLen);
466 return HILINK_SAL_SET_SOCK_OPT_ERR;
467 }
468 return HILINK_SAL_OK;
469 }
470
SetSocketOptionReadBuffer(int fd,const void * value,unsigned int len)471 static int SetSocketOptionReadBuffer(int fd, const void *value, unsigned int len)
472 {
473 if (len < sizeof(unsigned int)) {
474 HILINK_SAL_WARN("invalid param");
475 return HILINK_SAL_PARAM_INVALID;
476 }
477 unsigned int bufferLen = *(unsigned int *)value;
478 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *)&bufferLen, sizeof(bufferLen)) < 0) {
479 HILINK_SAL_WARN("set recvbuf %u failed\r\n", bufferLen);
480 return HILINK_SAL_SET_SOCK_OPT_ERR;
481 }
482 return HILINK_SAL_OK;
483 }
484
HILINK_SetSocketOpt(int fd,HiLinkSocketOption option,const void * value,unsigned int len)485 int HILINK_SetSocketOpt(int fd, HiLinkSocketOption option, const void *value, unsigned int len)
486 {
487 static const OptionItem optionList[] = {
488 {HILINK_SOCKET_OPTION_SETFL_BLOCK, SetSocketOptionBlock},
489 {HILINK_SOCKET_OPTION_SETFL_NONBLOCK, SetSocketOptionNonblock},
490 {HILINK_SOCKET_OPTION_READ_TIMEOUT, SetSocketOptionReadTimeouot},
491 {HILINK_SOCKET_OPTION_SEND_TIMEOUT, SetSocketOptionSendTimeouot},
492 {HILINK_SOCKET_OPTION_ENABLE_REUSEADDR, SetSocketOptionEnableReuseAddr},
493 {HILINK_SOCKET_OPTION_DISABLE_REUSEADDR, SetSocketOptionDisableReuseAddr},
494 {HILINK_SOCKET_OPTION_ADD_MULTI_GROUP, SetSocketOptionAddMultiGroup},
495 {HILINK_SOCKET_OPTION_DROP_MULTI_GROUP, SetSocketOptionDropMultiGroup},
496 {HILINK_SOCKET_OPTION_ENABLE_BROADCAST, SetSocketOptionEnableBroadcast},
497 {HILINK_SOCKET_OPTION_DISABLE_BROADCAST, SetSocketOptionDisableBroadcast},
498 {HILINK_SOCKET_OPTION_ENABLE_MULTI_LOOP, SetSocketOptionEnableMultiLoop},
499 {HILINK_SOCKET_OPTION_DISABLE_MULTI_LOOP, SetSocketOptionDisableMultiLoop},
500 {HILINK_SOCKET_OPTION_SEND_BUFFER, SetSocketOptionSendBuffer},
501 {HILINK_SOCKET_OPTION_READ_BUFFER, SetSocketOptionReadBuffer},
502 };
503 for (unsigned int i = 0; i < (sizeof(optionList) / sizeof(OptionItem)); ++i) {
504 if (option == optionList[i].option) {
505 return optionList[i].setOptionFunc(fd, value, len);
506 }
507 }
508 HILINK_SAL_WARN("unsupport option %d\r\n", option);
509 return HILINK_SAL_NOT_SUPPORT;
510 }
511
HILINK_Bind(int fd,const HiLinkSockaddr * addr,unsigned int addrLen)512 int HILINK_Bind(int fd, const HiLinkSockaddr *addr, unsigned int addrLen)
513 {
514 (void)addrLen;
515 if (addr == NULL) {
516 HILINK_SAL_WARN("invalid param");
517 return HILINK_SAL_PARAM_INVALID;
518 }
519 struct sockaddr addrIn;
520 addrIn.sa_family = HiLinkAiFamily2Socket(addr->saFamily);
521 if (memcpy_s(addrIn.sa_data, sizeof(addrIn.sa_data), addr->saData, sizeof(addr->saData)) != EOK) {
522 HILINK_SAL_WARN("memcpy error");
523 return HILINK_SAL_MEMCPY_ERR;
524 }
525
526 return bind(fd, &addrIn, sizeof(struct sockaddr));
527 }
528
529
HILINK_Connect(int fd,const HiLinkSockaddr * addr,unsigned int addrLen)530 int HILINK_Connect(int fd, const HiLinkSockaddr *addr, unsigned int addrLen)
531 {
532 (void)addrLen;
533 if (addr == NULL) {
534 HILINK_SAL_WARN("invalid param");
535 return HILINK_SAL_PARAM_INVALID;
536 }
537 struct sockaddr addrIn;
538 addrIn.sa_family = HiLinkAiFamily2Socket(addr->saFamily);
539 if (memcpy_s(addrIn.sa_data, sizeof(addrIn.sa_data), addr->saData, sizeof(addr->saData)) != EOK) {
540 HILINK_SAL_WARN("memcpy error");
541 return HILINK_SAL_MEMCPY_ERR;
542 }
543 return connect(fd, &addrIn, sizeof(struct sockaddr));
544 }
545
HILINK_Recv(int fd,unsigned char * buf,unsigned int len)546 int HILINK_Recv(int fd, unsigned char *buf, unsigned int len)
547 {
548 return recv(fd, buf, len, MSG_DONTWAIT);
549 }
550
HILINK_Send(int fd,const unsigned char * buf,unsigned int len)551 int HILINK_Send(int fd, const unsigned char *buf, unsigned int len)
552 {
553 return send(fd, buf, len, MSG_DONTWAIT);
554 }
555
HILINK_RecvFrom(int fd,unsigned char * buf,unsigned int len,HiLinkSockaddr * from,unsigned int * fromLen)556 int HILINK_RecvFrom(int fd, unsigned char *buf, unsigned int len,
557 HiLinkSockaddr *from, unsigned int *fromLen)
558 {
559 if ((from == NULL) || (fromLen == NULL)) {
560 HILINK_SAL_WARN("invalid param");
561 return HILINK_SAL_PARAM_INVALID;
562 }
563 struct sockaddr addr;
564 (void)memset_s(&addr, sizeof(struct sockaddr), 0, sizeof(struct sockaddr));
565 int ret = recvfrom(fd, buf, len, 0, &addr, (socklen_t *)fromLen);
566 from->saFamily = addr.sa_family;
567 if (memcpy_s(from->saData, sizeof(from->saData), addr.sa_data, sizeof(addr.sa_data)) != EOK) {
568 HILINK_SAL_WARN("memcpy error");
569 return HILINK_SAL_MEMCPY_ERR;
570 }
571 return ret;
572 }
573
HILINK_SendTo(int fd,const unsigned char * buf,unsigned int len,const HiLinkSockaddr * to,unsigned int toLen)574 int HILINK_SendTo(int fd, const unsigned char *buf, unsigned int len,
575 const HiLinkSockaddr *to, unsigned int toLen)
576 {
577 if ((to == NULL) || (toLen == 0)) {
578 HILINK_SAL_WARN("invalid param");
579 return HILINK_SAL_PARAM_INVALID;
580 }
581 struct sockaddr addr;
582 addr.sa_family = HiLinkAiFamily2Socket(to->saFamily);
583 if (memcpy_s(addr.sa_data, sizeof(addr.sa_data), to->saData, sizeof(to->saData)) != EOK) {
584 HILINK_SAL_WARN("memcpy error");
585 return HILINK_SAL_MEMCPY_ERR;
586 }
587 return sendto(fd, buf, len, 0, &addr, toLen);
588 }
589
GetFdSet(HiLinkFdSet * set,fd_set * fdSet,int * maxfd)590 static void GetFdSet(HiLinkFdSet *set, fd_set *fdSet, int *maxfd)
591 {
592 if ((set != NULL) && (set->fdSet != NULL)) {
593 memset_s(fdSet, sizeof(fd_set), 0, sizeof(fd_set));
594 for (unsigned int i = 0; i < set->num; ++i) {
595 if (set->fdSet[i] >= 0) {
596 FD_SET(set->fdSet[i], fdSet);
597 *maxfd = MAX(*maxfd, set->fdSet[i]);
598 }
599 }
600 }
601 }
602
FdIsSet(HiLinkFdSet * set,fd_set * fdSet)603 static void FdIsSet(HiLinkFdSet *set, fd_set *fdSet)
604 {
605 if ((set == NULL) || (fdSet == NULL)) {
606 return;
607 }
608 for (unsigned int i = 0; i < set->num; ++i) {
609 if (FD_ISSET(set->fdSet[i], fdSet) == 0) {
610 set->fdSet[i] = -1;
611 }
612 }
613 return;
614 }
615
HILINK_Select(HiLinkFdSet * readSet,HiLinkFdSet * writeSet,HiLinkFdSet * exceptSet,unsigned int ms)616 int HILINK_Select(HiLinkFdSet *readSet, HiLinkFdSet *writeSet, HiLinkFdSet *exceptSet, unsigned int ms)
617 {
618 int maxfd = -1;
619 fd_set read, write, except;
620 GetFdSet(readSet, &read, &maxfd);
621 GetFdSet(writeSet, &write, &maxfd);
622 GetFdSet(exceptSet, &except, &maxfd);
623
624 struct timeval timeout;
625 timeout.tv_sec = ms / MS_PER_SEC;
626 timeout.tv_usec = ms % MS_PER_SEC * US_PER_MS;
627 int ret = lwip_select(maxfd + 1, (readSet == NULL) ? NULL : &read,
628 (writeSet == NULL) ? NULL : &write,
629 (exceptSet == NULL) ? NULL : &except, &timeout);
630 if (ret <= 0) {
631 return ret;
632 }
633 FdIsSet(readSet, &read);
634 FdIsSet(writeSet, &write);
635 FdIsSet(exceptSet, &except);
636 return ret;
637 }
638
HILINK_GetSocketErrno(int fd)639 int HILINK_GetSocketErrno(int fd)
640 {
641 #if defined(_LINUX_OS_) && defined(errno)
642 if (fd < 0) {
643 return errno;
644 }
645 #endif
646 int socketErr;
647 unsigned int len = sizeof(socklen_t);
648 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &socketErr, (socklen_t *)&len) != 0) {
649 HILINK_SAL_WARN("get socket errno error\r\n");
650 return HILINK_SAL_GET_SOCK_OPT_ERR;
651 }
652
653 switch (socketErr) {
654 case EINTR:
655 return HILINK_SOCKET_ERRNO_EINTR;
656 case EAGAIN:
657 return HILINK_SOCKET_ERRNO_EAGAIN;
658 case EINPROGRESS:
659 return HILINK_SOCKET_ERRNO_EINPROGRESS;
660 default:
661 break;
662 }
663
664 return socketErr;
665 }
666
get_os_errno(void)667 int get_os_errno(void)
668 {
669 int errCode = errno;
670 return errCode;
671 }
672
HILINK_Htonl(unsigned int hl)673 unsigned int HILINK_Htonl(unsigned int hl)
674 {
675 return htonl(hl);
676 }
677
HILINK_Ntohl(unsigned int nl)678 unsigned int HILINK_Ntohl(unsigned int nl)
679 {
680 return ntohl(nl);
681 }
682
HILINK_Htons(unsigned short hs)683 unsigned short HILINK_Htons(unsigned short hs)
684 {
685 return htons(hs);
686 }
687
HILINK_Ntohs(unsigned short ns)688 unsigned short HILINK_Ntohs(unsigned short ns)
689 {
690 return ntohs(ns);
691 }
692
HILINK_InetAton(const char * ip,unsigned int * addr)693 unsigned int HILINK_InetAton(const char *ip, unsigned int *addr)
694 {
695 return inet_aton(ip, (struct in_addr *)addr);
696 }
697
HILINK_InetAddr(const char * ip)698 unsigned int HILINK_InetAddr(const char *ip)
699 {
700 return inet_addr(ip);
701 }
702
HILINK_InetNtoa(unsigned int addr,char * buf,unsigned int buflen)703 const char *HILINK_InetNtoa(unsigned int addr, char *buf, unsigned int buflen)
704 {
705 struct in_addr tempAddr;
706 tempAddr.s_addr = addr;
707 #ifndef _LINUX_OS_
708 return inet_ntoa_r(tempAddr, buf, buflen);
709 #else
710 return inet_ntop(AF_INET, &tempAddr, buf, buflen);
711 #endif
712 }