mirror of
https://github.com/openharmony/communication_t2stack.git
synced 2026-08-26 18:46:36 -04:00
9f56148dfc
Signed-off-by: Agrant <luojuheng@huawei.com>
125 lines
2.7 KiB
C
125 lines
2.7 KiB
C
/*
|
|
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "nstackx_socket.h"
|
|
#include "nstackx_log.h"
|
|
#include "nstackx_error.h"
|
|
#include "nstackx_util.h"
|
|
#include "nstackx_dev.h"
|
|
#include "securec.h"
|
|
|
|
#define DEFAULT_UDP_MSS 1472
|
|
#define DEFAULT_MAX_BUF 4096
|
|
#define IOV_CNT 2
|
|
|
|
#define TAG "nStackXSocket"
|
|
#ifndef SOL_UDP
|
|
#define SOL_UDP 17
|
|
#endif
|
|
|
|
void SocketModuleClean(void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int32_t SocketModuleInit(void)
|
|
{
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
int32_t SetSocketNonBlock(SocketDesc fd)
|
|
{
|
|
int32_t flag;
|
|
|
|
flag = fcntl(fd, F_GETFL, 0);
|
|
if (flag < 0) {
|
|
LOGE(TAG, "fcntl GETFL error");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
|
|
if (fcntl(fd, F_SETFL, (unsigned int)flag | O_NONBLOCK) < 0) {
|
|
LOGE(TAG, "fcntl SETFL error");
|
|
return NSTACKX_EFAILED;
|
|
}
|
|
return NSTACKX_EOK;
|
|
}
|
|
|
|
int32_t SocketOpInProgress(void)
|
|
{
|
|
return errno == EINPROGRESS;
|
|
}
|
|
|
|
int32_t SocketOpWouldBlock(void)
|
|
{
|
|
return errno == EAGAIN || errno == EWOULDBLOCK;
|
|
}
|
|
|
|
int32_t SupportGSO(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void CheckGSOSupport(void)
|
|
{
|
|
LOGI(TAG, "kernel does not support UDP GSO");
|
|
}
|
|
|
|
#ifndef UDP_SEGMENT
|
|
#define UDP_SEGMENT 103
|
|
#endif
|
|
|
|
static inline void SetupCmsg(struct cmsghdr *cm, uint16_t mss)
|
|
{
|
|
cm->cmsg_level = SOL_UDP;
|
|
cm->cmsg_type = UDP_SEGMENT;
|
|
cm->cmsg_len = CMSG_LEN(sizeof(mss));
|
|
*(uint16_t *)(void *)CMSG_DATA(cm) = mss;
|
|
}
|
|
|
|
static inline int32_t IsSocketValid(const Socket *s)
|
|
{
|
|
return !(s == NULL || s->protocol != NSTACKX_PROTOCOL_UDP);
|
|
}
|
|
|
|
int32_t SocketSendEx(const Socket *s, uint16_t mss, const struct iovec *iov, uint32_t cnt)
|
|
{
|
|
int32_t ret = NSTACKX_EFAILED;
|
|
char ctrl[CMSG_SPACE(sizeof(uint16_t))] = {0};
|
|
struct msghdr mh;
|
|
|
|
if (!IsSocketValid(s)) {
|
|
LOGE(TAG, "invalid socket input\n");
|
|
return ret;
|
|
}
|
|
|
|
mh.msg_name = (struct sockaddr *)&s->dstAddr;
|
|
mh.msg_namelen = sizeof(struct sockaddr_in);
|
|
mh.msg_iov = (struct iovec *)iov;
|
|
mh.msg_iovlen = (size_t)cnt;
|
|
mh.msg_control = ctrl;
|
|
mh.msg_controllen = sizeof(ctrl);
|
|
mh.msg_flags = 0;
|
|
|
|
SetupCmsg(CMSG_FIRSTHDR(&mh), mss);
|
|
|
|
ret = (int32_t)sendmsg(s->sockfd, &mh, 0);
|
|
if (ret <= 0) {
|
|
ret = CheckSocketError();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|