Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1625 lines
45 KiB

#include "precomp.h"
DEBUG_FILEZONE(ZONE_T120_SAP);
#include "appsap.h"
#include "conf.h"
#include "gcontrol.h"
void CALLBACK MCS_SapCallback(UINT, LPARAM, LPVOID);
void CALLBACK GCC_SapCallback(GCCAppSapMsg *);
T120Error WINAPI T120_CreateAppletSAP
(
IT120Applet **ppApplet
)
{
if (NULL != ppApplet)
{
*ppApplet = NULL;
if (NULL != g_pGCCController)
{
T120Error rc;
DBG_SAVE_FILE_LINE
CApplet *pApplet = new CApplet(&rc);
if (NULL != pApplet)
{
if (T120_NO_ERROR == rc)
{
*ppApplet = (IT120Applet *) pApplet;
return T120_NO_ERROR;
}
ERROR_OUT(("T120_CreateAppletSAP: CApplet failed, rc=%u", rc));
pApplet->Release();
return rc;
}
ERROR_OUT(("T120_CreateAppletSAP: cannot create CApplet"));
return T120_ALLOCATION_FAILURE;
}
WARNING_OUT(("T120_CreateAppletSAP: GCC Provider is not initialized."));
return T120_NOT_INITIALIZED;
}
ERROR_OUT(("T120_CreateAppletSAP: callback pfn null"));
return T120_INVALID_PARAMETER;
}
/* ------ interface methods for applet session ------ */
CAppletSession::CAppletSession
(
CApplet *pApplet,
T120ConfID nConfID
)
:
CRefCount(MAKE_STAMP_ID('A','p','p','S')),
m_pApplet(pApplet),
m_pAppletContext(NULL),
m_pSessionContext(NULL),
m_pfnCallback(NULL),
m_pMCSAppletSAP(NULL),
m_nConfID(nConfID),
m_uidMyself(0),
m_sidMyself(0),
m_eidMyself(0),
m_nidMyself(0),
m_eState(APPSESS_INITIALIZED),
m_nArrayIndex(0),
m_eErrorType(NONE_CHOSEN),
m_eDynamicChannelJoinState(DCJS_INITIALIZED),
m_fMCSFreeDataIndBuffer(0),
m_fFirstRoster(FALSE),
m_pTempMsg(NULL)
{
ASSERT(0 != m_nConfID);
::ZeroMemory(&m_JoinRequest, sizeof(m_JoinRequest));
m_pApplet->RegisterSession(this);
}
CAppletSession::~CAppletSession(void)
{
m_pApplet->UnregisterSession(this);
FreeJoinRequest(FALSE);
ASSERT(NULL == m_pfnCallback);
ASSERT(NULL == m_pAppletContext);
ASSERT(NULL == m_pSessionContext);
}
void CAppletSession::FreeJoinRequest(BOOL fZeroOut)
{
delete [] m_JoinRequest.aResourceReqs;
if (fZeroOut)
{
::ZeroMemory(&m_JoinRequest, sizeof(m_JoinRequest));
}
}
void CAppletSession::ReleaseInterface(void)
{
ASSERT(NULL != g_pGCCController);
Leave();
m_pfnCallback = NULL;
m_pAppletContext = NULL;
m_pSessionContext = NULL;
Release();
}
void CAppletSession::Advise
(
LPFN_APPLET_SESSION_CB pfnCallback,
LPVOID pAppletContext,
LPVOID pSessionContext
)
{
m_pfnCallback = pfnCallback;
m_pAppletContext = pAppletContext;
m_pSessionContext = pSessionContext;
}
void CAppletSession::Unadvise(void)
{
m_pfnCallback = NULL;
m_pAppletContext = NULL;
m_pSessionContext = NULL;
}
BOOL CAppletSession::IsThisNodeTopProvider(void)
{
return m_pApplet->GetAppSap()->IsThisNodeTopProvider(m_nConfID);
}
T120NodeID CAppletSession::GetTopProvider(void)
{
return m_pApplet->GetAppSap()->GetTopProvider(m_nConfID);
}
T120Error CAppletSession::Join
(
T120JoinSessionRequest *pReq
)
{
ASSERT(0 != m_nConfID);
if (NULL != g_pGCCController->GetConfObject(m_nConfID))
{
T120Error rc = T120_NO_ERROR;
// remember the join request, shallow structure copy
m_JoinRequest = *pReq;
// we need to duplicate the resource requests because we put the results in place.
// we have to do this in order to support multiple conferences simultaneously
if (NULL != pReq->aResourceReqs && 0 != pReq->cResourceReqs)
{
DBG_SAVE_FILE_LINE
m_JoinRequest.aResourceReqs = new T120ResourceRequest[m_JoinRequest.cResourceReqs];
if (NULL != m_JoinRequest.aResourceReqs)
{
::CopyMemory(m_JoinRequest.aResourceReqs, pReq->aResourceReqs,
sizeof(T120ResourceRequest) * m_JoinRequest.cResourceReqs);
}
else
{
ERROR_OUT(("CAppletSession::Join: can't create resource requests"));
rc = T120_ALLOCATION_FAILURE;
}
}
// attach user now
if (T120_NO_ERROR == rc)
{
m_fFirstRoster = FALSE;
m_fMCSFreeDataIndBuffer = (pReq->dwAttachmentFlags & ATTACHMENT_MCS_FREES_DATA_IND_BUFFER);
SetState(APPSESS_ATTACH_USER_REQ);
rc = ::MCS_AttachRequest(&m_pMCSAppletSAP,
(LPBYTE) &m_nConfID, sizeof(m_nConfID),
MCS_SapCallback,
this,
pReq->dwAttachmentFlags);
ASSERT(T120_NO_ERROR == rc);
}
if (T120_NO_ERROR == rc)
{
return T120_NO_ERROR;
}
FreeJoinRequest(TRUE);
return rc;
}
return GCC_INVALID_CONFERENCE;
}
void CAppletSession::Leave(void)
{
if (APPSESS_LEAVING != m_eState && APPSESS_LEFT != m_eState)
{
APPLET_SESSION_STATE eOldState = m_eState;
m_eState = APPSESS_LEAVING;
switch (eOldState)
{
case APPSESS_INACTIVELY_ENROLL_REQ:
case APPSESS_INACTIVELY_ENROLL_CON:
case APPSESS_RESOURCE_REQ:
case APPSESS_RESOURCE_CON:
case APPSESS_ACTIVELY_ENROLL_REQ:
case APPSESS_ACTIVELY_ENROLL_CON:
case APPSESS_JOINED:
default:
// un-enroll
DoEnroll(FALSE);
// fall through
case APPSESS_ATTACH_USER_REQ:
case APPSESS_ATTACH_USER_CON:
case APPSESS_JOIN_MY_CHANNEL_REQ:
case APPSESS_JOIN_MY_CHANNEL_CON:
case APPSESS_JOIN_STATIC_CHANNEL_REQ:
case APPSESS_JOIN_STATIC_CHANNEL_CON:
if (NULL != m_pMCSAppletSAP)
{
m_pMCSAppletSAP->ReleaseInterface();
m_pMCSAppletSAP = NULL;
}
// fall through
case APPSESS_INITIALIZED:
m_fMCSFreeDataIndBuffer = 0;
break;
}
m_eState = APPSESS_LEFT;
m_fFirstRoster = FALSE;
}
FreeJoinRequest(TRUE);
}
T120Error CAppletSession::AllocateSendDataBuffer
(
ULONG cbBufSize,
void **ppBuf
)
{
if (NULL != m_pMCSAppletSAP)
{
return m_pMCSAppletSAP->GetBuffer(cbBufSize, ppBuf);
}
return T120_NOT_INITIALIZED;
}
void CAppletSession::FreeSendDataBuffer
(
void *pBuf
)
{
if (NULL != m_pMCSAppletSAP && (! m_fMCSFreeDataIndBuffer))
{
m_pMCSAppletSAP->FreeBuffer(pBuf);
}
else
{
ASSERT(0);
}
}
T120Error CAppletSession::SendData
(
DataRequestType eReqType,
T120ChannelID nChannelID,
T120Priority ePriority,
LPBYTE pbBuf,
ULONG cbBufSize,
SendDataFlags eBufSource
)
{
if (NULL != m_pMCSAppletSAP)
{
return m_pMCSAppletSAP->SendData(eReqType,
nChannelID,
(Priority) ePriority,
pbBuf,
cbBufSize,
eBufSource);
}
return T120_NOT_INITIALIZED;
}
T120Error CAppletSession::InvokeApplet
(
GCCAppProtEntityList *pApeList,
GCCSimpleNodeList *pNodeList,
T120RequestTag *pnReqTag
)
{
return m_pApplet->GetAppSap()->AppInvoke(m_nConfID, pApeList, pNodeList, pnReqTag);
}
T120Error CAppletSession::InquireRoster
(
GCCSessionKey *pSessionKey
)
{
return m_pApplet->GetAppSap()->AppRosterInquire(m_nConfID, pSessionKey, NULL);
}
T120Error CAppletSession::RegistryRequest
(
T120RegistryRequest *pReq
)
{
T120Error rc;
if (NULL != pReq)
{
IGCCAppSap *pAppSap = m_pApplet->GetAppSap();
ASSERT(NULL != pAppSap);
GCCRegistryKey *pKey = pReq->pRegistryKey;
switch (pReq->eCommand)
{
case APPLET_REGISTER_CHANNEL:
rc = pAppSap->RegisterChannel(m_nConfID, pKey, pReq->nChannelID);
break;
case APPLET_ASSIGN_TOKEN:
rc = pAppSap->RegistryAssignToken(m_nConfID, pKey);
break;
case APPLET_SET_PARAMETER:
rc = pAppSap->RegistrySetParameter(m_nConfID, pKey,
pReq->Param.postrValue, pReq->Param.eModifyRights);
break;
case APPLET_RETRIEVE_ENTRY:
rc = pAppSap->RegistryRetrieveEntry(m_nConfID, pKey);
break;
case APPLET_DELETE_ENTRY:
rc = pAppSap->RegistryDeleteEntry(m_nConfID, pKey);
break;
case APPLET_ALLOCATE_HANDLE:
rc = pAppSap->RegistryAllocateHandle(m_nConfID, pReq->cHandles);
break;
case APPLET_MONITOR:
rc = pAppSap->RegistryMonitor(m_nConfID, pReq->fEnableDelivery, pKey);
break;
default:
ERROR_OUT(("CAppletSession::RegistryRequest: invalid command=%u", (UINT) pReq->eCommand));
rc = T120_INVALID_PARAMETER;
break;
}
}
else
{
rc = T120_INVALID_PARAMETER;
}
return rc;
}
T120Error CAppletSession::ChannelRequest
(
T120ChannelRequest *pReq
)
{
T120Error rc;
if (NULL != pReq)
{
T120ChannelID chid = pReq->nChannelID;
switch (pReq->eCommand)
{
case APPLET_JOIN_CHANNEL:
rc = m_pMCSAppletSAP->ChannelJoin(chid);
break;
case APPLET_LEAVE_CHANNEL:
rc = m_pMCSAppletSAP->ChannelLeave(chid);
break;
case APPLET_CONVENE_CHANNEL:
rc = m_pMCSAppletSAP->ChannelConvene();
break;
case APPLET_DISBAND_CHANNEL:
rc = m_pMCSAppletSAP->ChannelDisband(chid);
break;
case APPLET_ADMIT_CHANNEL:
rc = m_pMCSAppletSAP->ChannelAdmit(chid, pReq->aUsers, pReq->cUsers);
break;
default:
ERROR_OUT(("CAppletSession::ChannelRequest: invalid command=%u", (UINT) pReq->eCommand));
rc = T120_INVALID_PARAMETER;
break;
}
}
else
{
rc = T120_INVALID_PARAMETER;
}
return rc;
}
T120Error CAppletSession::TokenRequest
(
T120TokenRequest *pReq
)
{
//T120TokenID nTokenID;
//T120UserID uidGiveTo;
T120Error rc;
if (NULL != pReq)
{
T120TokenID tid = pReq->nTokenID;
switch (pReq->eCommand)
{
case APPLET_GRAB_TOKEN:
rc = m_pMCSAppletSAP->TokenGrab(tid);
break;
case APPLET_INHIBIT_TOKEN:
rc = m_pMCSAppletSAP->TokenInhibit(tid);
break;
case APPLET_GIVE_TOKEN:
rc = m_pMCSAppletSAP->TokenGive(tid, pReq->uidGiveTo);
break;
case APPLET_GIVE_TOKEN_RESPONSE:
rc = m_pMCSAppletSAP->TokenGiveResponse(tid, pReq->eGiveResponse);
break;
case APPLET_PLEASE_TOKEN:
rc = m_pMCSAppletSAP->TokenPlease(tid);
break;
case APPLET_RELEASE_TOKEN:
rc = m_pMCSAppletSAP->TokenRelease(tid);
break;
case APPLET_TEST_TOKEN:
rc = m_pMCSAppletSAP->TokenTest(tid);
break;
default:
ERROR_OUT(("CAppletSession::TokenRequest: invalid command=%u", (UINT) pReq->eCommand));
rc = T120_INVALID_PARAMETER;
break;
}
}
else
{
rc = T120_INVALID_PARAMETER;
}
return rc;
}
/* ------ private methods ------ */
void CAppletSession::SendCallbackMessage
(
T120AppletSessionMsg *pMsg
)
{
ASSERT(NULL != pMsg);
if (NULL != m_pfnCallback)
{
pMsg->pAppletContext = m_pAppletContext;
pMsg->pSessionContext = m_pSessionContext;
(*m_pfnCallback)(pMsg);
}
}
void CAppletSession::SendMCSMessage
(
T120AppletSessionMsg *pMsg
)
{
ASSERT(NULL != pMsg);
if (NULL != m_pfnCallback)
{
pMsg->nConfID = m_nConfID;
pMsg->pAppletContext = m_pAppletContext;
pMsg->pSessionContext = m_pSessionContext;
(*m_pfnCallback)(pMsg);
}
else
{
if (pMsg->eMsgType == MCS_UNIFORM_SEND_DATA_INDICATION ||
pMsg->eMsgType == MCS_SEND_DATA_INDICATION)
{
if (! m_fMCSFreeDataIndBuffer)
{
WARNING_OUT(("CAppletSession::SendMCSMessage: send data ind, free ptr=0x%x, len=%d", pMsg->SendDataInd.user_data.value, pMsg->SendDataInd.user_data.length));
FreeSendDataBuffer(pMsg->SendDataInd.user_data.value);
}
}
}
}
void CAppletSession::MCSCallback
(
T120AppletSessionMsg *pMsg
)
{
// dispatch the message depeneding on whether we are still in the join process or not
if (IsJoining())
{
SetTempMsg(pMsg);
switch (pMsg->eMsgType)
{
case MCS_ATTACH_USER_CONFIRM:
HandleAttachUserConfirm();
break;
case MCS_CHANNEL_JOIN_CONFIRM:
HandleJoinChannelConfirm();
break;
case MCS_TOKEN_GRAB_CONFIRM:
HandleTokenGrabConfirm();
break;
}
}
else
{
SendMCSMessage(pMsg);
}
}
void CAppletSession::GCCCallback
(
T120AppletSessionMsg *pMsg
)
{
if (IsJoining())
{
// remember the current GCC applet SAP message
SetTempMsg(pMsg);
switch (pMsg->eMsgType)
{
case GCC_ENROLL_CONFIRM:
HandleEnrollConfirm();
break;
case GCC_APP_ROSTER_REPORT_INDICATION:
if (! m_fFirstRoster)
{
if (APPSESS_INACTIVELY_ENROLL_CON == m_eState)
{
DoResourceRequests();
}
m_fFirstRoster = TRUE;
}
break;
case GCC_REGISTER_CHANNEL_CONFIRM:
HandleRegisterChannelConfirm();
break;
case GCC_RETRIEVE_ENTRY_CONFIRM:
HandleRetrieveEntryConfirm();
break;
}
}
else
{
SendCallbackMessage(pMsg);
}
}
void CAppletSession::SetState(APPLET_SESSION_STATE eNewState)
{
#ifdef _DEBUG
if (APPSESS_LEAVING != eNewState)
{
switch (m_eState)
{
case APPSESS_INITIALIZED:
ASSERT(APPSESS_ATTACH_USER_REQ == eNewState);
break;
// attach user
case APPSESS_ATTACH_USER_REQ:
ASSERT(APPSESS_ATTACH_USER_CON == eNewState);
break;
case APPSESS_ATTACH_USER_CON:
ASSERT(APPSESS_JOIN_MY_CHANNEL_REQ == eNewState);
break;
// join my channel
case APPSESS_JOIN_MY_CHANNEL_REQ:
ASSERT(APPSESS_JOIN_MY_CHANNEL_CON == eNewState);
break;
case APPSESS_JOIN_MY_CHANNEL_CON:
ASSERT(APPSESS_JOIN_STATIC_CHANNEL_REQ == eNewState ||
APPSESS_INACTIVELY_ENROLL_REQ == eNewState ||
APPSESS_ACTIVELY_ENROLL_REQ == eNewState);
break;
// join static channels
case APPSESS_JOIN_STATIC_CHANNEL_REQ:
ASSERT(APPSESS_JOIN_STATIC_CHANNEL_CON == eNewState);
break;
case APPSESS_JOIN_STATIC_CHANNEL_CON:
ASSERT(APPSESS_JOIN_STATIC_CHANNEL_REQ == eNewState ||
APPSESS_INACTIVELY_ENROLL_REQ == eNewState ||
APPSESS_ACTIVELY_ENROLL_REQ == eNewState);
break;
// enroll applet in order to do resource requests
case APPSESS_INACTIVELY_ENROLL_REQ:
ASSERT(APPSESS_INACTIVELY_ENROLL_CON == eNewState);
break;
case APPSESS_INACTIVELY_ENROLL_CON:
ASSERT(APPSESS_RESOURCE_REQ == eNewState);
break;
// do resource requests
case APPSESS_RESOURCE_REQ:
ASSERT(APPSESS_RESOURCE_CON == eNewState ||
APPSESS_ACTIVELY_ENROLL_REQ == eNewState);
break;
case APPSESS_RESOURCE_CON:
ASSERT(APPSESS_RESOURCE_REQ == eNewState);
break;
// enroll applet in order to do resource requests
case APPSESS_ACTIVELY_ENROLL_REQ:
ASSERT(APPSESS_ACTIVELY_ENROLL_CON == eNewState);
break;
case APPSESS_ACTIVELY_ENROLL_CON:
ASSERT(APPSESS_JOINED == eNewState);
break;
// done with the join process
case APPSESS_JOINED:
ASSERT(APPSESS_LEAVING == eNewState);
break;
case APPSESS_LEAVING:
ASSERT(APPSESS_LEFT == eNewState);
break;
default:
ASSERT(0);
break;
} // switch
} // if
#endif
m_eState = eNewState;
}
BOOL CAppletSession::IsJoining(void)
{
return (APPSESS_INITIALIZED < m_eState && m_eState < APPSESS_JOINED);
}
void CAppletSession::HandleAttachUserConfirm(void)
{
if (MCS_ATTACH_USER_CONFIRM == m_pTempMsg->eMsgType)
{
ASSERT(IsJoining());
SetState(APPSESS_ATTACH_USER_CON);
if (RESULT_SUCCESSFUL == m_pTempMsg->AttachUserConfirm.eResult)
{
m_uidMyself = m_pTempMsg->AttachUserConfirm.nUserID;
// join my channel
SetState(APPSESS_JOIN_MY_CHANNEL_REQ);
T120Error rc = m_pMCSAppletSAP->ChannelJoin(m_uidMyself);
if (T120_NO_ERROR == rc)
{
return;
}
SetError(rc);
AbortJoin();
}
else
{
SetError(m_pTempMsg->AttachUserConfirm.eResult);
AbortJoin();
}
}
else
{
ERROR_OUT(("CAppletSession::HandleAttachUserConfirm: expecting attach user confirm, invalid msg type=%u",
m_pTempMsg->eMsgType));
}
}
void CAppletSession::HandleTokenGrabConfirm(void)
{
if (MCS_TOKEN_GRAB_CONFIRM == m_pTempMsg->eMsgType)
{
BOOL fImmediateNotification = m_JoinRequest.aResourceReqs[m_nArrayIndex].fImmediateNotification;
ASSERT(IsJoining());
switch (GetState())
{
case APPSESS_RESOURCE_REQ:
ASSERT(APPLET_GRAB_TOKEN_REQUEST == m_JoinRequest.aResourceReqs[m_nArrayIndex].eCommand);
// remember the notification message if needed
if (fImmediateNotification)
{
AddRef();
SendMCSMessage(m_pTempMsg);
if (0 == Release())
{
WARNING_OUT(("CAppletSession::HandleTokenGrabConfirm: involuntary exit"));
return;
}
}
SetState(APPSESS_RESOURCE_CON);
if (RESULT_SUCCESSFUL != m_pTempMsg->TokenConfirm.eResult)
{
m_JoinRequest.aResourceReqs[m_nArrayIndex].nTokenID = 0; // do not grab it
}
DoResourceRequests();
break;
default:
ERROR_OUT(("CAppletSession::HandleTokenGrabConfirm: unknown state=%u", (UINT) GetState()));
break;
}
}
}
void CAppletSession::HandleJoinChannelConfirm(void)
{
if (MCS_CHANNEL_JOIN_CONFIRM == m_pTempMsg->eMsgType)
{
ASSERT(IsJoining());
if (RESULT_SUCCESSFUL == m_pTempMsg->ChannelConfirm.eResult)
{
T120ChannelID nChannelID = m_pTempMsg->ChannelConfirm.nChannelID;
switch (GetState())
{
case APPSESS_JOIN_MY_CHANNEL_REQ:
if (nChannelID == m_uidMyself)
{
SetState(APPSESS_JOIN_MY_CHANNEL_CON);
DoJoinStaticChannels();
}
else
{
ERROR_OUT(("CAppletSession::HandleJoinChannelConfirm: unknown channel join confirm, chid=%x", (UINT) nChannelID));
}
break;
case APPSESS_JOIN_STATIC_CHANNEL_REQ:
if (nChannelID == m_JoinRequest.aStaticChannels[m_nArrayIndex])
{
SetState(APPSESS_JOIN_STATIC_CHANNEL_CON);
DoJoinStaticChannels();
}
else
{
ERROR_OUT(("CAppletSession::HandleJoinChannelConfirm: unknown channel join confirm, chid=%x", (UINT) nChannelID));
}
break;
case APPSESS_RESOURCE_REQ:
// SetState(APPSESS_RESOURCE_CON);
DoResourceRequests();
break;
default:
ERROR_OUT(("CAppletSession::HandleJoinChannelConfirm: unknown state=%u", (UINT) GetState()));
break;
}
}
else
{
ERROR_OUT(("CAppletSession::HandleJoinChannelConfirm: mcs_result=%u", (UINT) m_pTempMsg->ChannelConfirm.eResult));
SetError(m_pTempMsg->ChannelConfirm.eResult);
AbortJoin();
}
}
else
{
ERROR_OUT(("CAppletSession::HandleJoinChannelConfirm: invalid msg type=%u", (UINT) m_pTempMsg->eMsgType));
}
}
void CAppletSession::HandleEnrollConfirm(void)
{
if (GCC_ENROLL_CONFIRM == m_pTempMsg->eMsgType)
{
m_sidMyself = m_pTempMsg->AppEnrollConfirm.sidMyself;
m_eidMyself = m_pTempMsg->AppEnrollConfirm.eidMyself;
m_nidMyself = m_pTempMsg->AppEnrollConfirm.nidMyself;
switch (GetState())
{
case APPSESS_ACTIVELY_ENROLL_REQ:
ASSERT(m_pTempMsg->AppEnrollConfirm.nConfID == m_nConfID);
SetState(APPSESS_ACTIVELY_ENROLL_CON);
if (GCC_RESULT_SUCCESSFUL == m_pTempMsg->AppEnrollConfirm.nResult)
{
SetState(APPSESS_JOINED);
SendJoinResult(GCC_RESULT_SUCCESSFUL);
}
else
{
ERROR_OUT(("CAppletSession::HandleEnrollConfirm: gcc_result=%u", (UINT) m_pTempMsg->AppEnrollConfirm.nResult));
SetError(m_pTempMsg->AppEnrollConfirm.nResult);
AbortJoin();
}
break;
case APPSESS_INACTIVELY_ENROLL_REQ:
ASSERT(m_pTempMsg->AppEnrollConfirm.nConfID == m_nConfID);
SetState(APPSESS_INACTIVELY_ENROLL_CON);
if (GCC_RESULT_SUCCESSFUL == m_pTempMsg->AppEnrollConfirm.nResult)
{
// DoResourceRequests();
}
else
{
ERROR_OUT(("CAppletSession::HandleEnrollConfirm: gcc_result=%u", (UINT) m_pTempMsg->AppEnrollConfirm.nResult));
SetError(m_pTempMsg->AppEnrollConfirm.nResult);
AbortJoin();
}
break;
default:
ERROR_OUT(("CAppletSession::HandleEnrollConfirm: unknown state=%u", (UINT) GetState()));
break;
}
}
else
{
ERROR_OUT(("CAppletSession::HandleEnrollConfirm: expecting enroll confirm, invalid msg type=%u",
(UINT) m_pTempMsg->eMsgType));
}
}
void CAppletSession::HandleRegisterChannelConfirm(void)
{
if (GCC_REGISTER_CHANNEL_CONFIRM == m_pTempMsg->eMsgType)
{
switch (GetState())
{
case APPSESS_RESOURCE_REQ:
DoResourceRequests();
break;
default:
ERROR_OUT(("CAppletSession::HandleRegisterChannelConfirm: unknown state=%u", (UINT) GetState()));
break;
}
}
else
{
ERROR_OUT(("CAppletSession::HandleEnrollConfirm: expecting channel register confirm, invalid msg type=%u",
(UINT) m_pTempMsg->eMsgType));
}
}
void CAppletSession::HandleRetrieveEntryConfirm(void)
{
if (GCC_RETRIEVE_ENTRY_CONFIRM == m_pTempMsg->eMsgType)
{
switch (GetState())
{
case APPSESS_RESOURCE_REQ:
DoResourceRequests();
break;
default:
ERROR_OUT(("CAppletSession::HandleRetrieveEntryConfirm: unknown state=%u", (UINT) GetState()));
break;
}
}
else
{
ERROR_OUT(("CAppletSession::HandleEnrollConfirm: expecting entry retrieve confirm, invalid msg type=%u",
(UINT) m_pTempMsg->eMsgType));
}
}
T120Error CAppletSession::DoEnroll
(
BOOL fEnroll,
BOOL fEnrollActively
)
{
T120Error rc;
T120RequestTag tag;
GCCEnrollRequest Req;
Req.pSessionKey = &m_JoinRequest.SessionKey;
Req.fEnrollActively = fEnrollActively;
Req.nUserID = m_uidMyself;
Req.fConductingCapable = m_JoinRequest.fConductingCapable;
Req.nStartupChannelType = m_JoinRequest.nStartupChannelType;
Req.cNonCollapsedCaps = m_JoinRequest.cNonCollapsedCaps;
Req.apNonCollapsedCaps = m_JoinRequest.apNonCollapsedCaps;
Req.cCollapsedCaps = m_JoinRequest.cCollapsedCaps;
Req.apCollapsedCaps = m_JoinRequest.apCollapsedCaps;
Req.fEnroll = fEnroll;
rc = m_pApplet->GetAppSap()->AppEnroll(m_nConfID, &Req, &tag);
if (GCC_NO_ERROR == rc)
{
return GCC_NO_ERROR;
}
if (fEnroll)
{
WARNING_OUT(("CAppletSession::DoEnroll: AppEnroll failed, rc=%u", (UINT) rc));
ASSERT(GCC_CONFERENCE_NOT_ESTABLISHED == rc);
SetError(rc);
AbortJoin();
}
else
{
// doing nothing because we don't care we fail to unenroll...
}
return rc;
}
void CAppletSession::DoJoinStaticChannels(void)
{
T120Error rc;
ASSERT(IsJoining());
// set up array index
switch (GetState())
{
case APPSESS_JOIN_MY_CHANNEL_CON:
m_nArrayIndex = 0;
break;
case APPSESS_JOIN_STATIC_CHANNEL_CON:
m_nArrayIndex++;
break;
default:
ERROR_OUT(("CAppletSession::DoJoinStaticChannels: invalid state=%u", (UINT) GetState()));
break;
}
if (m_nArrayIndex < m_JoinRequest.cStaticChannels &&
NULL != m_JoinRequest.aStaticChannels)
{
SetState(APPSESS_JOIN_STATIC_CHANNEL_REQ);
rc = m_pMCSAppletSAP->ChannelJoin(m_JoinRequest.aStaticChannels[m_nArrayIndex]);
if (T120_NO_ERROR == rc)
{
return;
}
ERROR_OUT(("CAppletSession::DoJoinStaticChannels: ChannelJoin failed, rc=%u", (UINT) rc));
SetError(rc);
AbortJoin();
}
else
{
m_nArrayIndex = 0;
if (m_JoinRequest.cResourceReqs == 0)
{
SetState(APPSESS_ACTIVELY_ENROLL_REQ);
DoEnroll(TRUE, TRUE);
}
else
{
SetState(APPSESS_INACTIVELY_ENROLL_REQ);
DoEnroll(TRUE, FALSE);
}
}
}
void CAppletSession::DoResourceRequests(void)
{
//T120Error rc;
BOOL fInitResourceState = FALSE;
//ULONG i;
ASSERT(IsJoining());
// set up array index
switch (GetState())
{
case APPSESS_INACTIVELY_ENROLL_CON:
m_nArrayIndex = 0;
fInitResourceState = TRUE;
SetState(APPSESS_RESOURCE_REQ);
break;
case APPSESS_RESOURCE_REQ:
// do nothing
break;
case APPSESS_RESOURCE_CON:
m_nArrayIndex++;
fInitResourceState = TRUE;
SetState(APPSESS_RESOURCE_REQ);
break;
default:
ERROR_OUT(("CAppletSession::DoJoinDynamicChannels: invalid state=%u", (UINT) GetState()));
break;
}
if (m_nArrayIndex < m_JoinRequest.cResourceReqs)
{
ASSERT(NULL != m_JoinRequest.aResourceReqs);
switch (m_JoinRequest.aResourceReqs[m_nArrayIndex].eCommand)
{
case APPLET_GRAB_TOKEN_REQUEST:
DoGrabTokenRequest();
break;
case APPLET_JOIN_DYNAMIC_CHANNEL:
DoJoinDynamicChannels(fInitResourceState);
break;
default:
ERROR_OUT(("CAppletSession::DoResourceRequests: should not get here, state=%u",
(UINT) m_JoinRequest.aResourceReqs[m_nArrayIndex].eCommand));
break;
}
}
else
{
SetState(APPSESS_ACTIVELY_ENROLL_REQ);
DoEnroll(TRUE, TRUE);
}
}
void CAppletSession::DoGrabTokenRequest(void)
{
T120TokenRequest Req;
Req.eCommand = APPLET_GRAB_TOKEN;
Req.nTokenID = m_JoinRequest.aResourceReqs[m_nArrayIndex].nTokenID;
TokenRequest(&Req);
}
void CAppletSession::DoJoinDynamicChannels(BOOL fInitState)
{
T120Error rc;
//ULONG i;
ASSERT(IsJoining());
ASSERT(APPLET_JOIN_DYNAMIC_CHANNEL == m_JoinRequest.aResourceReqs[m_nArrayIndex].eCommand);
if (fInitState)
{
m_eDynamicChannelJoinState = DCJS_INITIALIZED;
}
switch (m_eDynamicChannelJoinState)
{
case DCJS_INITIALIZED:
// clean up all the dynamic channel id
m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID = 0;
// start the first dynamic channel negotiation process
// SetState(APPSESS_JOIN_DYNAMIC_CHANNEL_REQ);
m_eDynamicChannelJoinState = DCJS_RETRIEVE_ENTRY_REQ;
rc = m_pApplet->GetAppSap()->RegistryRetrieveEntry(m_nConfID,
&m_JoinRequest.aResourceReqs[m_nArrayIndex].RegKey);
if (T120_NO_ERROR != rc)
{
ERROR_OUT(("CAppletSession::DoJoinDynamicChannels: RegistryRetrieveEntry failed, rc=%u", (UINT) rc));
SetError(rc);
AbortJoin();
}
break;
case DCJS_EXISTING_CHANNEL_JOIN_REQ:
if (MCS_CHANNEL_JOIN_CONFIRM == m_pTempMsg->eMsgType)
{
if (m_pTempMsg->ChannelConfirm.nChannelID == m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID)
{
m_eDynamicChannelJoinState = DCJS_EXISTING_CHANNEL_JOIN_CON;
SetState(APPSESS_RESOURCE_CON);
DoResourceRequests();
}
else
{
ERROR_OUT(("CAppletSession::DoJoinDynamicChannels: unknown channel join confirm, chid=%x",
(UINT) m_pTempMsg->ChannelConfirm.nChannelID));
}
}
else
{
ERROR_OUT(("CAppletSession::DoJoinDynamicChannels: expecting channel join confirm, invalid msg type=%u",
(UINT) m_pTempMsg->eMsgType));
}
break;
case DCJS_NEW_CHANNEL_JOIN_REQ:
if (MCS_CHANNEL_JOIN_CONFIRM == m_pTempMsg->eMsgType)
{
ASSERT(0 == m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID);
m_eDynamicChannelJoinState = DCJS_NEW_CHANNEL_JOIN_CON;
// remember the channel id
m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID = m_pTempMsg->ChannelConfirm.nChannelID;
// try to register this channel
m_eDynamicChannelJoinState = DCJS_REGISTER_CHANNEL_REQ;
rc = m_pApplet->GetAppSap()->RegisterChannel(m_nConfID,
&m_JoinRequest.aResourceReqs[m_nArrayIndex].RegKey,
m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID);
if (T120_NO_ERROR != rc)
{
ERROR_OUT(("CAppletSession::DoJoinDynamicChannels: RegistryRetrieveEntry failed, rc=%u", (UINT) rc));
SetError(rc);
AbortJoin();
}
}
else
{
ERROR_OUT(("CAppletSession::DoJoinDynamicChannels: expecting channel join confirm, invalid msg type=%u",
(UINT) m_pTempMsg->eMsgType));
}
break;
case DCJS_RETRIEVE_ENTRY_REQ:
if (GCC_RETRIEVE_ENTRY_CONFIRM == m_pTempMsg->eMsgType)
{
m_eDynamicChannelJoinState = DCJS_RETRIEVE_ENTRY_CON;
ASSERT(m_nConfID == m_pTempMsg->RegistryConfirm.nConfID);
if (GCC_RESULT_SUCCESSFUL == m_pTempMsg->RegistryConfirm.nResult)
{
ASSERT(GCC_REGISTRY_CHANNEL_ID == m_pTempMsg->RegistryConfirm.pRegItem->item_type);
ASSERT(0 != m_pTempMsg->RegistryConfirm.pRegItem->channel_id);
// remember the existing channel ID
m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID = m_pTempMsg->RegistryConfirm.pRegItem->channel_id;
// join this channel
m_eDynamicChannelJoinState = DCJS_EXISTING_CHANNEL_JOIN_REQ;
rc = m_pMCSAppletSAP->ChannelJoin(m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID);
if (T120_NO_ERROR != rc)
{
ERROR_OUT(("CAppletSession::DoJoinDynamicChannels: ChannelJoin(%u) failed, rc=%u",
(UINT) m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID, (UINT) rc));
SetError(rc);
AbortJoin();
}
}
else
{
ASSERT(GCC_RESULT_ENTRY_DOES_NOT_EXIST == m_pTempMsg->RegistryConfirm.nResult);
ASSERT(0 == m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID);
// allocate a new channel
m_eDynamicChannelJoinState = DCJS_NEW_CHANNEL_JOIN_REQ;
rc = m_pMCSAppletSAP->ChannelJoin(0);
if (T120_NO_ERROR != rc)
{
ERROR_OUT(("CAppletSession::DoJoinDynamicChannels: ChannelJoin(0) failed, rc=%u", (UINT) rc));
SetError(rc);
AbortJoin();
}
}
}
else
{
ERROR_OUT(("CAppletSession::DoJoinDynamicChannels: expecting entry retrieve confirm, invalid msg type=%u",
(UINT) m_pTempMsg->eMsgType));
}
break;
case DCJS_REGISTER_CHANNEL_REQ:
if (GCC_REGISTER_CHANNEL_CONFIRM == m_pTempMsg->eMsgType)
{
ASSERT(0 != m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID);
m_eDynamicChannelJoinState = DCJS_REGISTER_CHANNEL_CON;
if (GCC_RESULT_SUCCESSFUL == m_pTempMsg->RegistryConfirm.nResult)
{
ASSERT(GCC_REGISTRY_CHANNEL_ID == m_pTempMsg->RegistryConfirm.pRegItem->item_type);
ASSERT(m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID == m_pTempMsg->RegistryConfirm.pRegItem->channel_id);
SetState(APPSESS_RESOURCE_CON);
DoResourceRequests();
}
else
if (GCC_RESULT_ENTRY_ALREADY_EXISTS == m_pTempMsg->RegistryConfirm.nResult)
{
ASSERT(GCC_REGISTRY_CHANNEL_ID == m_pTempMsg->RegistryConfirm.pRegItem->item_type);
// leave the old channel (DON'T CARE ABOUT THE CONFIRM)
rc = m_pMCSAppletSAP->ChannelLeave(m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID);
ASSERT(T120_NO_ERROR == rc);
// remember the new channel id
m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID = m_pTempMsg->RegistryConfirm.pRegItem->channel_id;
// join the new channel
m_eDynamicChannelJoinState = DCJS_EXISTING_CHANNEL_JOIN_REQ;
rc = m_pMCSAppletSAP->ChannelJoin(m_JoinRequest.aResourceReqs[m_nArrayIndex].nChannelID);
if (T120_NO_ERROR != rc)
{
ERROR_OUT(("CAppletSession::DoJoinDynamicChannels: ChannelJoin(0) failed, rc=%u", (UINT) rc));
SetError(rc);
AbortJoin();
}
}
else
{
ERROR_OUT(("CAppletSession::DoJoinDynamicChannels: ChannelJoin(0) failed, result=%u",
(UINT) m_pTempMsg->RegistryConfirm.nResult));
SetError(m_pTempMsg->RegistryConfirm.nResult);
AbortJoin();
}
}
else
{
ERROR_OUT(("CAppletSession::DoJoinDynamicChannels: expecting channel register confirm, invalid msg type=%u",
(UINT) m_pTempMsg->eMsgType));
}
break;
default:
ERROR_OUT(("CAppletSession::DoJoinDynamicChannels: should not get here, state=%u", (UINT) m_eDynamicChannelJoinState));
break;
}
}
void CAppletSession::AbortJoin(void)
{
T120Result eResult = T120_RESULT_CHECK_T120_ERROR;
T120Error eError = T12_ERROR_CHECK_T120_RESULT;
switch (m_eErrorType)
{
case NONE_CHOSEN:
ERROR_OUT(("CAppletSession::AbortJoin: NON_CHOSEN, impossible"));
break;
case ERROR_CHOSEN:
eError = m_Error.eError;
break;
case RESULT_CHOSEN:
eResult = m_Error.eResult;
break;
default:
ERROR_OUT(("CAppletSession::AbortJoin: invalid err type=%u", (UINT) m_eErrorType));
break;
}
// let's debug why the join process is aborted.
WARNING_OUT(("CAppletSession::AbortJoin: eResult=%u, eError=%u", eResult, eError));
ASSERT(GCC_CONFERENCE_NOT_ESTABLISHED == eError ||
T12_ERROR_CHECK_T120_RESULT == eError);
SendJoinResult(eResult, eError);
}
void CAppletSession::SendJoinResult(T120Result eResult, T120Error eError)
{
T120AppletSessionMsg Msg;
::ZeroMemory(&Msg, sizeof(Msg));
Msg.eMsgType = T120_JOIN_SESSION_CONFIRM;
Msg.nConfID = m_nConfID;
Msg.JoinSessionConfirm.eResult = eResult;
Msg.JoinSessionConfirm.eError = eError;
Msg.JoinSessionConfirm.pIAppletSession = (IT120AppletSession *) this;
if (T120_RESULT_SUCCESSFUL == eResult)
{
Msg.JoinSessionConfirm.uidMyself = m_uidMyself;
Msg.JoinSessionConfirm.sidMyself = m_sidMyself;
Msg.JoinSessionConfirm.eidMyself = m_eidMyself;
Msg.JoinSessionConfirm.nidMyself = m_nidMyself;
Msg.JoinSessionConfirm.cResourceReqs = m_JoinRequest.cResourceReqs;
Msg.JoinSessionConfirm.aResourceReqs = m_JoinRequest.aResourceReqs;
}
SendCallbackMessage(&Msg);
}
CApplet::CApplet
(
T120Error *pRetCode
)
:
CRefCount(MAKE_STAMP_ID('C','A','p','l')),
m_pfnCallback(NULL),
m_pAppletContext(NULL),
m_pAppSap(NULL),
m_pAutoJoinReq(NULL),
m_pAutoAppletSession(NULL)
{
*pRetCode = ::GCC_CreateAppSap(&m_pAppSap, this, GCC_SapCallback);
}
CApplet::~CApplet(void)
{
ASSERT(NULL == m_pfnCallback);
ASSERT(NULL == m_pAppletContext);
ASSERT(NULL == m_pAppSap);
}
void CApplet::ReleaseInterface(void)
{
Unadvise();
if (NULL != m_pAppSap)
{
m_pAppSap->ReleaseInterface();
m_pAppSap = NULL;
}
Release();
}
void CApplet::Advise
(
LPFN_APPLET_CB pfnCallback,
LPVOID pAppletContext
)
{
ASSERT(NULL == m_pfnCallback);
ASSERT(NULL == m_pAppletContext);
m_pfnCallback = pfnCallback;
m_pAppletContext = pAppletContext;
// this may incur permit to enroll indication
g_pGCCController->RegisterApplet(this);
}
void CApplet::Unadvise(void)
{
m_pfnCallback = NULL;
m_pAppletContext = NULL;
if (g_pGCCController)
{
g_pGCCController->UnregisterApplet(this);
}
}
T120Error CApplet::RegisterAutoJoin
(
T120JoinSessionRequest *pReq
)
{
m_pAutoJoinReq = pReq;
return T120_NO_ERROR;
}
void CApplet::UnregisterAutoJoin(void)
{
m_pAutoJoinReq = NULL;
}
T120Error CApplet::CreateSession
(
IT120AppletSession **ppSession,
T120ConfID nConfID
)
{
if (NULL != ppSession)
{
if (NULL != g_pGCCController->GetConfObject(nConfID))
{
if (! FindSessionByConfID(nConfID))
{
DBG_SAVE_FILE_LINE
*ppSession = (IT120AppletSession *) new CAppletSession(this, nConfID);
if (NULL != *ppSession)
{
return T120_NO_ERROR;
}
ERROR_OUT(("CApplet::CreateSession: cannot create CAppletSession"));
return T120_ALLOCATION_FAILURE;
}
WARNING_OUT(("CApplet::CreateSession: session already exists for nConfID=%u", (UINT) nConfID));
return GCC_CONFERENCE_ALREADY_EXISTS;
}
WARNING_OUT(("CApplet::CreateSession: invalid conf, nConfID=%u", (UINT) nConfID));
return GCC_INVALID_CONFERENCE;
}
ERROR_OUT(("CApplet::CreateSession: ppSession is null"));
return T120_INVALID_PARAMETER;
}
void CApplet::SendCallbackMessage(T120AppletMsg *pMsg)
{
if (NULL != m_pfnCallback)
{
pMsg->pAppletContext = m_pAppletContext;
(*m_pfnCallback)(pMsg);
}
}
void CApplet::GCCCallback
(
T120AppletSessionMsg *pMsg
)
{
T120ConfID nConfID = pMsg->nConfID;
ASSERT(0 != nConfID);
if (GCC_PERMIT_TO_ENROLL_INDICATION == pMsg->eMsgType)
{
T120AppletMsg *p = (T120AppletMsg *) pMsg;
if (p->PermitToEnrollInd.fPermissionGranted && NULL != m_pAutoJoinReq)
{
HandleAutoJoin(nConfID);
}
else
{
if (! p->PermitToEnrollInd.fPermissionGranted)
{
CAppletSession *pAppletSession = FindSessionByConfID(nConfID);
if (NULL != pAppletSession)
{
if (pAppletSession->IsJoining())
{
pAppletSession->SetError(GCC_CONFERENCE_NOT_ESTABLISHED);
pAppletSession->AbortJoin();
}
}
}
SendCallbackMessage(p);
}
}
else
{
CAppletSession *pAppletSession = FindSessionByConfID(nConfID);
if (NULL != pAppletSession)
{
pAppletSession->GCCCallback(pMsg);
}
else
{
WARNING_OUT(("GCC_SapCallback: cannot find a session (%u) for this gcc message (%u)",
(UINT) nConfID, (UINT) pMsg->eMsgType));
}
}
}
void CALLBACK AutoJoinCallbackProc
(
T120AppletSessionMsg *pMsg
)
{
switch (pMsg->eMsgType)
{
case T120_JOIN_SESSION_CONFIRM:
if (NULL != pMsg->pAppletContext)
{
pMsg->pSessionContext = NULL;
((CApplet *) pMsg->pAppletContext)->SendCallbackMessage((T120AppletMsg *) pMsg);
}
break;
default:
ERROR_OUT(("AutoJoinCallbackProc: invalid msg type=%u", pMsg->eMsgType));
break;
}
}
void CApplet::HandleAutoJoin
(
T120ConfID nConfID
)
{
DBG_SAVE_FILE_LINE
CAppletSession *pSession = new CAppletSession(this, nConfID);
if (NULL != pSession)
{
T120Error rc;
pSession->Advise(AutoJoinCallbackProc, this, pSession);
rc = pSession->Join(m_pAutoJoinReq);
if (rc != T120_NO_ERROR)
{
delete pSession;
}
}
}
CAppletSession * CSessionList::FindByConfID
(
T120ConfID nConfID
)
{
CAppletSession *p;
Reset();
while (NULL != (p = Iterate()))
{
if (p->GetConfID() == nConfID)
{
return p;
}
}
return NULL;
}
void CALLBACK GCC_SapCallback
(
GCCAppSapMsg *_pMsg
)
{
T120AppletSessionMsg *pMsg = (T120AppletSessionMsg *) _pMsg;
CApplet *pApplet = (CApplet *) pMsg->pAppletContext;
ASSERT(NULL != pApplet);
pApplet->GCCCallback(pMsg);
}
void CALLBACK MCS_SapCallback
(
UINT nMsg,
LPARAM Param1,
LPVOID Param2
)
{
CAppletSession *pAppletSession = (CAppletSession *) Param2;
ASSERT(NULL != pAppletSession);
T120AppletSessionMsg Msg;
::ZeroMemory(&Msg, sizeof(Msg));
Msg.eMsgType = (T120MessageType) nMsg;
// Msg.pAppletContext = NULL;
// Msg.pSessionContext = NULL;
// Msg.nConfID = 0;
// construct MCS message
switch (Msg.eMsgType)
{
// send data
case MCS_SEND_DATA_INDICATION:
case MCS_UNIFORM_SEND_DATA_INDICATION:
Msg.SendDataInd = * (SendDataIndicationPDU *) Param1;
break;
// channel confirm
case MCS_CHANNEL_JOIN_CONFIRM:
case MCS_CHANNEL_CONVENE_CONFIRM:
Msg.ChannelConfirm.eResult = (T120Result) HIWORD(Param1);
Msg.ChannelConfirm.nChannelID = LOWORD(Param1);
break;
// channel indication
case MCS_CHANNEL_LEAVE_INDICATION:
case MCS_CHANNEL_DISBAND_INDICATION:
case MCS_CHANNEL_ADMIT_INDICATION:
case MCS_CHANNEL_EXPEL_INDICATION:
Msg.ChannelInd.nChannelID = LOWORD(Param1);
Msg.ChannelInd.eReason = (T120Reason) HIWORD(Param1);
break;
// token confirm
case MCS_TOKEN_GRAB_CONFIRM:
case MCS_TOKEN_INHIBIT_CONFIRM:
case MCS_TOKEN_GIVE_CONFIRM:
case MCS_TOKEN_RELEASE_CONFIRM:
case MCS_TOKEN_TEST_CONFIRM:
Msg.TokenConfirm.nTokenID = LOWORD(Param1);
Msg.TokenConfirm.eResult = (T120Result) HIWORD(Param1);
break;
// token indication
case MCS_TOKEN_GIVE_INDICATION:
case MCS_TOKEN_PLEASE_INDICATION:
case MCS_TOKEN_RELEASE_INDICATION:
Msg.TokenInd.nTokenID = LOWORD(Param1);
Msg.TokenInd.eReason = (T120Reason) HIWORD(Param1);
break;
// user
case MCS_ATTACH_USER_CONFIRM:
Msg.AttachUserConfirm.nUserID = LOWORD(Param1);
Msg.AttachUserConfirm.eResult = (T120Result) HIWORD(Param1);
break;
case MCS_DETACH_USER_INDICATION:
Msg.DetachUserInd.nUserID = LOWORD(Param1);
Msg.DetachUserInd.eReason = (T120Reason) HIWORD(Param1);
break;
default:
WARNING_OUT(("MCS_SapCallback: Ignore MCS message, type=%u", Msg.eMsgType));
break;
}
pAppletSession->MCSCallback(&Msg);
}