#include "dapl.h"
#include "dapl_evd_util.h"
#include "dapl_ep_util.h"
void
dapl_evd_connection_callback(
IN ib_cm_handle_t ib_cm_handle,
IN const ib_cm_events_t ib_cm_event,
IN const void *private_data_ptr,
IN const void *context)
{
DAPL_EP *ep_ptr;
DAPL_EVD *evd_ptr;
DAPL_PRIVATE *prd_ptr;
DAT_EVENT_NUMBER event_type;
dapl_dbg_log(
DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,
"--> dapl_evd_connection_callback: ctxt: %p event: %x"
" cm_handle %p\n",
context,
ib_cm_event,
ib_cm_handle);
dapl_os_assert(((DAPL_HEADER *)context)->magic == DAPL_MAGIC_EP ||
((DAPL_HEADER *)context)->magic == DAPL_MAGIC_EP_EXIT);
ep_ptr = (DAPL_EP *)context;
evd_ptr = (DAPL_EVD *)ep_ptr->param.connect_evd_handle;
prd_ptr = (DAPL_PRIVATE *)private_data_ptr;
switch (ib_cm_event) {
case IB_CME_CONNECTED:
{
DAT_RETURN dat_status;
if (ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECT_PENDING) {
break;
}
dapls_ib_connected(ep_ptr);
ep_ptr->param.ep_state = DAT_EP_STATE_CONNECTED;
ep_ptr->cm_handle = ib_cm_handle;
(void) dapl_os_memcpy(ep_ptr->private_data,
prd_ptr->private_data,
IB_MAX_REQ_PDATA_SIZE);
dat_status = dapls_evd_post_connection_event(
evd_ptr,
DAT_CONNECTION_EVENT_ESTABLISHED,
(DAT_HANDLE) ep_ptr,
IB_MAX_REQ_PDATA_SIZE,
ep_ptr->private_data);
if (dat_status != DAT_SUCCESS) {
(void) dapls_ib_disconnect(ep_ptr,
DAT_CLOSE_ABRUPT_FLAG);
ep_ptr->param.ep_state =
DAT_EP_STATE_DISCONNECT_PENDING;
}
dapls_evd_post_premature_events(ep_ptr);
break;
}
case IB_CME_DISCONNECTED:
case IB_CME_DISCONNECTED_ON_LINK_DOWN:
{
if (ep_ptr->param.ep_state == DAT_EP_STATE_DISCONNECTED) {
event_type = DAT_CONNECTION_EVENT_BROKEN;
} else {
ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE,
ib_cm_event);
event_type = DAT_CONNECTION_EVENT_DISCONNECTED;
}
if (evd_ptr != NULL) {
(void) dapls_evd_post_connection_event(
evd_ptr, event_type, (DAT_HANDLE) ep_ptr, 0, 0);
}
if (ep_ptr->header.magic == DAPL_MAGIC_EP_EXIT) {
(void) dapl_ep_free(ep_ptr);
}
break;
}
case IB_CME_DESTINATION_REJECT_PRIVATE_DATA:
{
ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, ib_cm_event);
(void) dapls_evd_post_connection_event(
evd_ptr,
DAT_CONNECTION_EVENT_PEER_REJECTED,
(DAT_HANDLE) ep_ptr,
0,
0);
break;
}
case IB_CME_DESTINATION_UNREACHABLE:
{
ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, ib_cm_event);
(void) dapls_evd_post_connection_event(
evd_ptr,
DAT_CONNECTION_EVENT_UNREACHABLE,
(DAT_HANDLE) ep_ptr,
0,
0);
break;
}
case IB_CME_DESTINATION_REJECT:
case IB_CME_TOO_MANY_CONNECTION_REQUESTS:
case IB_CME_LOCAL_FAILURE:
{
ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, ib_cm_event);
(void) dapls_evd_post_connection_event(
evd_ptr,
DAT_CONNECTION_EVENT_NON_PEER_REJECTED,
(DAT_HANDLE) ep_ptr,
0,
0);
break;
}
case IB_CME_TIMED_OUT:
{
ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECTED;
dapls_ib_disconnect_clean(ep_ptr, DAT_TRUE, ib_cm_event);
(void) dapls_evd_post_connection_event(
evd_ptr,
DAT_CONNECTION_EVENT_TIMED_OUT,
(DAT_HANDLE) ep_ptr,
0,
0);
break;
}
case IB_CME_CONNECTION_REQUEST_PENDING:
case IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA:
default:
{
dapl_os_assert(0);
break;
}
}
dapl_dbg_log(DAPL_DBG_TYPE_CM | DAPL_DBG_TYPE_CALLBACK,
"dapl_evd_connection_callback () returns\n");
}