/* * 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()); } }
/* * 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; }