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

📄 ioqueue_symbian.cpp

📁 一个开源的sip源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
    if (type_ == TYPE_READ)
	sock_->Socket().CancelRecv();
    else if (type_ == TYPE_ACCEPT)
	sock_->Socket().CancelAccept();

    type_ = TYPE_NONE;
}

//
// Cancel operation and call callback.
//
void CIoqueueCallback::CancelOperation(pj_ioqueue_op_key_t *op_key, 
				       pj_ssize_t bytes_status)
{
    Type cur_type = type_;

    Cancel();

    if (cur_type == TYPE_READ) {
    	if (cb_.on_read_complete)
    	    cb_.on_read_complete(key_, op_key, bytes_status);
    } else if (cur_type == TYPE_ACCEPT)
	;
}


/////////////////////////////////////////////////////////////////////////////
/*
 * IO Queue key structure.
 */
struct pj_ioqueue_key_t
{
    CIoqueueCallback	*cbObj;
};


/*
 * Return the name of the ioqueue implementation.
 */
PJ_DEF(const char*) pj_ioqueue_name(void)
{
    return "ioqueue-symbian";
}


/*
 * Create a new I/O Queue framework.
 */
PJ_DEF(pj_status_t) pj_ioqueue_create(	pj_pool_t *pool, 
					pj_size_t max_fd,
					pj_ioqueue_t **p_ioqueue)
{
    pj_ioqueue_t *ioq;

    PJ_UNUSED_ARG(max_fd);

    ioq = PJ_POOL_ZALLOC_T(pool, pj_ioqueue_t);
    *p_ioqueue = ioq;
    return PJ_SUCCESS;
}


/*
 * Destroy the I/O queue.
 */
PJ_DEF(pj_status_t) pj_ioqueue_destroy( pj_ioqueue_t *ioq )
{
    PJ_UNUSED_ARG(ioq);
    return PJ_SUCCESS;
}


/*
 * Set the lock object to be used by the I/O Queue. 
 */
PJ_DEF(pj_status_t) pj_ioqueue_set_lock( pj_ioqueue_t *ioq, 
					 pj_lock_t *lock,
					 pj_bool_t auto_delete )
{
    /* Don't really need lock for now */
    PJ_UNUSED_ARG(ioq);
    
    if (auto_delete) {
	pj_lock_destroy(lock);
    }

    return PJ_SUCCESS;
}


/*
 * Register a socket to the I/O queue framework. 
 */
PJ_DEF(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,
					      pj_ioqueue_t *ioq,
					      pj_sock_t sock,
					      void *user_data,
					      const pj_ioqueue_callback *cb,
                                              pj_ioqueue_key_t **p_key )
{
    pj_ioqueue_key_t *key;

    key = PJ_POOL_ZALLOC_T(pool, pj_ioqueue_key_t);
    key->cbObj = CIoqueueCallback::NewL(ioq, key, sock, cb, user_data);

    *p_key = key;
    return PJ_SUCCESS;
}

/*
 * Unregister from the I/O Queue framework. 
 */
PJ_DEF(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key )
{
    if (key == NULL || key->cbObj == NULL)
	return PJ_SUCCESS;

    // Cancel pending async object
    if (key->cbObj && key->cbObj->IsActive()) {
	key->cbObj->Cancel();
    }

    // Close socket.
    key->cbObj->get_pj_socket()->Socket().Close();
    delete key->cbObj->get_pj_socket();

    // Delete async object.
    if (key->cbObj) {
	delete key->cbObj;
	key->cbObj = NULL;
    }

    return PJ_SUCCESS;
}


/*
 * Get user data associated with an ioqueue key.
 */
PJ_DEF(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key )
{
    return key->cbObj->get_user_data();
}


/*
 * Set or change the user data to be associated with the file descriptor or
 * handle or socket descriptor.
 */
PJ_DEF(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key,
                                              void *user_data,
                                              void **old_data)
{
    if (old_data)
	*old_data = key->cbObj->get_user_data();
    key->cbObj->set_user_data(user_data);

    return PJ_SUCCESS;
}


/*
 * Initialize operation key.
 */
PJ_DEF(void) pj_ioqueue_op_key_init( pj_ioqueue_op_key_t *op_key,
				     pj_size_t size )
{
    pj_bzero(op_key, size);
}


/*
 * Check if operation is pending on the specified operation key.
 */
PJ_DEF(pj_bool_t) pj_ioqueue_is_pending( pj_ioqueue_key_t *key,
                                         pj_ioqueue_op_key_t *op_key )
{
    return key->cbObj->get_op_key()==op_key &&
	   key->cbObj->IsActive();
}


/*
 * Post completion status to the specified operation key and call the
 * appropriate callback. 
 */
PJ_DEF(pj_status_t) pj_ioqueue_post_completion( pj_ioqueue_key_t *key,
                                                pj_ioqueue_op_key_t *op_key,
                                                pj_ssize_t bytes_status )
{
    if (pj_ioqueue_is_pending(key, op_key)) {
	key->cbObj->CancelOperation(op_key, bytes_status);
    }
    return PJ_SUCCESS;
}


#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0
/**
 * Instruct I/O Queue to accept incoming connection on the specified 
 * listening socket.
 */
PJ_DEF(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key,
                                       pj_ioqueue_op_key_t *op_key,
				       pj_sock_t *new_sock,
				       pj_sockaddr_t *local,
				       pj_sockaddr_t *remote,
				       int *addrlen )
{
    
    return key->cbObj->StartAccept(op_key, new_sock, local, remote, addrlen);
}


/*
 * Initiate non-blocking socket connect.
 */
PJ_DEF(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key,
					const pj_sockaddr_t *addr,
					int addrlen )
{
    PJ_ASSERT_RETURN(addrlen == sizeof(pj_sockaddr_in), PJ_EINVAL);

    RSocket &rSock = key->cbObj->get_pj_socket()->Socket();
    TInetAddr inetAddr;
    PjSymbianOS::pj2Addr(*(const pj_sockaddr_in*)addr, inetAddr);
    TRequestStatus reqStatus;

    // We don't support async connect for now.
    PJ_TODO(IOQUEUE_SUPPORT_ASYNC_CONNECT);

    rSock.Connect(inetAddr, reqStatus);
    User::WaitForRequest(reqStatus);

    if (reqStatus == KErrNone)
	return PJ_SUCCESS;

    return PJ_RETURN_OS_ERROR(reqStatus.Int());
}


#endif	/* PJ_HAS_TCP */

/*
 * Poll the I/O Queue for completed events.
 */
PJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioq,
			     const pj_time_val *timeout)
{
    /* Polling is not necessary on Symbian, since all async activities
     * are registered to active scheduler.
     */
    PJ_UNUSED_ARG(ioq);
    PJ_UNUSED_ARG(timeout);
    return 0;
}


/*
 * Instruct the I/O Queue to read from the specified handle.
 */
PJ_DEF(pj_status_t) pj_ioqueue_recv( pj_ioqueue_key_t *key,
                                     pj_ioqueue_op_key_t *op_key,
				     void *buffer,
				     pj_ssize_t *length,
				     pj_uint32_t flags )
{
    // If socket has reader, delete it.
    if (key->cbObj->get_pj_socket()->Reader())
    	key->cbObj->get_pj_socket()->DestroyReader();
    
    // Clear flag
    flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC;
    return key->cbObj->StartRead(op_key, buffer, length, flags, NULL, NULL);
}


/*
 * 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)
{
    // If socket has reader, delete it.
    if (key->cbObj->get_pj_socket()->Reader())
    	key->cbObj->get_pj_socket()->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);
}


/*
 * Instruct the I/O Queue to write to the handle.
 */
PJ_DEF(pj_status_t) pj_ioqueue_send( pj_ioqueue_key_t *key,
                                     pj_ioqueue_op_key_t *op_key,
				     const void *data,
				     pj_ssize_t *length,
				     pj_uint32_t flags )
{
    TRequestStatus reqStatus;
    TPtrC8 aBuffer((const TUint8*)data, (TInt)*length);
    TSockXfrLength aLen;
    
    PJ_UNUSED_ARG(op_key);

    // Forcing pending operation is not supported.
    PJ_ASSERT_RETURN((flags & PJ_IOQUEUE_ALWAYS_ASYNC)==0, PJ_EINVAL);

    // Clear flag
    flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC;

    key->cbObj->get_pj_socket()->Socket().Send(aBuffer, flags, reqStatus, aLen);
    User::WaitForRequest(reqStatus);

    if (reqStatus.Int() != KErrNone)
	return PJ_RETURN_OS_ERROR(reqStatus.Int());

    //At least in UIQ Emulator, aLen.Length() reports incorrect length
    //for UDP (some newlc.com users seem to have reported this too).
    //*length = aLen.Length();
    return PJ_SUCCESS;
}


/*
 * Instruct the I/O Queue to write to the handle.
 */
PJ_DEF(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key,
                                       pj_ioqueue_op_key_t *op_key,
				       const void *data,
				       pj_ssize_t *length,
                                       pj_uint32_t flags,
				       const pj_sockaddr_t *addr,
				       int addrlen)
{
    TRequestStatus reqStatus;
    TPtrC8 aBuffer;
    TInetAddr inetAddr;
    TSockXfrLength aLen;
    
    PJ_UNUSED_ARG(op_key);

    // Forcing pending operation is not supported.
    PJ_ASSERT_RETURN((flags & PJ_IOQUEUE_ALWAYS_ASYNC)==0, PJ_EINVAL);

    // Must be pj_sockaddr_in for now.
    PJ_ASSERT_RETURN(addrlen == sizeof(pj_sockaddr_in), PJ_EINVAL);

    // Clear flag
    flags &= ~PJ_IOQUEUE_ALWAYS_ASYNC;

    aBuffer.Set((const TUint8*)data, (TInt)*length);
    PjSymbianOS::pj2Addr(*(const pj_sockaddr_in*)addr, inetAddr);
    CPjSocket *pjSock = key->cbObj->get_pj_socket();

    pjSock->Socket().SendTo(aBuffer, inetAddr, flags, reqStatus, aLen);
    User::WaitForRequest(reqStatus);

    if (reqStatus.Int() != KErrNone)
	return PJ_RETURN_OS_ERROR(reqStatus.Int());

    //At least in UIQ Emulator, aLen.Length() reports incorrect length
    //for UDP (some newlc.com users seem to have reported this too).
    //*length = aLen.Length();
    return PJ_SUCCESS;
}

⌨️ 快捷键说明

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