📄 callmgr.c
字号:
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 + -