⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rvsocket.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:

    res = RvSemaphoreConstruct(&RvSharer.requestSem, RvUint32Const(0));
    if (res != RV_OK)
    {
        RvLockDestruct(&RvSharer.lock);
        return res;
    }

    res = RvSemaphoreConstruct(&RvSharer.responseSem, RvUint32Const(0));
    if (res != RV_OK)
    {
        RvSemaphoreDestruct(&RvSharer.requestSem);
        RvLockDestruct(&RvSharer.lock);
        return res;
    }

    res = RvThreadConstruct(&RvSharer.thread, RvSocketSharerThread, &RvSharer);
    if (res != RV_OK)
    {
        RvSemaphoreDestruct(&RvSharer.responseSem);
        RvSemaphoreDestruct(&RvSharer.requestSem);
        RvLockDestruct(&RvSharer.lock);
        return res;
    }

    /* Create and start the sharer thread. */
    res = RvThreadCreate(&RvSharer.thread);
    if (res == RV_OK)
        res = RvThreadStart(&RvSharer.thread);

    if (res != RV_OK)
    {
        RvThreadDestruct(&RvSharer.thread);
        RvSemaphoreDestruct(&RvSharer.responseSem);
        RvSemaphoreDestruct(&RvSharer.requestSem);
        RvLockDestruct(&RvSharer.lock);
    }

    return res;
}


static RvStatus RvSocketSharerEnd(void)
{
    /* Make sure we exit the sharer thread */
    RvLockGet(&RvSharer.lock);
    RvSharer.cmd.command = RvSocketSharerCommandExit; /* Post an exit request */
    if (RvSemaphorePost(&RvSharer.requestSem) == RV_OK)
        RvSemaphoreWait(&RvSharer.responseSem);

    RvThreadDestruct(&RvSharer.thread);
    RvSemaphoreDestruct(&RvSharer.responseSem);
    RvSemaphoreDestruct(&RvSharer.requestSem);
    RvLockDestruct(&RvSharer.lock);
    return RV_OK;
}


/********************************************************************************************
 * RvSocketSharerConstruct
 *
 * purpose : Construct a socket using the socket sharer
 * input   : sock   - Socket to construct
 *           addressType    - Type of address to create
 *           protocolType   - Type of protocol used by the socket
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
static RvStatus RvSocketSharerConstruct(
    IN RvSocket*        sock,
    IN RvAddressType    addressType,
    IN RvSocketProtocol protocolType)
{
    RvStatus res;

    RvSharer.cmd.command = RvSocketSharerCommandCreate;
    RvSharer.cmd.socket = sock;
    RvSharer.cmd.addressType = addressType;
    RvSharer.cmd.protocolType = protocolType;

    /* Send command to the sharer thread */
    res = RvLockGet(&RvSharer.lock);
    if (res != RV_OK)
        return res;

    res = RvSemaphorePost(&RvSharer.requestSem);
    if (res == RV_OK)
        res = RvSemaphoreWait(&RvSharer.responseSem);

    if (res == RV_OK)
        res = (RvStatus)RvSharer.result;

    RvLockRelease(&RvSharer.lock);
    return res;
}

static RvStatus RvSocketSharerDestruct(IN RvSocket* sock)
{
    RvStatus res;

    RvSharer.cmd.command = RvSocketSharerCommandDestroy;
    RvSharer.cmd.socket = sock;

    /* Send command to the sharer thread */
    res = RvLockGet(&RvSharer.lock);
    if (res != RV_OK)
        return res;

    res = RvSemaphorePost(&RvSharer.requestSem);
    if (res == RV_OK)
        res = RvSemaphoreWait(&RvSharer.responseSem);

    if (res == RV_OK)
        res = (RvStatus)RvSharer.result;

    RvLockRelease(&RvSharer.lock);
    return res;
}

static RvStatus RvSocketSharerShare(IN RvSocket* sock, OUT RvSocket* sharableSocket)
{
    RvStatus res;

    RvSharer.cmd.command = RvSocketSharerCommandShare;
    RvSharer.cmd.socket = sock;
    RvSharer.cmd.task = RvThreadCurrentId();
    RvSharer.cmd.sharableSocket = sharableSocket;

    /* Send command to the sharer thread */
    res = RvLockGet(&RvSharer.lock);
    if (res != RV_OK)
        return res;

    res = RvSemaphorePost(&RvSharer.requestSem);
    if (res == RV_OK)
        res = RvSemaphoreWait(&RvSharer.responseSem);

    if (res == RV_OK)
        res = (RvStatus)RvSharer.result;

    RvLockRelease(&RvSharer.lock);
    return res;
}

/* todo: open commented part! */
#define RvSocketSharerClose(_sock) /*close(*(_sock))*/


static int RvSocketSetSockOpt(
    IN RvSocket*    socket,
    IN int          level,
    IN int          optName,
    IN const char*  optVal,
    IN int          optLen)
{
    RvSocket ourSocket;
    RvStatus status;
    int res;

    status = RvSocketSharerShare(socket, &ourSocket);
    if (status != RV_OK)
        return -1;

#if (RV_OS_TYPE != RV_OS_TYPE_NUCLEUS)
    res = setsockopt(ourSocket, level, optName, optVal, optLen);
#else
    res = NU_Setsockopt(ourSocket, level, optName, optVal, optLen);
#endif

    RvSocketSharerClose(&ourSocket);

    return res;
}


#else
/* (RV_SOCKET_USE_SHARER == 0) */

#define RvSocketSharerInit() RV_OK
#define RvSocketSharerEnd() RV_OK
#define RvSocketSharerConstruct(_sock, _addressType, _protocolType) RV_OK
#define RvSocketSharerDestruct(_sock) RV_OK
#define RvSocketSharerShare(_sock, _sharableSock) (*(_sharableSock) = *(_sock)) ? RV_OK : RV_OK
#define RvSocketSharerClose(_sock)
#if (RV_OS_TYPE != RV_OS_TYPE_NUCLEUS)
#define RvSocketSetSockOpt(_sock, _level, _optName, _optVal, _optLen) \
    setsockopt(*(_sock), (_level), (_optName), (_optVal), (_optLen))
#else
#define RvSocketSetSockOpt(_sock, _level, _optName, _optVal, _optLen) \
    NU_Setsockopt(*(_sock), (_level), (_optName), (_optVal), (_optLen))
#endif



#endif  /* (RV_SOCKET_USE_SHARER == 1) */




/********************************************************************************************
 *
 *                                      Private functions
 *
 ********************************************************************************************/


#if (RV_SOCKET_TYPE == RV_SOCKET_BSD)
/* Handler for SIGPIPE signals. We get these when TCP connections tear down in a non-graceful
   manner. Their default behavior in Unix is a core dump, so we put in place this signal
   handler that just ignores this signal. */
#if (RV_OS_TYPE != RV_OS_TYPE_WINCE) && (RV_OS_TYPE != RV_OS_TYPE_OSE)
static void RvSocketHandleSigPipe(IN int sigNo)
{
    sigNo = 0;

    /* Reset this signal */
    signal(SIGPIPE, RvSocketHandleSigPipe);
}
#endif /* (RV_OS_TYPE != RV_OS_TYPE_WINCE) */
#endif /* (RV_SOCKET_TYPE == RV_SOCKET_BSD) */


/********************************************************************************************
 * RvSocketConstructHere
 *
 * purpose : Create a socket handle here. This function is internal, since some operating
 *           systems such as pSOS needs to create the socket in a specified thread, other than
 *           the one that called RvSocketConstruct()
 * input   : sock           - Socket to construct
 *           addressType    - Type of address to create
 *           protocolType   - Protocol to use with socket
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
static RvStatus RvSocketConstructHere(
    IN RvSocket*        sock,
    IN RvInt            addressType,
    IN RvSocketProtocol protocolType)
{
    int addressFamily = 0;
    RvStatus status = RV_OK;

    switch (addressType)
    {
    case RV_ADDRESS_TYPE_IPV4:
        addressFamily = AF_INET;
        break;

#if RV_SOCKET_HAS_IPV6
    case RV_ADDRESS_TYPE_IPV6:
        addressFamily = AF_INET6;
        break;
#endif

    default:
        return RvSocketErrorCode(RV_ERROR_BADPARAM);
    }

#if (RV_SOCKET_TYPE == RV_SOCKET_WIN32_WSA)

    *sock = WSASocket(addressFamily, rvSocketProtocolInfo[protocolType].protocolType,
        rvSocketProtocolInfo[protocolType].protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
    if ((*sock) == INVALID_SOCKET)
        status = RvSocketErrorCode(RV_ERROR_UNKNOWN);

#elif ((RV_SOCKET_TYPE == RV_SOCKET_BSD) || (RV_SOCKET_TYPE == RV_SOCKET_PSOS))

    if ((*sock = socket(addressFamily,  rvSocketProtocolInfo[protocolType].protocolType,
        rvSocketProtocolInfo[protocolType].protocol)) < 0)
        status = RvSocketErrorCode(RV_ERROR_UNKNOWN);

#elif (RV_SOCKET_TYPE == RV_SOCKET_NUCLEUS)

    if ((*sock = NU_Socket(addressFamily,  rvSocketProtocolInfo[protocolType].protocolType,
        rvSocketProtocolInfo[protocolType].protocol)) < 0)
        status = RvSocketErrorCode(RV_ERROR_UNKNOWN);

    /* make sure there's no old socket still open here */
    if (nuConInfo[*sock].socketState!=0)
    {
        RvSocketTaskClean(*sock);
        RvSocketCallback(*sock, RV_SELECT_CLOSE);
    }

    memset(nuConInfo+(*sock), 0, sizeof(nuConInfo[*sock]));
#endif

    if (status == RV_OK)
    {
        if (protocolType == RvSocketProtocolTcp)
        {
            int yes = RV_TRUE;

#if (RV_OS_TYPE == RV_OS_TYPE_WIN32) || (RV_OS_TYPE == RV_OS_TYPE_WINCE)
            /* Set linger parameter of the socket. On Windows, we'll disable it. */
            RvSocketSetLinger(sock, -1);
#else
            /* On other operating systems - we set the linger timeout to 0 */
            RvSocketSetLinger(sock, 0);
#endif

#if (RV_OS_TYPE != RV_OS_TYPE_NUCLEUS)      /* no support for KEEP-ALIVE in nucleus */
            /* Make sure the TCP connection sends keep-alive messages once in a while */
            if (RvSocketSetSockOpt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&yes, sizeof(yes)) != 0)
            {
                RvLogError(&rvSocketLogSource, (&rvSocketLogSource,
                    "RvSocketConstructHere: Failed to setsockopt(SO_KEEPALIVE) %d",
                    RvSocketErrNo));
            }
#endif
            /* Disable Nagle algorithm - we want our messages to be sent as soon as possible */
            if (RvSocketSetSockOpt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes)) != 0)
            {
                RvLogError(&rvSocketLogSource, (&rvSocketLogSource,
                    "RvSocketConstructHere: Failed to setsockopt(TCP_NODELAY) %d",
                    RvSocketErrNo));
            }
        }
    }
    else
    {
        RvLogError(&rvSocketLogSource, (&rvSocketLogSource,
            "RvSocketConstructHere: Failed to call socket() - %d", RvSocketErrNo));
    }

    return RV_OK;
}


/********************************************************************************************
 * RvSocketSockAddrToAddress
 *
 * purpose : Convert a sockaddr struct into an RvAddress struct.
 * input   : sockaddr   - Socket address
 *           socklen    - Socket address length
 * output  : address    - Address constructed
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
static RvStatus RvSocketSockAddrToAddress(
    IN  RvUint8*    sockaddr,
    IN  int         socklen,
    OUT RvAddress*  address)
{
    RV_UNUSED_ARG(socklen);

    switch (((struct sockaddr_in*)sockaddr)->sin_family)
    {
    case AF_INET:
        {
            struct sockaddr_in* sin = (struct sockaddr_in *)sockaddr;

            RvAddressConstructIpv4(address,
                (RvUint32)sin->sin_addr.s_addr, ntohs(sin->sin_port));
        }
        break;

#if RV_SOCKET_HAS_IPV6
    case AF_INET6:
        {
            struct sockaddr_in6* sin = (struct sockaddr_in6*)sockaddr;

            return RvAddressConstructIpv6(address, sin->sin6_addr,
                ntohs(sin->sin6_port),
                sin->sin6_flowinfo, sin->sin6_scope_id);
        }
        break;
#endif  /* RV_SOCKET_HAS_IPV6 */

    default:
        return RvSocketErrorCode(RV_ERROR_NOTSUPPORTED);
    }

    return RV_OK;
}

/********************************************************************************************
 * RvSocketAddressToSockAddr
 *
 * purpose : Convert an RvAddress struct into a sockaddr struct.
 * input   : address    - Address to convert
 * output  : sockaddr   - Socket address constructed
 *           socklen    - Socket address length constructed
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
static RvStatus RvSocketAddressToSockAddr(
    IN  RvAddress*      address,
    OUT RV_SOCKADDR_PTR sockaddr,
    OUT int*            socklen)
{
    RvStatus res = RV_OK;

    switch (RvAddressGetType(address))
    {
    case RV_ADDRESS_TYPE_IPV4:
        {
            struct sockaddr_in* sin = (struct sockaddr_in *)sockaddr;
            const RvAddressIpv4* ipv4Addr;

            ipv4Addr = RvAddressGetIpv4(address);
            if (ipv4Addr != NULL)
            {
                memset(sin, 0, sizeof(struct sockaddr_in));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -