• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }