Exemple #1
0
/*
 * Receive data.
 */
PJ_DEF(pj_status_t) pj_sock_recvfrom(pj_sock_t sock,
				     void *buf,
				     pj_ssize_t *len,
				     unsigned flags,
				     pj_sockaddr_t *from,
				     int *fromlen)
{
    PJ_CHECK_STACK();

    PJ_ASSERT_RETURN(sock && buf && len && from && fromlen, PJ_EINVAL);
    PJ_ASSERT_RETURN(*len > 0, PJ_EINVAL);
    PJ_ASSERT_RETURN(*fromlen >= (int)sizeof(pj_sockaddr_in), PJ_EINVAL);

    CPjSocket *pjSock = (CPjSocket*)sock;
    RSocket &rSock = pjSock->Socket();

    if (pjSock->Reader()) {
	CPjSocketReader *reader = pjSock->Reader();

	while (reader->IsActive() && !reader->HasData()) {
	    User::WaitForAnyRequest();
	}

	if (reader->HasData()) {
	    TPtr8 data((TUint8*)buf, (TInt)*len);
	    TInetAddr inetAddr;

	    reader->ReadData(data, &inetAddr);

	    *len = data.Length();

	    if (from && fromlen) {
		return PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr*)from, 
					    fromlen);
	    } else {
	    	return PJ_SUCCESS;
	    }
	}
    }

    TInetAddr inetAddr;
    TRequestStatus reqStatus;
    TSockXfrLength recvLen;
    TPtr8 data((TUint8*)buf, (TInt)*len, (TInt)*len);

    rSock.RecvFrom(data, inetAddr, flags, reqStatus, recvLen);
    User::WaitForRequest(reqStatus);

    if (reqStatus == KErrNone) {
	//*len = (TInt)recvLen.Length();
	*len = data.Length();
	return PjSymbianOS::Addr2pj(inetAddr, *(pj_sockaddr*)from, fromlen);
    } else {
	*len = -1;
	*fromlen = -1;
	return PJ_RETURN_OS_ERROR(reqStatus.Int());
    }
}
Exemple #2
0
/*
 * Receive data.
 */
PJ_DEF(pj_status_t) pj_sock_recv(pj_sock_t sock,
				 void *buf,
				 pj_ssize_t *len,
				 unsigned flags)
{
    PJ_CHECK_STACK();

    PJ_ASSERT_RETURN(sock && buf && len, PJ_EINVAL);
    PJ_ASSERT_RETURN(*len > 0, PJ_EINVAL);

    // Return failure if access point is marked as down by app.
    PJ_SYMBIAN_CHECK_CONNECTION();

    CPjSocket *pjSock = (CPjSocket*)sock;

    if (pjSock->Reader()) {
	CPjSocketReader *reader = pjSock->Reader();

	while (reader->IsActive() && !reader->HasData()) {
	    User::WaitForAnyRequest();
	}

	if (reader->HasData()) {
	    TPtr8 data((TUint8*)buf, (TInt)*len);
	    TInetAddr inetAddr;

	    reader->ReadData(data, &inetAddr);

	    *len = data.Length();
	    return PJ_SUCCESS;
	}
    }

    TRequestStatus reqStatus;
    TSockXfrLength recvLen;
    TPtr8 data((TUint8*)buf, (TInt)*len, (TInt)*len);

    if (pjSock->IsDatagram()) {
	pjSock->Socket().Recv(data, flags, reqStatus);
    } else {
	// Using static like this is not pretty, but we don't need to use
	// the value anyway, hence doing it like this is probably most
	// optimal.
	static TSockXfrLength len;
	pjSock->Socket().RecvOneOrMore(data, flags, reqStatus, len);
    }
    User::WaitForRequest(reqStatus);

    if (reqStatus == KErrNone) {
	//*len = (TInt)recvLen.Length();
	*len = data.Length();
	return PJ_SUCCESS;
    } else {
	*len = -1;
	return PJ_RETURN_OS_ERROR(reqStatus.Int());
    }
}
/*
 * This function behaves similarly as #pj_ioqueue_recv(), except that it is
 * normally called for socket, and the remote address will also be returned
 * along with the data.
 */
PJ_DEF(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_key_t *key,
        pj_ioqueue_op_key_t *op_key,
        void *buffer,
        pj_ssize_t *length,
        pj_uint32_t flags,
        pj_sockaddr_t *addr,
        int *addrlen)
{
    CPjSocket *sock = key->cbObj->get_pj_socket();

    // If address is specified, check that the length match the
    // address family
    if (addr || addrlen) {
        PJ_ASSERT_RETURN(addr && addrlen && *addrlen, PJ_EINVAL);
        if (sock->GetAf() == PJ_AF_INET) {
            PJ_ASSERT_RETURN(*addrlen>=(int)sizeof(pj_sockaddr_in), PJ_EINVAL);
        } else if (sock->GetAf() == PJ_AF_INET6) {
            PJ_ASSERT_RETURN(*addrlen>=(int)sizeof(pj_sockaddr_in6), PJ_EINVAL);
        }
    }

    // If socket has reader, delete it.
    if (sock->Reader())
        sock->DestroyReader();

    if (key->cbObj->IsActive())
        return PJ_EBUSY;

    // Clear flag
    flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC;
    return key->cbObj->StartRead(op_key, buffer, length, flags, addr, addrlen);
}
PJ_DEF(int) pj_sock_select( int n, 
			    pj_fd_set_t *readfds, 
			    pj_fd_set_t *writefds,
			    pj_fd_set_t *exceptfds, 
			    const pj_time_val *timeout)
{
    CPjTimeoutTimer *pjTimer;
    unsigned i;

    PJ_UNUSED_ARG(n);
    PJ_UNUSED_ARG(writefds);
    PJ_UNUSED_ARG(exceptfds);

    if (timeout) {
	pjTimer = PjSymbianOS::Instance()->SelectTimeoutTimer();
	pjTimer->StartTimer(timeout->sec*1000 + timeout->msec);

    } else {
	pjTimer = NULL;
    }

    /* Scan for readable sockets */

    if (readfds) {
	symbian_fd_set *fds = (symbian_fd_set *)readfds;

	do {
	    /* Scan sockets for readily available data */
	    for (i=0; i<fds->count; ++i) {
		CPjSocket *pjsock = fds->sock[i];

		if (pjsock->Reader()) {
		    if (pjsock->Reader()->HasData() && !pjsock->Reader()->IsActive()) {

			/* Found socket with data ready */
			PJ_FD_ZERO(readfds);
			PJ_FD_SET((pj_sock_t)pjsock, readfds);

			/* Cancel timer, if any */
			if (pjTimer) {
			    pjTimer->Cancel();
			}

			/* Clear writable and exception fd_set */
			if (writefds)
			    PJ_FD_ZERO(writefds);
			if (exceptfds)
			    PJ_FD_ZERO(exceptfds);

			return 1;

		    } else if (!pjsock->Reader()->IsActive())
			pjsock->Reader()->StartRecvFrom();

		} else {
		    pjsock->CreateReader();
		    pjsock->Reader()->StartRecvFrom();
		}
	    }

	    PjSymbianOS::Instance()->WaitForActiveObjects();

	} while (pjTimer==NULL || !pjTimer->HasTimedOut());
    }


    /* Timeout */

    if (readfds)
	PJ_FD_ZERO(readfds);
    if (writefds)
	PJ_FD_ZERO(writefds);
    if (exceptfds)
	PJ_FD_ZERO(exceptfds);

    return 0;
}