/** @brief This function is used by the DAL Core to initialize the Control Transport for processing. It must be called prior to calling any other APIs of the Control Transport. @param szName: unique name for the channel that is to be opened uSize: size of the channel that must be opened (should fit the largest size of packet that the Dal Core wishes to send) wctsCBs: a list of callbacks that the CT needs to use to send notification and messages back to DAL @see @return A handle that must be used for further communication with the CTS. This is an opaque structure for the caller and it will be used in all communications to and from the CTS. */ WCTS_HandleType WCTS_OpenTransport ( const wpt_uint8* szName, wpt_uint32 uSize, WCTS_TransportCBsType* wctsCBs ) { WCTS_ControlBlockType* pWCTSCb; wpt_status status; int smdstatus; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /*--------------------------------------------------------------------- Sanity check ---------------------------------------------------------------------*/ if ((NULL == wctsCBs) || (NULL == szName) || (NULL == wctsCBs->wctsNotifyCB) || (NULL == wctsCBs->wctsRxMsgCB)) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "WCTS_OpenTransport: Invalid parameters received."); return NULL; } /* This open is coming after a SSR, we don't need to reopen SMD, * the SMD port was never closed during SSR*/ if (gwctsHandle) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, "WCTS_OpenTransport port is already open\n"); pWCTSCb = gwctsHandle; if (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, "WCTS_OpenTransport: Invalid magic."); return NULL; } pWCTSCb->wctsState = WCTS_STATE_OPEN; pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb, WCTS_EVENT_OPEN, pWCTSCb->wctsNotifyCBData); /* we initially don't want read interrupts (we only want them if we get into deferred write mode) */ smd_disable_read_intr(pWCTSCb->wctsChannel); return (WCTS_HandleType)pWCTSCb; } #ifdef FEATURE_R33D if(port_open) { /* Port open before, not need to open again */ /* notified registered client that the channel is open */ ctsCB->wctsState = WCTS_STATE_OPEN; ctsCB->wctsNotifyCB((WCTS_HandleType)ctsCB, WCTS_EVENT_OPEN, ctsCB->wctsNotifyCBData); return (WCTS_HandleType)ctsCB; } #endif /* FEATURE_R33D */ /* allocate a ControlBlock to hold all context */ pWCTSCb = wpalMemoryAllocate(sizeof(*pWCTSCb)); if (NULL == pWCTSCb) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "WCTS_OpenTransport: Memory allocation failure."); return NULL; } /* make sure the control block is initialized. in particular we need to make sure the embedded event and list structures are initialized to prevent "magic number" tests from being run against uninitialized values */ wpalMemoryZero(pWCTSCb, sizeof(*pWCTSCb)); #ifdef FEATURE_R33D smd_init(0); port_open = 1; ctsCB = pWCTSCb; #endif /* FEATURE_R33D */ /*Initialise the event*/ wpalEventInit(&pWCTSCb->wctsEvent); /* save the user-supplied information */ pWCTSCb->wctsNotifyCB = wctsCBs->wctsNotifyCB; pWCTSCb->wctsNotifyCBData = wctsCBs->wctsNotifyCBData; pWCTSCb->wctsRxMsgCB = wctsCBs->wctsRxMsgCB; pWCTSCb->wctsRxMsgCBData = wctsCBs->wctsRxMsgCBData; /* initialize the remaining fields */ wpal_list_init(&pWCTSCb->wctsPendingQueue); pWCTSCb->wctsMagic = WCTS_CB_MAGIC; pWCTSCb->wctsState = WCTS_STATE_OPEN_PENDING; pWCTSCb->wctsChannel = NULL; /* since SMD will callback in interrupt context, we will used * canned messages to serialize the SMD events into a thread * context */ pWCTSCb->wctsOpenMsg.callback = WCTS_PALOpenCallback; pWCTSCb->wctsOpenMsg.pContext = pWCTSCb; pWCTSCb->wctsDataMsg.callback = WCTS_PALDataCallback; pWCTSCb->wctsDataMsg.pContext = pWCTSCb; /*--------------------------------------------------------------------- Open the SMD channel ---------------------------------------------------------------------*/ wpalEventReset(&pWCTSCb->wctsEvent); smdstatus = smd_named_open_on_edge(szName, SMD_APPS_WCNSS, &pWCTSCb->wctsChannel, pWCTSCb, WCTS_NotifyCallback); if (0 != smdstatus) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: smd_named_open_on_edge failed with status %d", __func__, smdstatus); goto fail; } /* wait for the channel to be fully opened before we proceed */ status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_OPEN_TIMEOUT); if (eWLAN_PAL_STATUS_SUCCESS != status) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: failed to receive SMD_EVENT_OPEN", __func__); /* since we opened one end of the channel, close it */ smdstatus = smd_close(pWCTSCb->wctsChannel); if (0 != smdstatus) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: smd_close failed with status %d", __func__, smdstatus); } goto fail; } /* we initially don't want read interrupts (we only want them if we get into deferred write mode) */ smd_disable_read_intr(pWCTSCb->wctsChannel); /* we have successfully opened the SMD channel */ gwctsHandle = pWCTSCb; return (WCTS_HandleType)pWCTSCb; fail: /* we were unable to open the SMD channel */ pWCTSCb->wctsMagic = 0; wpalMemoryFree(pWCTSCb); return NULL; }/*WCTS_OpenTransport*/
WCTS_HandleType WCTS_OpenTransport ( const wpt_uint8* szName, wpt_uint32 uSize, WCTS_TransportCBsType* wctsCBs ) { WCTS_ControlBlockType* pWCTSCb; wpt_status status; int smdstatus; if ((NULL == wctsCBs) || (NULL == szName) || (NULL == wctsCBs->wctsNotifyCB) || (NULL == wctsCBs->wctsRxMsgCB)) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "WCTS_OpenTransport: Invalid parameters received."); return NULL; } if (gwctsHandle) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, "WCTS_OpenTransport port is already open"); pWCTSCb = gwctsHandle; if (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, "WCTS_OpenTransport: Invalid magic."); return NULL; } pWCTSCb->wctsState = WCTS_STATE_OPEN; pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb, WCTS_EVENT_OPEN, pWCTSCb->wctsNotifyCBData); smd_disable_read_intr(pWCTSCb->wctsChannel); return (WCTS_HandleType)pWCTSCb; } #ifdef FEATURE_R33D if(port_open) { ctsCB->wctsState = WCTS_STATE_OPEN; ctsCB->wctsNotifyCB((WCTS_HandleType)ctsCB, WCTS_EVENT_OPEN, ctsCB->wctsNotifyCBData); return (WCTS_HandleType)ctsCB; } #endif pWCTSCb = wpalMemoryAllocate(sizeof(*pWCTSCb)); if (NULL == pWCTSCb) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "WCTS_OpenTransport: Memory allocation failure."); return NULL; } wpalMemoryZero(pWCTSCb, sizeof(*pWCTSCb)); #ifdef FEATURE_R33D smd_init(0); port_open = 1; ctsCB = pWCTSCb; #endif wpalEventInit(&pWCTSCb->wctsEvent); pWCTSCb->wctsNotifyCB = wctsCBs->wctsNotifyCB; pWCTSCb->wctsNotifyCBData = wctsCBs->wctsNotifyCBData; pWCTSCb->wctsRxMsgCB = wctsCBs->wctsRxMsgCB; pWCTSCb->wctsRxMsgCBData = wctsCBs->wctsRxMsgCBData; wpal_list_init(&pWCTSCb->wctsPendingQueue); pWCTSCb->wctsMagic = WCTS_CB_MAGIC; pWCTSCb->wctsState = WCTS_STATE_OPEN_PENDING; pWCTSCb->wctsChannel = NULL; pWCTSCb->wctsOpenMsg.callback = WCTS_PALOpenCallback; pWCTSCb->wctsOpenMsg.pContext = pWCTSCb; pWCTSCb->wctsOpenMsg.type= WPAL_MC_MSG_SMD_NOTIF_OPEN_SIG; pWCTSCb->wctsDataMsg.callback = WCTS_PALDataCallback; pWCTSCb->wctsDataMsg.pContext = pWCTSCb; pWCTSCb-> wctsDataMsg.type= WPAL_MC_MSG_SMD_NOTIF_DATA_SIG; wpalEventReset(&pWCTSCb->wctsEvent); smdstatus = smd_named_open_on_edge(szName, SMD_APPS_WCNSS, &pWCTSCb->wctsChannel, pWCTSCb, WCTS_NotifyCallback); if (0 != smdstatus) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: smd_named_open_on_edge failed with status %d", __func__, smdstatus); goto fail; } status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_OPEN_TIMEOUT); if (eWLAN_PAL_STATUS_SUCCESS != status) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: failed to receive SMD_EVENT_OPEN", __func__); smdstatus = smd_close(pWCTSCb->wctsChannel); if (0 != smdstatus) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: smd_close failed with status %d", __func__, smdstatus); } goto fail; } smd_disable_read_intr(pWCTSCb->wctsChannel); gwctsHandle = pWCTSCb; return (WCTS_HandleType)pWCTSCb; fail: pWCTSCb->wctsMagic = 0; wpalMemoryFree(pWCTSCb); return NULL; }