📄 portemu.cxx
字号:
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
static int portemu_msc_ind (void *pUserContext, HANDLE hConnect, unsigned char v24, unsigned char bs) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_msc_ind 0x%08x 0x%02x 0x%02x\n", pUserContext, v24, bs));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_msc_ind 0x%08x : not initialized!\n", pUserContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_msc_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_msc_ind 0x%08x : context not found\n", pUserContext));
gpPORTEMU->Unlock ();
return ERROR_NOT_FOUND;
}
if (pContext->fkeep_dcd)
v24 |= MSC_DV_BIT;
DWORD dwOldLine = pContext->dwModemStatusIn;
if (v24 & MSC_RTC_BIT) // RTC == DSR
pContext->dwModemStatusIn |= MS_DSR_ON;
else
pContext->dwModemStatusIn &= ~MS_DSR_ON;
if (v24 & MSC_RTR_BIT) // RTR == CTS
pContext->dwModemStatusIn |= MS_CTS_ON;
else
pContext->dwModemStatusIn &= ~MS_CTS_ON;
if (v24 & MSC_IC_BIT)
pContext->dwModemStatusIn |= MS_RING_ON;
else
pContext->dwModemStatusIn &= ~MS_RING_ON;
if (v24 & MSC_DV_BIT) // DV = DCD
pContext->dwModemStatusIn |= MS_RLSD_ON;
else
pContext->dwModemStatusIn &= ~MS_RLSD_ON;
dwOldLine ^= pContext->dwModemStatusIn;
if (v24 & MSC_FC_BIT)
pContext->fc = TRUE;
else {
pContext->fc = FALSE;
SendData (pContext);
}
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"MSC Indicated : %s %s %s %s\n",
dwOldLine & MS_RING_ON ? L"EV_RING" : L"",
dwOldLine & MS_DSR_ON ? L"EV_DSR" : L"",
dwOldLine & MS_CTS_ON ? L"EV_CTS" : L"",
dwOldLine & MS_RLSD_ON ? L"EV_RLSD" : L"",
v24 & MSC_FC_BIT ? L"Flow_Off" : L""));
// Signal status change
if (dwOldLine && gpPORTEMU->fInitialized && (pContext == GetContext ((DWORD)pUserContext))) {
DWORD dwEvent = 0;
if (dwOldLine & MS_RING_ON)
dwEvent = EV_RING;
if (dwOldLine & MS_DSR_ON)
dwEvent |= EV_DSR;
if (dwOldLine & MS_CTS_ON)
dwEvent |= EV_CTS;
if (dwOldLine & MS_RLSD_ON)
dwEvent |= EV_RLSD;
RegisterCommEvent (pContext, dwEvent, 0);
}
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
static int portemu_stack_event (void *pUserContext, int iEvent, void *pEventContext) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_stack_event 0x%08x\n", pUserContext));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_stack_event 0x%08x : not initialized!\n", pUserContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_stack_event 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_stack_event 0x%08x : context not found\n", pUserContext));
gpPORTEMU->Unlock ();
return ERROR_NOT_FOUND;
}
if (iEvent == BTH_STACK_DOWN)
btutil_ScheduleEvent (StackDown, pContext);
else if (iEvent == BTH_STACK_DISCONNECT)
btutil_ScheduleEvent (StackDisconnect, NULL);
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
static int portemu_call_aborted (void *pCallContext, int iError) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_call_aborted 0x%08x\n", pCallContext));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_call_aborted 0x%08x : not initialized!\n", pCallContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_call_aborted 0x%08x: not initialized!\n", pCallContext));
gpPORTEMU->Unlock ();
return 0;
}
ECall *pCall = FindCall (pCallContext);
if (! pCall) {
IFDBG(DebugOut (DEBUG_WARN, L"[PORTEMU] portemu_call_aborted 0x%08x : context does not exist\n", pCallContext));
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
PORTEMU_CONTEXT *pContext = pCall->pContext;
BOOL fSendDisconnect = (pCall->fWhat != RFCOMM_DISC);
DeleteCall (pCall);
CloseConnection (pContext, iError, fSendDisconnect);
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
static int portemu_disconnect_out (void *pCallContext, int iError) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_disconnect_out 0x%08x\n", pCallContext));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_disconnect_out 0x%08x : not initialized!\n", pCallContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_disconnect_out 0x%08x: not initialized!\n", pCallContext));
gpPORTEMU->Unlock ();
return 0;
}
ECall *pCall = FindCall (pCallContext);
if (! pCall) {
IFDBG(DebugOut (DEBUG_WARN, L"[PORTEMU] portemu_disconnect_out 0x%08x : context does not exist\n", pCallContext));
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
PORTEMU_CONTEXT *pContext = pCall->pContext;
DeleteCall (pCall);
CloseConnection (pContext, iError, FALSE);
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
static int portemu_connect_request_out (void *pCallContext, int iError, HANDLE hConnection) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_connect_request_out 0x%08x\n", pCallContext));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_connect_request_out 0x%08x : not initialized!\n", pCallContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_connect_request_out 0x%08x: not initialized!\n", pCallContext));
gpPORTEMU->Unlock ();
return 0;
}
ECall *pCall = FindCall (pCallContext);
if (! pCall) {
IFDBG(DebugOut (DEBUG_WARN, L"[PORTEMU] portemu_connect_request_out 0x%08x : context does not exist\n", pCallContext));
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
PORTEMU_CONTEXT *pContext = pCall->pContext;
SVSUTIL_ASSERT (pCall->fWhat == RFCOMM_CONNECT);
SVSUTIL_ASSERT (pContext->pops && (pContext->pops->op == COMM_OPEN) && (! pContext->pops->pNext)); // MUST have one connection request pops
DeleteCall (pCall);
if (iError != ERROR_SUCCESS)
CloseConnection (pContext, iError, TRUE);
else {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_connect_request_out 0x%08x : connection established\n", pCallContext));
ReinitNewConnection (pContext, hConnection);
PendingIO *pIO = pContext->pops;
pContext->pops = NULL;
SVSUTIL_ASSERT (pIO->op == COMM_OPEN);
SVSUTIL_ASSERT (pIO->pNext == NULL);
SVSUTIL_ASSERT (pIO->buffer == NULL);
SVSUTIL_ASSERT (pIO->cbuffer == 0);
SVSUTIL_ASSERT (pIO->cbuffer_used == 0);
pIO->iIoResult = ERROR_SUCCESS;
SetEvent (pIO->hEvent);
pContext->ucv24out &= ~MSC_FC_BIT;
SendMSC (pContext);
}
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
static int portemu_data_down_out (void *pCallContext, int iError) {
if (! pCallContext) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_data_down_out : ignored empty call!\n"));
return 0;
}
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_data_down_out 0x%08x\n", pCallContext));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_data_down_out 0x%08x : not initialized!\n", pCallContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_data_down_out 0x%08x: not initialized!\n", pCallContext));
gpPORTEMU->Unlock ();
return 0;
}
ECall *pCall = FindCall (pCallContext);
if (! pCall) {
IFDBG(DebugOut (DEBUG_WARN, L"[PORTEMU] portemu_data_down_out 0x%08x : context does not exist\n", pCallContext));
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
PORTEMU_CONTEXT *pContext = pCall->pContext;
int cb = pCall->cBytes;
SVSUTIL_ASSERT (pCall->fWhat == RFCOMM_WRITE);
DeleteCall (pCall);
if (iError != ERROR_SUCCESS)
CloseConnection (pContext, iError, TRUE);
else {
pContext->iSendQuotaUsed -= cb;
if (pContext->iSendQuota < 0) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] quota miscalculated in portemu_data_down_out\n"));
pContext->iSendQuota = 0;
}
SendData (pContext);
}
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
static int portemu_pnreq_out (void *pCallContext, int iError, unsigned char priority, unsigned short n1, int use_credit_fc, int initial_credits) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_pnreq_out 0x%08x mtu = %d credit fc = %x initial credits = %d\n", pCallContext, n1, use_credit_fc, initial_credits));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_pnreq_out 0x%08x : not initialized!\n", pCallContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_pnreq_out 0x%08x: not initialized!\n", pCallContext));
gpPORTEMU->Unlock ();
return 0;
}
ECall *pCall = FindCall (pCallContext);
if (! pCall) {
IFDBG(DebugOut (DEBUG_WARN, L"[PORTEMU] portemu_pnreq_out 0x%08x : context does not exist\n", pCallContext));
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
PORTEMU_CONTEXT *pContext = pCall->pContext;
SVSUTIL_ASSERT (pCall->fWhat == RFCOMM_PN);
SVSUTIL_ASSERT (pContext->pops && (pContext->pops->op == COMM_OPEN) && (! pContext->pops->pNext)); // MUST have one connection request pops
DeleteCall (pCall);
if (use_credit_fc == RFCOMM_PN_CREDIT_OUT) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[PORTEMU] portemu_pnreq_ind 0x%08x CREDIT-based Flow ON\n", pContext));
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", pContext));
pContext->credit_fc = FALSE;
pContext->iHaveCredits = 0;
pContext->iGaveCredits = 0;
}
if ((n1 >= pContext->iMinMTU) && (n1 <= pContext->iMaxMTU)) {
pContext->iMTU = n1;
pContext->pops->iIoResult = ERROR_SUCCESS;
} else
pContext->pops->iIoResult = ERROR_INVALID_DATA;
SVSUTIL_ASSERT (pContext->pops->pNext == NULL);
SVSUTIL_ASSERT (pContext->pops->op == COMM_OPEN);
SetEvent (pContext->pops->hEvent);
pContext->pops = NULL;
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
static int portemu_rpnreq_out (void *pCallContext, int iError, 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_out 0x%08x\n", pCallContext));
if (! gpPORTEMU) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_rpnreq_out 0x%08x : not initialized!\n", pCallContext));
return 0;
}
gpPORTEMU->Lock ();
if (! gpPORTEMU->fInitialized) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PORTEMU] portemu_rpnreq_out 0x%08x: not initialized!\n", pCallContext));
gpPORTEMU->Unlock ();
return 0;
}
ECall *pCall = FindCall (pCallContext);
if (! pCall) {
IFDBG(DebugOut (DEBUG_WARN, L"[PORTEMU] portemu_rpnreq_out 0x%08x : context does not exist\n", pCallContext));
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
SVSUTIL_ASSERT (pCall->fWhat == RFCOMM_RPN);
PORTEMU_CONTEXT *pContext = pCall->pContext;
DeleteCall (pCall);
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;
//#error what's the deal with the rest of the flow???
PendingIO *pio = pContext->pops;
PendingIO *pParent = NULL;
while (pio && (pio->op != COMM_RPN)) {
pParent = pio;
pio = pio->pNext;
}
if (pio) {
if (pParent)
pParent = pio->pNext;
else
pContext->pops = pio->pNext;
pio->iIoResult = ERROR_SUCCESS;
SetEvent (pio->hEvent);
}
gpPORTEMU->Unlock ();
return ERROR_SUCCESS;
}
static int PORTEMUSetPortParams
(
PORTEMU_CONTEXT *pContext,
int channel,
int flocal,
BD_ADDR *pdevice,
int imtu,
int iminmtu,
int imaxmtu,
int isendquo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -