|
|
#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); }
|