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

📄 callmgr.c

📁 驱动开发,经过测试可以直接编译后使用,编译使用DDK中的build工具
💻 C
📖 第 1 页 / 共 3 页
字号:
    OUT PNDIS_HANDLE            ProtocolVcContext
    )
/*++

Routine Description:

    Entry point called by NDIS when the Call Manager wants to create
    a new endpoint (VC). We allocate a new VC structure, and return 
    a pointer to it as our VC context.

Arguments:

    ProtocolAfContext   - Actually a pointer to the ATMSM adapter structure
    NdisVcHandle        - Handle for this VC for all future references
    ProtocolVcContext  - Place where we (protocol) return our context for the VC

Return Value:

    NDIS_STATUS_SUCCESS if we could create a VC
    NDIS_STATUS_RESOURCES otherwise
--*/
{
    PATMSM_ADAPTER  pAdapt = (PATMSM_ADAPTER)ProtocolAfContext;
    PATMSM_VC       pVc;
    NDIS_STATUS     Status;

    DbgInfo(("CreateVc: NdisVcHandle %x, Adapt - %x\n", NdisVcHandle, pAdapt));

    *ProtocolVcContext  = NULL;


    Status = AtmSmAllocVc(pAdapt, &pVc, VC_TYPE_INCOMING, NdisVcHandle);

    if(NDIS_STATUS_SUCCESS == Status){

        *ProtocolVcContext  = pVc;
    }

    return Status;
}


NDIS_STATUS
AtmSmDeleteVc(
    IN  NDIS_HANDLE                 ProtocolVcContext
    )
/*++

Routine Description:

    Our Delete VC handler. This VC would have been allocated as a result
    of a previous entry into our CreateVcHandler, and possibly used for
    an incoming call.

    We dereference the VC here.

Arguments:

    ProtocolVcContext   - pointer to our VC structure

Return Value:

    NDIS_STATUS_SUCCESS always

--*/
{
    PATMSM_VC  pVc = (PATMSM_VC)ProtocolVcContext;

    DbgInfo(("DeleteVc: For Vc %lx\n", pVc));

    pVc->NdisVcHandle = NULL;
    AtmSmDereferenceVc(pVc);

    return NDIS_STATUS_SUCCESS;
}


NDIS_STATUS
AtmSmIncomingCall(
    IN  NDIS_HANDLE             ProtocolSapContext,
    IN  NDIS_HANDLE             ProtocolVcContext,
    IN OUT PCO_CALL_PARAMETERS  CallParameters
    )
/*++

Routine Description:

    Handler for incoming call. We accept the call unless we are shutting down 
    and then do the actual processing when the call processing completes.

Arguments:

    ProtocolSapContext      Pointer to the pAdapt
    ProtocolVcContext       Pointer to the Vc
    CallParameters          Call Parameters

Return Value:


--*/
{
    PATMSM_ADAPTER              pAdapt = (PATMSM_ADAPTER)ProtocolSapContext;
    PATMSM_VC                   pVc    = (PATMSM_VC)ProtocolVcContext;
    Q2931_CALLMGR_PARAMETERS UNALIGNED * CallMgrSpecific;

    ASSERT (pVc->pAdapt == pAdapt);

    DbgInfo(("AtmSmIncomingCall: On Vc %lx\n", pVc));

    //
    // Mark the Vc to indicate the call processing is underway
    //
    ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);

    ASSERT ((pVc->ulFlags & (ATMSM_VC_ACTIVE | ATMSM_VC_CALLPROCESSING)) == 0);

    ATMSM_SET_VC_STATE(pVc, ATMSM_VC_CALLPROCESSING);

    RELEASE_ADAPTER_GEN_LOCK(pAdapt);

    //
    // Get the remote atm address from the call-parameters
    //
    CallMgrSpecific = (PQ2931_CALLMGR_PARAMETERS)&CallParameters->
                            CallMgrParameters->CallMgrSpecific.Parameters[0];

    pVc->HwAddr.Address = CallMgrSpecific->CallingParty;

    //
    // Get the max size of packets we can send on this VC, from the
    // AAL5 parameters. Limit it to the size our miniport can support.
    //
    pVc->MaxSendSize = pAdapt->MaxPacketSize; // default

    if (CallMgrSpecific->InfoElementCount > 0) {

        Q2931_IE UNALIGNED *            pIe;
        AAL5_PARAMETERS UNALIGNED *     pAal5;
        ULONG                           IeCount;

        pIe = (PQ2931_IE)CallMgrSpecific->InfoElements;
        for (IeCount = CallMgrSpecific->InfoElementCount;
             IeCount >= 0;
             IeCount--) {

            if (pIe->IEType == IE_AALParameters) {

                pAal5 = &(((PAAL_PARAMETERS_IE)pIe->IE)->
                                    AALSpecificParameters.AAL5Parameters);
                //
                // Make sure we don't send more than what the caller can handle.
                //
                if (pAal5->ForwardMaxCPCSSDUSize < pVc->MaxSendSize) {

                    pVc->MaxSendSize = pAal5->ForwardMaxCPCSSDUSize;
                }

                //
                // Make sure the caller doesn't send more than what our
                // miniport can handle.
                //
                if (pAal5->BackwardMaxCPCSSDUSize > pAdapt->MaxPacketSize) {

                    pAal5->BackwardMaxCPCSSDUSize = pAdapt->MaxPacketSize;
                }
                break;
            }
            pIe = (PQ2931_IE)((PUCHAR)pIe + pIe->IELength);
        }
    }


    return NDIS_STATUS_SUCCESS;
}


VOID
AtmSmCallConnected(
    IN  NDIS_HANDLE             ProtocolVcContext
    )
/*++

Routine Description:

    Last hand-shake in the incoming call path. Move the Vc to the list of 
    active calls.

Arguments:

    ProtocolVcContext   Pointer to VC

Return Value:

    None.

--*/
{
    PATMSM_VC       pVc     = (PATMSM_VC)ProtocolVcContext;
    PATMSM_ADAPTER  pAdapt  = pVc->pAdapt;

    DbgInfo(("AtmSmCallConnected: On pVc %x  pAdapt %x\n", pVc, pAdapt));

    pAdapt = pVc->pAdapt;

    // now we add a reference to the VC
    AtmSmReferenceVc(pVc);

    ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);

    ASSERT(ATMSM_GET_VC_STATE(pVc) != ATMSM_VC_ACTIVE);

    ASSERT(ATMSM_GET_VC_STATE(pVc) == ATMSM_VC_CALLPROCESSING);

    ATMSM_SET_VC_STATE(pVc, ATMSM_VC_ACTIVE);

    // remove the Vc from the inactive list
    RemoveEntryList(&pVc->List);

    // insert the vc into the active list
    InsertHeadList(&pAdapt->ActiveVcHead, &pVc->List);

    RELEASE_ADAPTER_GEN_LOCK(pAdapt);

}


VOID
AtmSmMakeCallComplete(
    IN  NDIS_STATUS             Status,
    IN  NDIS_HANDLE             ProtocolVcContext,
    IN  NDIS_HANDLE             NdisPartyHandle     OPTIONAL,
    IN  PCO_CALL_PARAMETERS     CallParameters
    )
/*++

Routine Description:

    Handle completion of an earlier call to NdisClMakeCall. If the call has
    succeeded and if this is a point to multipoint call, initiate Addparty on 
    the rest of the addresses. If it is not multipoint, then send any packets
    pending on the call.

Arguments:

    Status              Result of NdisClMakeCall
    ProtocolVcContext   Pointer to P-P or PMP Vc
    NdisPartyHandle     If successful, the handle for this party
    CallParameters      Pointer to Call parameters

Return Value:

    None.

--*/
{
    PATMSM_VC           pVc     = (PATMSM_VC)ProtocolVcContext;
    PATMSM_ADAPTER      pAdapt  = (PATMSM_ADAPTER)pVc->pAdapt;
    PATMSM_PMP_MEMBER   pMember;
    BOOLEAN             bLockReleased = FALSE;


    DbgInfo(("MakeCallComplete: Status %x, pVc %x, VC flag %x\n",
                        Status, pVc, pVc->ulFlags));

    // Free the call parameters
    AtmSmFreeMem(CallParameters);

    //
    // If this is a point to point connection and we succeeded in connecting
    // then send the packets pending on the VC.
    //
    if(VC_TYPE_PMP_OUTGOING != pVc->VcType){

        PIRP pIrp;


        if(NDIS_STATUS_SUCCESS == Status){
            // successfully connected the P-P call, send any pending packets

            ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);

            ATMSM_SET_VC_STATE(pVc, ATMSM_VC_ACTIVE);

            DbgInfo(("PP VC 0x%x successfully connected to destination\n", 
                                                                         pVc));

            // now complete IRP that started this connect call
            pIrp = pVc->pConnectIrp;
            pVc->pConnectIrp = NULL;

            ASSERT(pIrp);

            // remove the Vc from the inactive list
            RemoveEntryList(&pVc->List);

            // insert the vc into the active list
            InsertHeadList(&pAdapt->ActiveVcHead, &pVc->List);

            RELEASE_ADAPTER_GEN_LOCK(pAdapt);

            if(pIrp){

                pIrp->IoStatus.Status = STATUS_SUCCESS;

                // now set the connect context
                *(PHANDLE)(pIrp->AssociatedIrp.SystemBuffer) = (HANDLE)pVc;
                pIrp->IoStatus.Information = sizeof(HANDLE);

                IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
            }

            AtmSmSendQueuedPacketsOnVc(pVc);

        } else {

            // failed to connect the call.  

            // now complete IRP that started this connect call
            PIRP pIrp = pVc->pConnectIrp;
            pVc->pConnectIrp = NULL;

            ASSERT(pIrp);

            if(pIrp){

                pIrp->IoStatus.Status = Status;

                pIrp->IoStatus.Information = 0;

                IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
            }

            DbgInfo(("PP VC 0x%x failed to connect to destination - Status - "
                "0x%x\n", pVc, Status));

            // Cleanup the VC - remove the reference added at create
            AtmSmDereferenceVc(pVc);
        }

        return;
    }


    //
    // This is the completion of the first Make call on a PMP.  If the first
    // has succeeded, we add the rest. If the first one failed, we remove it 
    // and try to make a call on another one.
    //

    ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);

    //
    // Get the member we were trying to connect to.
    //
    for (pMember = pVc->pPMPMembers; pMember; pMember = pMember->pNext)
        if(ATMSM_GET_MEMBER_STATE(pMember) == ATMSM_MEMBER_CONNECTING)
            break;

    ASSERT(NULL != pMember);

    pVc->ulNumConnectingMembers--;

    if (NDIS_STATUS_SUCCESS == Status){

        ASSERT(NULL != NdisPartyHandle);

        ATMSM_SET_MEMBER_STATE(pMember, ATMSM_MEMBER_CONNECTED);

        pMember->NdisPartyHandle = NdisPartyHandle;

        pVc->ulNumActiveMembers++;

        //
        // check if the member was invalidated during the call setup
        // if so, remove this guy
        //
        if(ATMSM_IS_MEMBER_INVALID(pMember)){

            RELEASE_ADAPTER_GEN_LOCK(pAdapt);
            bLockReleased = TRUE;

            // This member was invalidated, now drop him off
            AtmSmDropMemberFromVc(pVc, pMember); 
        }
    }
    else
    {
        DbgWarn(("MakeCall error %x, pMember %x to addr:", Status, pMember));

        DumpATMAddress(ATMSMD_ERR, "", &pMember->HwAddr.Address);

        RELEASE_ADAPTER_GEN_LOCK(pAdapt);
        bLockReleased = TRUE;

        //
        // Connection failed. Delete this member from our list of members.
        //
        DeleteMemberInfoFromVc(pVc, pMember);
    }

    if(!bLockReleased) {
    
        RELEASE_ADAPTER_GEN_LOCK(pAdapt);
    }

    //
    // Add anymore members remaining

⌨️ 快捷键说明

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