* Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
* ubs-comm is licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "ubsocket_socket.h"
#include "ubsocket_data_rx.h"
#include "ubsocket_data_tx.h"
#include "umq/umq_data_rx_ops.h"
#include "umq/umq_data_tx_ops.h"
#include "umq/umq_socket.h"
#include "umq/umq_socket_acceptor.h"
#include "umq/umq_socket_connector.h"
namespace ock {
namespace ubs {
Result SocketBase::Create(int fd, ock::ubs::SocketType t, SocketPtr &outSocket)
{
if (t == SocketType::SOCK_TYPE_UMQ) {
using namespace umq;
auto umqSock = MakeRef<UmqSocket>(fd);
if (umqSock == nullptr) {
return UBS_MALLOC_FAILED;
}
auto result = umqSock->Initialize();
if (result != UBS_OK) {
return result;
}
auto sock = RefConvert<UmqSocket, Socket>(umqSock);
auto sockBase = RefConvert<UmqSocket, SocketBase>(umqSock);
AcceptorOps *acceptorOps = nullptr;
result = CreateAcceptorOps(t, sock, acceptorOps);
if (result != UBS_OK) {
return result;
}
ConnectorOps *connectorOps = nullptr;
result = CreateConnectorOps(t, sock, connectorOps);
if (result != UBS_OK) {
delete acceptorOps;
return result;
}
sockBase->acceptor_ = new Acceptor(sock, acceptorOps);
sockBase->connector_ = new Connector(sock, connectorOps);
result = EpollRunnerFactory::GetInstance(SocketType::SOCK_TYPE_UMQ).Start();
if (result != UBS_OK) {
return result;
}
outSocket = sock;
return UBS_OK;
} else {
return UBS_INVALID_PARAM;
}
}
Result SocketBase::GenerateSocketCommOps(const SocketPtr &sock)
{
auto sockBase = RefConvert<Socket, SocketBase>(sock);
DataTxOps *txOps = nullptr;
Result result = CreateTxOps(sock->type_, sock, txOps);
if (result != UBS_OK) {
return result;
}
DataRxOps *rxOps = nullptr;
result = CreateRxOps(sock->type_, sock, rxOps);
if (result != UBS_OK) {
delete txOps;
return result;
}
sockBase->tx_ = DataTx(sock, txOps);
sockBase->rx_ = DataRx(sock, rxOps);
return UBS_OK;
}
Result SocketBase::CreateTxOps(SocketType value, const SocketPtr &sock, DataTxOps *&ops)
{
if (sock == nullptr) {
return UBS_INVALID_PARAM;
}
if (value == SocketType::SOCK_TYPE_UMQ) {
using namespace umq;
UmqSocketPtr umqSock = RefConvert<Socket, UmqSocket>(sock);
auto umqOps = new (std::nothrow) UmqTxOps(umqSock->raw_socket_, umqSock->UmqHandle());
if (umqOps == nullptr) {
return UBS_MALLOC_FAILED;
}
ops = umqOps;
return UBS_OK;
} else {
return UBS_INVALID_PARAM;
}
}
Result SocketBase::CreateRxOps(SocketType value, const SocketPtr &sock, DataRxOps *&ops)
{
if (sock == nullptr) {
return UBS_INVALID_PARAM;
}
if (value == SocketType::SOCK_TYPE_UMQ) {
using namespace umq;
UmqSocketPtr umqSock = RefConvert<Socket, UmqSocket>(sock);
auto umqOps = new (std::nothrow) UmqRxOps(umqSock->raw_socket_, umqSock->UmqHandle());
if (umqOps == nullptr) {
return UBS_MALLOC_FAILED;
}
ops = umqOps;
return UBS_OK;
} else {
return UBS_INVALID_PARAM;
}
}
Result SocketBase::CreateAcceptorOps(SocketType value, const SocketPtr &sock, AcceptorOps *&acceptorOps)
{
if (sock == nullptr) {
return UBS_INVALID_PARAM;
}
if (value == SocketType::SOCK_TYPE_UMQ) {
using namespace umq;
UmqSocketPtr umqSock = RefConvert<Socket, UmqSocket>(sock);
auto umqOps = new (std::nothrow) UmqAcceptorOps(sock->raw_socket_);
if (umqOps == nullptr) {
return UBS_MALLOC_FAILED;
}
acceptorOps = umqOps;
return UBS_OK;
} else {
return UBS_INVALID_PARAM;
}
}
Result SocketBase::CreateConnectorOps(SocketType value, const SocketPtr &sock, ConnectorOps *&connectorOps)
{
if (sock == nullptr) {
return UBS_INVALID_PARAM;
}
if (value == SocketType::SOCK_TYPE_UMQ) {
using namespace umq;
UmqSocketPtr umqSock = RefConvert<Socket, UmqSocket>(sock);
auto umqOps = new (std::nothrow) UmqConnectorOps(sock->raw_socket_);
if (umqOps == nullptr) {
return UBS_MALLOC_FAILED;
}
connectorOps = umqOps;
return UBS_OK;
} else {
return UBS_INVALID_PARAM;
}
}
int SocketBase::GetSockOpt(int fd, int level, int optname, void *optval, socklen_t *optlen)
{
if (optval == nullptr || optlen == nullptr) {
errno = EINVAL;
UBS_VLOG_ERR("getsockopt optval or optlen is null\n");
return -1;
}
if (level == static_cast<int>(UbsocketLevel::SOL_UB)) {
switch (static_cast<UbSocketOpt>(optname)) {
case UbSocketOpt::UBS_OPT_PROTOCOL: {
int connectType = static_cast<int>(type_);
memcpy(optval, &connectType, sizeof(int));
*optlen = sizeof(int);
return 0;
}
default: {
errno = EINVAL;
return -1;
}
}
}
errno = EINVAL;
return -1;
}
}
}