[ofw] [ND 4/7] ND: connector APIs

Sean Hefty sean.hefty at intel.com
Mon Apr 6 10:22:14 PDT 2009


/*
 * Copyright (c) 2009 Intel Corporation. All rights reserved.
 *
 * This software is available to you under the OpenIB.org BSD license
 * below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#pragma once

#ifndef _ND_CONNECTOR_H_
#define _ND_CONNECTOR_H_

#include <initguid.h>
#include <ndspi.h>
#include "nd_base.h"
#include "nd_adapter.h"


#define ND_PRIVATE_DATA_SIZE	56


class CNDConnector : INDConnector, public CNDBase
{
public:
	// IUnknown methods
	STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
	STDMETHODIMP_(ULONG) AddRef();
	STDMETHODIMP_(ULONG) Release();

	// INDOverlapped methods
	STDMETHODIMP CancelOverlappedRequests();
	STDMETHODIMP GetOverlappedResult(OVERLAPPED *pOverlapped,
									 SIZE_T *pNumberOfBytesTransferred, BOOL bWait);

	// INDConnector methods
	STDMETHODIMP CreateEndpoint(INDCompletionQueue* pInboundCq,
								INDCompletionQueue* pOutboundCq,
								SIZE_T nInboundEntries, SIZE_T nOutboundEntries,
								SIZE_T nInboundSge, SIZE_T nOutboundSge,
								SIZE_T InboundReadLimit, SIZE_T OutboundReadLimit,
								SIZE_T* pMaxInlineData, INDEndpoint** ppEndpoint);
	STDMETHODIMP Connect(INDEndpoint* pEndpoint, 
						 const struct sockaddr* pAddress, SIZE_T AddressLength,
						 INT Protocol, USHORT LocalPort,
						 const void* pPrivateData, SIZE_T PrivateDataLength,
						 OVERLAPPED* pOverlapped);
	STDMETHODIMP CompleteConnect(OVERLAPPED* pOverlapped);
	STDMETHODIMP Accept(INDEndpoint* pEndpoint,
						const void* pPrivateData, SIZE_T PrivateDataLength,
						OVERLAPPED* pOverlapped);
	STDMETHODIMP Reject(const void* pPrivateData, SIZE_T PrivateDataLength);
	STDMETHODIMP GetConnectionData(SIZE_T* pInboundReadLimit,
								   SIZE_T* pOutboundReadLimit,
								   void* pPrivateData, SIZE_T* pPrivateDataLength);
	STDMETHODIMP GetLocalAddress(struct sockaddr* pAddress, SIZE_T* pAddressLength);
	STDMETHODIMP GetPeerAddress(struct sockaddr* pAddress, SIZE_T* pAddressLength);
	STDMETHODIMP NotifyDisconnect(OVERLAPPED* pOverlapped);
	STDMETHODIMP Disconnect(OVERLAPPED* pOverlapped);

	CNDConnector(CNDAdapter *pAdapter);
	~CNDConnector();
	void Delete() {delete this;}
	static STDMETHODIMP
	CreateInstance(CNDAdapter *pAdapter, INDConnector** ppConnector)
	{
		HRESULT hr;
		CNDConnector *conn;

		conn = new CNDConnector(pAdapter);
		if (conn == NULL) {
			hr = ND_NO_MEMORY;
			goto err1;
		}

		hr = conn->Init();
		if (FAILED(hr)) {
			goto err2;
		}

		*ppConnector = conn;
		return ND_SUCCESS;

	err2:
		conn->Release();
	err1:
		*ppConnector = NULL;
		return hr;
	}

	IWVConnectEndpoint	*m_pWvConnEp;
	CNDAdapter			*m_pAdapter;

protected:
	STDMETHODIMP		Init();
};

#endif // _ND_CONNECTOR_H_

/*
 * Copyright (c) 2009 Intel Corporation. All rights reserved.
 *
 * This software is available to you under the OpenIB.org BSD license
 * below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "nd_connect.h"
#include "nd_ep.h"


CNDConnector::CNDConnector(CNDAdapter *pAdapter)
{
	pAdapter->AddRef();
	m_pAdapter = pAdapter;
	m_pWvConnEp = NULL;
}

STDMETHODIMP CNDConnector::
Init(void)
{
	return m_pAdapter->m_pWvProvider->CreateConnectEndpoint(&m_pWvConnEp);
}

CNDConnector::~CNDConnector()
{
	if (m_pWvConnEp != NULL) {
		m_pWvConnEp->Release();
	}
	m_pAdapter->Release();
}

STDMETHODIMP CNDConnector::
QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
{
	if (riid != IID_IUnknown && riid != IID_INDConnector) {
		*ppvObj = NULL;
		return E_NOINTERFACE;
	}

	*ppvObj = this;
	AddRef();
	return ND_SUCCESS;
}

STDMETHODIMP_(ULONG) CNDConnector::
AddRef(void)
{
	return CNDBase::AddRef();
}

STDMETHODIMP_(ULONG) CNDConnector::
Release(void)
{
	return CNDBase::Release();
}

STDMETHODIMP CNDConnector::
CancelOverlappedRequests(void)
{
	return m_pWvConnEp->CancelOverlappedRequests();
}

STDMETHODIMP CNDConnector::
GetOverlappedResult(OVERLAPPED *pOverlapped,
					SIZE_T *pNumberOfBytesTransferred, BOOL bWait)
{
	return m_pWvConnEp->GetOverlappedResult(pOverlapped,
											(DWORD *) pNumberOfBytesTransferred,
											bWait);
}

STDMETHODIMP CNDConnector::
CreateEndpoint(INDCompletionQueue* pInboundCq, INDCompletionQueue* pOutboundCq,
			   SIZE_T nInboundEntries, SIZE_T nOutboundEntries,
			   SIZE_T nInboundSge, SIZE_T nOutboundSge,
			   SIZE_T InboundReadLimit, SIZE_T OutboundReadLimit,
			   SIZE_T* pMaxInlineData, INDEndpoint** ppEndpoint)
{
	CNDCompletionQueue *incq = (CNDCompletionQueue *) pInboundCq;
	CNDCompletionQueue *outcq = (CNDCompletionQueue *) pOutboundCq;

	return CNDEndpoint::CreateInstance(this, incq, outcq,
									   nInboundEntries, nOutboundEntries,
									   nInboundSge, nOutboundSge,
									   InboundReadLimit, OutboundReadLimit,
									   pMaxInlineData, ppEndpoint);
}

STDMETHODIMP CNDConnector::
Connect(INDEndpoint* pEndpoint,
		const struct sockaddr* pAddress, SIZE_T AddressLength,
		INT Protocol, USHORT LocalPort,
		const void* pPrivateData, SIZE_T PrivateDataLength,
		OVERLAPPED* pOverlapped)
{
	// TODO
	return ND_NOT_SUPPORTED;
}

STDMETHODIMP CNDConnector::
CompleteConnect(OVERLAPPED* pOverlapped)
{
	// TODO
	return ND_NOT_SUPPORTED;
}

STDMETHODIMP CNDConnector::
Accept(INDEndpoint* pEndpoint,
	   const void* pPrivateData, SIZE_T PrivateDataLength,
	   OVERLAPPED* pOverlapped)
{
	// TODO
	return ND_NOT_SUPPORTED;
}

STDMETHODIMP CNDConnector::
Reject(const void* pPrivateData, SIZE_T PrivateDataLength)
{
	return m_pWvConnEp->Reject(pPrivateData, PrivateDataLength);
}

STDMETHODIMP CNDConnector::
GetConnectionData(SIZE_T* pInboundReadLimit, SIZE_T* pOutboundReadLimit,
				  void* pPrivateData, SIZE_T* pPrivateDataLength)
{
	WV_CONNECT_ATTRIBUTES attr;
	HRESULT hr;
	
	if (pPrivateDataLength && *pPrivateDataLength < ND_PRIVATE_DATA_SIZE) {
		*pPrivateDataLength = ND_PRIVATE_DATA_SIZE;
		return ND_BUFFER_OVERFLOW;
	}

	hr = m_pWvConnEp->Query(&attr);
	if (FAILED(hr)) {
		return hr;
	}

	*pInboundReadLimit = attr.Param.ResponderResources;
	*pOutboundReadLimit = attr.Param.InitiatorDepth;
	if (pPrivateDataLength) {
		RtlCopyMemory(pPrivateData, attr.Param.Data, ND_PRIVATE_DATA_SIZE);
		*pPrivateDataLength = ND_PRIVATE_DATA_SIZE;
	}
	return ND_SUCCESS;
}

static SIZE_T GetAddressSize(WV_SOCKADDR *addr)
{
	return (addr->Sa.sa_family == AF_INET) ? sizeof(addr->Sin) : sizeof(addr->Sin6);
}

STDMETHODIMP CNDConnector::
GetLocalAddress(struct sockaddr* pAddress, SIZE_T* pAddressLength)
{
	WV_CONNECT_ATTRIBUTES attr;
	HRESULT hr;
	
	hr = m_pWvConnEp->Query(&attr);
	if (FAILED(hr)) {
		return hr;
	}

	if (*pAddressLength < GetAddressSize(&attr.LocalAddress)) {
		hr = ND_BUFFER_OVERFLOW;
		goto out;
	}

	RtlCopyMemory(pAddress, &attr.LocalAddress, GetAddressSize(&attr.LocalAddress));
out:
	*pAddressLength = GetAddressSize(&attr.LocalAddress);
	return hr;
}

STDMETHODIMP CNDConnector::
GetPeerAddress(struct sockaddr* pAddress, SIZE_T* pAddressLength)
{
	WV_CONNECT_ATTRIBUTES attr;
	HRESULT hr;
	
	hr = m_pWvConnEp->Query(&attr);
	if (FAILED(hr)) {
		return hr;
	}

	if (*pAddressLength < GetAddressSize(&attr.PeerAddress)) {
		hr = ND_BUFFER_OVERFLOW;
		goto out;
	}

	RtlCopyMemory(pAddress, &attr.PeerAddress, GetAddressSize(&attr.PeerAddress));
out:
	*pAddressLength = GetAddressSize(&attr.PeerAddress);
	return hr;
}

STDMETHODIMP CNDConnector::
NotifyDisconnect(OVERLAPPED* pOverlapped)
{
	return m_pWvConnEp->NotifyDisconnect(pOverlapped);
}

STDMETHODIMP CNDConnector::
Disconnect(OVERLAPPED* pOverlapped)
{
	// TODO
	return ND_NOT_SUPPORTED;
}




More information about the ofw mailing list