/* * 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); }
// // Handle asynchronous Accept() completion. // CPjSocket *CIoqueueCallback::HandleAcceptCompletion() { CPjSocket *pjNewSock = new CPjSocket (get_pj_socket()->GetAf(), get_pj_socket()->GetSockType(), blank_sock_); int addrlen = 0; if (pending_data_.accept_.new_sock_) { *pending_data_.accept_.new_sock_ = (pj_sock_t) pjNewSock; pending_data_.accept_.new_sock_ = NULL; } if (pending_data_.accept_.local_) { TInetAddr aAddr; pj_sockaddr *ptr_sockaddr; blank_sock_.LocalName (aAddr); ptr_sockaddr = (pj_sockaddr*) pending_data_.accept_.local_; addrlen = *pending_data_.accept_.addrlen_; PjSymbianOS::Addr2pj (aAddr, *ptr_sockaddr, &addrlen); pending_data_.accept_.local_ = NULL; } if (pending_data_.accept_.remote_) { TInetAddr aAddr; pj_sockaddr *ptr_sockaddr; blank_sock_.RemoteName (aAddr); ptr_sockaddr = (pj_sockaddr*) pending_data_.accept_.remote_; addrlen = *pending_data_.accept_.addrlen_; PjSymbianOS::Addr2pj (aAddr, *ptr_sockaddr, &addrlen); pending_data_.accept_.remote_ = NULL; } if (pending_data_.accept_.addrlen_) { if (addrlen == 0) { if (pjNewSock->GetAf() == PJ_AF_INET) addrlen = sizeof (pj_sockaddr_in); else if (pjNewSock->GetAf() == PJ_AF_INET6) addrlen = sizeof (pj_sockaddr_in6); else { pj_assert (!"Unsupported address family"); } } *pending_data_.accept_.addrlen_ = addrlen; pending_data_.accept_.addrlen_ = NULL; } return pjNewSock; }
/* * Accept incoming connections */ PJ_DEF(pj_status_t) pj_sock_accept( pj_sock_t serverfd, pj_sock_t *newsock, pj_sockaddr_t *addr, int *addrlen) { PJ_CHECK_STACK(); PJ_ASSERT_RETURN(serverfd && newsock, PJ_EINVAL); CPjSocket *pjSock = (CPjSocket*)serverfd; RSocket &rSock = pjSock->Socket(); // Create a 'blank' socket RSocket newSock; newSock.Open(PjSymbianOS::Instance()->SocketServ()); // Call Accept() TRequestStatus reqStatus; rSock.Accept(newSock, reqStatus); User::WaitForRequest(reqStatus); if (reqStatus != KErrNone) { return PJ_RETURN_OS_ERROR(reqStatus.Int()); } // Create PJ socket CPjSocket *newPjSock = new CPjSocket(pjSock->GetAf(), pjSock->GetSockType(), newSock); newPjSock->SetConnected(true); *newsock = (pj_sock_t) newPjSock; if (addr && addrlen) { return pj_sock_getpeername(*newsock, addr, addrlen); } return PJ_SUCCESS; }