📄 portemu.cxx
字号:
rfcommsdp_disconnect(pCall, status);
gpPORTEMU->Unlock();
return ERROR_SUCCESS;
}
static int portemu_connect_request_ind (void *pUserContext, HANDLE hConnection, BD_ADDR *pba, unsigned char channel) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_connect_request_ind 0x%08x\n", pUserContext));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_connect_request_ind 0x%08x : not initialized!\n", pUserContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_connect_request_ind 0x%08x: not initialized!\n", pUserContext));
gpPORTEMU->Unlock ();
return 0;
}
PORTEMU_CONTEXT *pContext = GetContext ((DWORD)pUserContext);
if (! pContext) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_connect_request_ind 0x%08x : context not found\n", pUserContext));
gpPORTEMU->Unlock ();
return ERROR_NOT_FOUND;
}
int fAllow = FALSE;
HANDLE hRFCOMM = pContext->hRFCOMM;
RFCOMM_ConnectResponse_In pCallback = pContext->rfcomm_if.rfcomm_ConnectResponse_In;
if ((pContext->channel == channel) && pContext->fLocal && pContext->fLocalOpen && !pContext->fConnected) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"Got active connection from %04x%08x (%d)\n", pba->NAP, pba->SAP, channel));
if (pContext->freq_auth || pContext->freq_encrypt) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"Requesting authentication for connection from %04x%08x (%d)\n", pba->NAP, pba->SAP, channel));
SVSCookie cookie = btutil_ScheduleEvent (AuthenticateThread, pContext);
if (cookie) {
pContext->b = *pba;
ReinitNewConnection (pContext, hConnection);
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_connect_request_ind 0x%08x : could not create authentication thread\n", pUserContext));
} else {
fAllow = TRUE;
pContext->b = *pba;
ReinitNewConnection (pContext, hConnection);
RegisterCommEvent (pContext, EV_RLSD, 0);
}
}
gpPORTEMU->Unlock ();
int iRes = ERROR_INTERNAL_ERROR;
__try {
iRes = pCallback (hRFCOMM, NULL, hConnection, fAllow);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_connect_request_ind 0x%08x : exception in rfcomm_ConnectResponse_In\n", pUserContext));
}
if (fAllow && (iRes == ERROR_SUCCESS) && gpPORTEMU) {
gpPORTEMU->Lock ();
if ((pContext == GetContext ((DWORD)pUserContext)) && pContext->hConnection) {
pContext->ucv24out &= ~MSC_FC_BIT;
SendMSC (pContext);
}
gpPORTEMU->Unlock ();
}
return iRes;
}
static int portemu_data_up_ind (void *pUserContext, HANDLE hConnection, BD_BUFFER *pb, int cAdditionalCredits) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_data_up_ind 0x%08x, new credits = %d\n", pUserContext, cAdditionalCredits));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_data_up_ind 0x%08x : not initialized!\n", pUserContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_data_up_ind 0x%08x: not initialized!\n", pUserContext));
if (pb->pFree)
pb->pFree (pb);
gpPORTEMU->Unlock ();
return 0;
}
PORTEMU_CONTEXT *pContext = GetContext ((DWORD)pUserContext);
if (! pContext) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_data_up_ind 0x%08x : context not found\n", pUserContext));
if (pb->pFree)
pb->pFree (pb);
gpPORTEMU->Unlock ();
return ERROR_NOT_FOUND;
}
// First see if we have consumers
PendingIO *pParent = NULL;
PendingIO *pIO = pContext->pops;
int cHaveData = BufferTotal (pb);
if ((cHaveData > 0) && pContext->credit_fc)
--pContext->iGaveCredits;
while (pIO && (cHaveData > 0)) {
if (pIO->op == COMM_READ) {
SVSUTIL_ASSERT (! pContext->pbl); // else why is the request here???
int cBytes = cHaveData > (pIO->cbuffer - pIO->cbuffer_used) ? (pIO->cbuffer - pIO->cbuffer_used) : cHaveData;
DWORD dwCurrentPerms = SetProcPermissions (pIO->dwPerms);
BOOL bkm = SetKMode (TRUE);
int iRes = BufferGetChunk (pb, cBytes, pIO->buffer + pIO->cbuffer_used);
SetKMode (bkm);
SetProcPermissions (dwCurrentPerms);
SVSUTIL_ASSERT (iRes);
cHaveData -= cBytes;
SVSUTIL_ASSERT (cHaveData == BufferTotal (pb));
pIO->cbuffer_used += cBytes;
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_data_up_ind 0x%08x : sat. read (%d bytes)\n", pUserContext, cBytes));
if (pIO->cbuffer_used == pIO->cbuffer) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_data_up_ind 0x%08x : retired read event\n", pUserContext, cBytes));
PendingIO *pNext = pIO->pNext;
pIO->pNext = NULL;
pIO->iIoResult = ERROR_SUCCESS;
SetEvent (pIO->hEvent);
if (pParent)
pParent->pNext = pNext;
else
pContext->pops = pNext;
pIO = pNext;
} else {
SVSUTIL_ASSERT (cHaveData == 0);
break;
}
} else {
pParent = pIO;
pIO = pIO->pNext;
}
}
SVSUTIL_ASSERT (cHaveData == BufferTotal (pb));
if ((cHaveData + pContext->iRecvQuotaUsed) > GetQuota(pContext)) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] OUT OF quota receiving the buffer!\n"));
cHaveData = 0;
RegisterCommEvent (pContext, EV_ERR, CE_OVERRUN);
}
if (cHaveData > 0) { // Queue the remainder
if (pb->fMustCopy)
pb = BufferCompress (pb); // Note: this is somewhat hackish, but it does not leak. Mental exercise: why :-)?
BD_BUFFER_LIST *pbl = pb ? new BD_BUFFER_LIST : NULL;
if (pbl) { // decrement quota and store the data
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_data_up_ind 0x%08x : queueing %d bytes\n", pUserContext, cHaveData));
pbl->pNext = NULL;
pbl->pb = pb;
if (pContext->pbl) {
BD_BUFFER_LIST *pP = pContext->pbl;
while (pP->pNext)
pP = pP->pNext;
pP->pNext = pbl;
} else
pContext->pbl = pbl;
pContext->iRecvQuotaUsed += cHaveData;
RegisterCommEvent (pContext, EV_RXCHAR, 0);
} else {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] OUTOFMEMORY queueing the buffer!\n"));
cHaveData = 0;
}
}
if (cHaveData == 0) { // Buffer all read or of no use anyway...
if (pb && pb->pFree)
pb->pFree (pb);
}
if ((! pContext->credit_fc) && (! pContext->fSentXon) && (pContext->iRecvQuotaUsed > pContext->dcb.XonLim)) {
pContext->fSentXon = TRUE;
pContext->ucv24out |= MSC_FC_BIT;
SendMSC (pContext);
} else if (pContext->credit_fc) {
pContext->iHaveCredits += cAdditionalCredits;
if (pContext->iHaveCredits - cAdditionalCredits <= 0)
SendData (pContext);
if (gpPORTEMU->fInitialized && (pContext == GetContext ((DWORD)pUserContext)))
SendCredits (pContext);
}
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
static int portemu_disconnect_ind (void *pUserContext, HANDLE hConnection) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_disconnect_ind 0x%08x\n", pUserContext));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_disconnect_ind 0x%08x : not initialized!\n", pUserContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_disconnect_ind 0x%08x: not initialized!\n", pUserContext));
gpPORTEMU->Unlock ();
return 0;
}
PORTEMU_CONTEXT *pContext = GetContext ((DWORD)pUserContext);
if (! pContext) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_disconnect_ind 0x%08x : context not found\n", pUserContext));
gpPORTEMU->Unlock ();
return ERROR_NOT_FOUND;
}
pContext->hConnection = NULL;
CloseConnection (pContext, ERROR_GRACEFUL_DISCONNECT, FALSE);
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
static int portemu_pnreq_ind (void *pUserContext, HANDLE hConnection, unsigned char priority, unsigned short n1, int use_credit_fc, int initial_credits) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_pnreq_ind 0x%08x hconn = 0x%08x, pri = %d, mtu = %d, credit = %x, initial credtis = %d\n", pUserContext, hConnection, priority, n1, use_credit_fc, initial_credits));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_pnreq_ind 0x%08x : not initialized!\n", pUserContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_pnreq_ind 0x%08x: not initialized!\n", pUserContext));
gpPORTEMU->Unlock ();
return 0;
}
PORTEMU_CONTEXT *pContext = GetContext ((DWORD)pUserContext);
if (! pContext) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_pnreq_ind 0x%08x : context not found\n", pUserContext));
gpPORTEMU->Unlock ();
return ERROR_NOT_FOUND;
}
if (! pContext->hConnection)
pContext->hConnection = hConnection;
if (n1 > pContext->iMaxMTU)
n1 = pContext->iMaxMTU;
if (n1 < pContext->iMinMTU)
n1 = pContext->iMinMTU;
pContext->iMTU = n1;
if (use_credit_fc == RFCOMM_PN_CREDIT_IN) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_pnreq_ind 0x%08x CREDIT-based Flow ON\n", pUserContext));
pContext->credit_fc = TRUE;
pContext->iHaveCredits = initial_credits;
pContext->iGaveCredits = RFCOMM_PN_CREDIT_MAX;
} else {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_pnreq_ind 0x%08x CREDIT-based Flow OFF\n", pUserContext));
pContext->credit_fc = FALSE;
pContext->iHaveCredits = 0;
pContext->iGaveCredits = 0;
}
HANDLE h = pContext->hRFCOMM;
RFCOMM_PNRSP_In pCallback = pContext->rfcomm_if.rfcomm_PNRSP_In;
gpPORTEMU->Unlock ();
int iRes = ERROR_INTERNAL_ERROR;
__try {
iRes = pCallback (h, NULL, hConnection, priority, n1,
(use_credit_fc == RFCOMM_PN_CREDIT_IN) ? RFCOMM_PN_CREDIT_OUT : 0,
(use_credit_fc == RFCOMM_PN_CREDIT_IN) ? RFCOMM_PN_CREDIT_MAX : 0);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_pnreq_ind Exception in rfcomm_PNRSP_In\n"));
}
#if defined (DEBUG) || defined (_DEBUG) || defined (RETAILLOG)
if (iRes != ERROR_SUCCESS)
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_pnreq_ind rfcomm_PNRSP_In returns %d\n", iRes));
#endif
return ERROR_SUCCESS;
}
static int portemu_rpnreq_ind (void *pUserContext, HANDLE hConnection, unsigned short mask, int baud, int data, int stop, int parity, int parity_type, unsigned char flow, unsigned char xon, unsigned char xoff) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_rpnreq_ind 0x%08x hconn = 0x%08x\n", pUserContext, hConnection));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_rpnreq_ind 0x%08x : not initialized!\n", pUserContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_rpnreq_ind 0x%08x: not initialized!\n", pUserContext));
gpPORTEMU->Unlock ();
return 0;
}
PORTEMU_CONTEXT *pContext = GetContext ((DWORD)pUserContext);
if (! pContext) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_rpnreq_ind 0x%08x : context not found\n", pUserContext));
gpPORTEMU->Unlock ();
return ERROR_NOT_FOUND;
}
if (mask & RFCOMM_RPN_HAVE_BAUD)
pContext->dcb.BaudRate = baud;
if (mask & RFCOMM_RPN_HAVE_DATA)
pContext->dcb.ByteSize = data;
if (mask & RFCOMM_RPN_HAVE_STOP)
pContext->dcb.StopBits = stop;
if (mask & RFCOMM_RPN_HAVE_PARITY)
pContext->dcb.fParity = parity;
if (mask & RFCOMM_RPN_HAVE_PT)
pContext->dcb.Parity = parity_type;
if (mask & RFCOMM_RPN_HAVE_XOFF)
pContext->dcb.XoffChar = xoff;
if (mask & RFCOMM_RPN_HAVE_XON)
pContext->dcb.XonChar = xon;
if (mask & RFCOMM_RPN_HAVE_XON_IN)
pContext->dcb.fInX = flow & RFCOMM_RPN_XON_IN ? TRUE : FALSE;
if (mask & RFCOMM_RPN_HAVE_XON_OUT)
pContext->dcb.fOutX = flow & RFCOMM_RPN_XON_OUT ? TRUE : FALSE;
if (! mask) {
mask = RFCOMM_RPN_HAVE_BAUD | RFCOMM_RPN_HAVE_DATA | RFCOMM_RPN_HAVE_STOP |
RFCOMM_RPN_HAVE_PARITY | RFCOMM_RPN_HAVE_PT;
baud = pContext->dcb.BaudRate;
data = pContext->dcb.ByteSize;
stop = pContext->dcb.StopBits;
parity = pContext->dcb.fParity;
parity_type = pContext->dcb.Parity;
xoff = 0;
xon = 0;
flow = 0;
} else
RegisterCommEvent (pContext, EV_EVENT1, 0);
HANDLE h = pContext->hRFCOMM;
RFCOMM_RPNRSP_In pCallback = pContext->rfcomm_if.rfcomm_RPNRSP_In;
gpPORTEMU->Unlock ();
int iRes = ERROR_INTERNAL_ERROR;
__try {
iRes = pCallback (h, NULL, hConnection, mask, baud, data, stop, parity, parity_type, flow, xon, xoff);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_rpnreq_ind Exception in rfcomm_PNRSP_In\n"));
}
#if defined (DEBUG) || defined (_DEBUG) || defined (RETAILLOG)
if (iRes != ERROR_SUCCESS)
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_rpnreq_ind rfcomm_PNRSP_In returns %d\n", iRes));
#endif
return ERROR_SUCCESS;
}
static int portemu_fc_ind (void *pUserContext, HANDLE hConnect, unsigned char fcOn) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_fc_ind 0x%08x %s\n", pUserContext, fcOn ? L"on" : L"off"));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_fc_ind 0x%08x : not initialized!\n", pUserContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_fc_ind 0x%08x: not initialized!\n", pUserContext));
gpPORTEMU->Unlock ();
return 0;
}
PORTEMU_CONTEXT *pContext = GetContext ((DWORD)pUserContext);
if (! pContext) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_fc_ind 0x%08x : context not found\n", pUserContext));
gpPORTEMU->Unlock ();
return ERROR_NOT_FOUND;
}
if (fcOn) {
pContext->fc_aggregate = FALSE;
SendData (pContext);
} else
pContext->fc_aggregate = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -