📄 rfcomm.cxx
字号:
}
if (pDLCI) {
RFCOMM_CONTEXT *pOwner = pDLCI->pOwner;
RFCOMM_PNREQ_Ind pCallback = pOwner->ei.rfcomm_PNREQ_Ind;
void *pUserContext = pOwner->pUserContext;
pOwner->AddRef ();
gpRFCOMM->Unlock ();
int iRes = ERROR_SUCCESS;
__try {
iRes = pCallback (pUserContext, pDLCI, body[2] & 0x3f, (body[5] << 8) | body[4], (body[1] >> 4) & 0xf, body[7] & 0x7);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[RFCOMM] ProcessSignallingData : exception in RFCOMM_PN_Ind\n"));
}
if (iRes != ERROR_SUCCESS)
fError = TRUE;
gpRFCOMM->Lock ();
pOwner->DelRef ();
} else
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : Disconnected or channel not found\n"));
break;
}
case MSG_RPN:
{
IFDBG(DebugOut (DEBUG_RFCOMM_PACKETS, L"ProcessSignallingData : MSG_RPN command arrived...\n"));
if ((cLen != 8) && (cLen != 1)) {
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_RPN command : incorrect length %d (need 8)...\n", cLen));
fError = TRUE;
break;
}
unsigned char body[8];
BufferGetChunk (pBuff, cLen, body);
DLCI *pDLCI = DLCIFromAddress (pSess, body[0]); // Cheat, convert to address...
if (pDLCI) {
RFCOMM_CONTEXT *pOwner = pDLCI->pOwner;
RFCOMM_RPNREQ_Ind pCallback = pOwner->ei.rfcomm_RPNREQ_Ind;
void *pUserContext = pOwner->pUserContext;
pOwner->AddRef ();
gpRFCOMM->Unlock ();
int iRes = ERROR_INTERNAL_ERROR;
__try {
if (cLen == 1)
iRes = pCallback (pUserContext, pDLCI, 0, 0, 0, 0, 0, 0, 0, 0, 0);
else
iRes = pCallback (pUserContext, pDLCI,
(body[7] << 8) | body[6],
ByteToBaud(body[1]),
ByteToData(body[2] & 3),
(body[2] & 4) ? ONE5STOPBITS : ONESTOPBIT,
(body[2] >> 3) & 1,
ByteToPT((body[2] >> 4) & 3),
body[3],
body[4],
body[5]);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[RFCOMM] ProcessSignallingData : exception in rfcomm_RPNREQ_Ind\n"));
}
if (iRes != ERROR_SUCCESS)
fError = TRUE;
gpRFCOMM->Lock ();
pOwner->DelRef ();
} else
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : Disconnected or channel not found\n"));
break;
}
case MSG_NSC: // This IS incorrect - it should have response bit!
case MSG_PSC:
case MSG_SNC:
case MSG_CLD:
default:
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : command 0x%02x type %d not supported!\n", cTypeByte, cType));
fError = TRUE;
}
}
if ((! fError) && (! (cTypeByte & CR_BIT))) { //Response
Task *pTask = NULL;
switch (cType) {
case MSG_PN:
{
IFDBG(DebugOut (DEBUG_RFCOMM_PACKETS, L"ProcessSignallingData : MSG_PN response arrived\n"));
unsigned char body[8];
if ((cLen == 8) && BufferGetChunk (pBuff, 8, body)) {
pTask = GetTaskByResponse (pSess, cType, body[0] << 2);
if (pTask) {
RFCOMM_CONTEXT *pOwner = pTask->pOwner;
void *pContext = pTask->pContext;
RFCOMM_PNREQ_Out pCallback = pOwner->c.rfcomm_PNREQ_Out;
DeleteCall (pTask);
pOwner->AddRef ();
gpRFCOMM->Unlock ();
__try {
pCallback (pContext, ERROR_SUCCESS, body[2] & 0x3f, (body[5] << 8) | body[4], (body[1] >> 4) & 0xf, body[7] & 0x7);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[RFCOMM] ProcessSignallingData : Exception in rfcomm_PNREQ_Out\n"));
}
gpRFCOMM->Lock ();
pOwner->DelRef ();
} else
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_PN response - found no owner, ignoring...\n"));
} else {
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_PN response incorrect\n"));
fError = TRUE;
}
break;
}
case MSG_PSC:
IFDBG(DebugOut (DEBUG_RFCOMM_PACKETS, L"ProcessSignallingData : MSG_PSC response arrived (swallowing)\n"));
break;
case MSG_TEST:
{
IFDBG(DebugOut (DEBUG_RFCOMM_PACKETS, L"ProcessSignallingData : MSG_TEST response arrived\n"));
pTask = GetTaskByResponse (pSess, cType);
if (pTask) {
RFCOMM_CONTEXT *pOwner = pTask->pOwner;
void *pContext = pTask->pContext;
RFCOMM_TEST_Out pCallback = pOwner->c.rfcomm_TEST_Out;
DeleteCall (pTask);
if (pCallback) {
pOwner->AddRef ();
gpRFCOMM->Unlock ();
__try {
pCallback (pContext, ERROR_SUCCESS, cLen, pBuff->pBuffer + pBuff->cStart);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[RFCOMM] ProcessSignallingData : Exception in rfcomm_TEST_Out\n"));
}
gpRFCOMM->Lock ();
pOwner->DelRef ();
}
} else
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_TEST response - found no owner, ignoring...\n"));
break;
}
case MSG_FCON:
case MSG_FCOFF:
{
IFDBG(DebugOut (DEBUG_RFCOMM_PACKETS, L"ProcessSignallingData : MSG_FCON/OFF response arrived\n"));
if (cLen == 0) {
pTask = GetTaskByResponse (pSess, cType);
if (pTask) {
RFCOMM_CONTEXT *pOwner = pTask->pOwner;
void *pContext = pTask->pContext;
RFCOMM_FC_Out pCallback = pOwner->c.rfcomm_FC_Out;
DeleteCall (pTask);
if (pCallback) {
pOwner->AddRef ();
gpRFCOMM->Unlock ();
__try {
pCallback (pContext, ERROR_SUCCESS);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[RFCOMM] ProcessSignallingData : Exception in rfcomm_FC_Out\n"));
}
gpRFCOMM->Lock ();
pOwner->DelRef ();
}
} else
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_FCON/OFF response - found no owner, ignoring...\n"));
} else {
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_FCON/OFF response incorrect\n"));
fError = TRUE;
}
break;
}
case MSG_MSC:
{
IFDBG(DebugOut (DEBUG_RFCOMM_PACKETS, L"ProcessSignallingData : MSG_MSC response arrived\n"));
unsigned char body[3];
if (((cLen == 2) || (cLen == 3)) && BufferGetChunk (pBuff, cLen, body)) {
pTask = GetTaskByResponse (pSess, cType, body[0]);
if (pTask) {
RFCOMM_CONTEXT *pOwner = pTask->pOwner;
void *pContext = pTask->pContext;
RFCOMM_MSC_Out pCallback = pOwner->c.rfcomm_MSC_Out;
DeleteCall (pTask);
if (pCallback) {
pOwner->AddRef ();
gpRFCOMM->Unlock ();
__try {
pCallback (pContext, ERROR_SUCCESS);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[RFCOMM] ProcessSignallingData : Exception in rfcomm_MSC_Out\n"));
}
gpRFCOMM->Lock ();
pOwner->DelRef ();
}
} else
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_MSC response - found no owner, ignoring...\n"));
} else {
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_MSC response incorrect\n"));
fError = TRUE;
}
break;
}
case MSG_NSC:
{
IFDBG(DebugOut (DEBUG_RFCOMM_PACKETS, L"ProcessSignallingData : MSG_NSC response arrived\n"));
if (cLen == 1) {
BufferGetByte (pBuff, &cType);
cType >>= 2;
pTask = GetTaskByResponse (pSess, cType);
if (pTask)
CancelCall (pTask, ERROR_NOT_FOUND, NULL);
else
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_NSC response - found no owner, ignoring...\n"));
} else {
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_NSC response incorrect\n"));
fError = TRUE;
}
break;
}
case MSG_RPN:
{
IFDBG(DebugOut (DEBUG_RFCOMM_PACKETS, L"ProcessSignallingData : MSG_RPN response arrived\n"));
unsigned char body[8];
if (((cLen == 1) || (cLen == 8)) && BufferGetChunk (pBuff, cLen, body)) {
pTask = GetTaskByResponse (pSess, cType, body[0]);
if (pTask) {
RFCOMM_CONTEXT *pOwner = pTask->pOwner;
void *pContext = pTask->pContext;
RFCOMM_RPNREQ_Out pCallback = pOwner->c.rfcomm_RPNREQ_Out;
DeleteCall (pTask);
pOwner->AddRef ();
gpRFCOMM->Unlock ();
__try {
if (cLen == 1)
pCallback (pContext, ERROR_SUCCESS, 0, 0, 0, 0, 0, 0, 0, 0, 0);
else
pCallback (pContext, ERROR_SUCCESS,
(body[7] << 8) | body[6],
ByteToBaud(body[1]),
ByteToData(body[2] & 3),
(body[2] & 4) ? ONE5STOPBITS : ONESTOPBIT,
(body[2] >> 3) & 1,
ByteToPT((body[2] >> 4) & 3),
body[3],
body[4],
body[5]);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[RFCOMM] ProcessSignallingData : Exception in rfcomm_PNREQ_Out\n"));
}
gpRFCOMM->Lock ();
pOwner->DelRef ();
} else
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_RPN response - found no owner, ignoring...\n"));
} else {
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_RPN response incorrect\n"));
fError = TRUE;
}
break;
}
case MSG_RLS:
{
IFDBG(DebugOut (DEBUG_RFCOMM_PACKETS, L"ProcessSignallingData : MSG_RLS response arrived\n"));
unsigned char body[2];
if ((cLen == 2) && BufferGetChunk (pBuff, cLen, body)) {
pTask = GetTaskByResponse (pSess, cType, body[0]);
if (pTask) {
RFCOMM_CONTEXT *pOwner = pTask->pOwner;
void *pContext = pTask->pContext;
RFCOMM_RLS_Out pCallback = pOwner->c.rfcomm_RLS_Out;
DeleteCall (pTask);
if (pCallback) {
pOwner->AddRef ();
gpRFCOMM->Unlock ();
__try {
pCallback (pContext, ERROR_SUCCESS);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[RFCOMM] ProcessSignallingData : Exception in rfcomm_RLS_Out\n"));
}
gpRFCOMM->Lock ();
pOwner->DelRef ();
}
} else
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_RLS response - found no owner, ignoring...\n"));
} else {
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : MSG_RLS response incorrect\n"));
fError = TRUE;
}
break;
}
case MSG_SNC:
case MSG_CLD:
default:
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : response 0x%02x type %d not supported!\n", cTypeByte, cType));
fError = TRUE;
}
}
if (pBuff->pFree)
pBuff->pFree (pBuff);
if ((cTypeByte & CR_BIT) && fError && gpRFCOMM && gpRFCOMM->fConnected && (pSess == VerifyLink (pSess))) { // Send NSC...
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] ProcessSignallingData : command 0x%02x type %d -- processing error condition.\n", cTypeByte, cType));
unsigned char ucCommand[3];
ucCommand[0] = EA_BIT | (MSG_NSC << 2);
ucCommand[1] = EA_BIT | (1 << 1);
ucCommand[2] = cTypeByte;
SendFrame (NULL, pSess->cid, pSess->fIncoming, sizeof(ucCommand), ucCommand);
}
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"[RFCOMM] -ProcessSignallingData\n"));
}
static void ProcessFrame (Session *pSess, TS_FRAME *pFrame) {
IFDBG(DebugOut (DEBUG_RFCOMM_TRACE, L"ProcessFrame %04x%08x ctl 0x%02x addr 0x%02x\n", pSess->b.NAP, pSess->b.SAP, pFrame->h.ucControl, pFrame->h.ucAddress));
SVSUTIL_ASSERT (pSess->fStage >= L2CAPUP);
SVSUTIL_ASSERT (gpRFCOMM->fConnected);
if (pFrame->h.ucControl == (CTL_SABM | CTL_PF)) { // SABM : connect
IFDBG(DebugOut (DEBUG_RFCOMM_PACKETS, L"ProcessFrame : Got SABM\n"));
unsigned char cDLCI = pFrame->h.ucAddress >> 2;
if (cDLCI == 0) { // Start MUX
IFDBG(DebugOut (DEBUG_RFCOMM_PACKETS, L"ProcessFrame : SABM (0) - MUX start\n"));
if ((! pSess->fIncoming) || (pSess->fStage != L2CAPUP)) {
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] SABM(0) out of synch session %04x%08x!\n", pSess->b.NAP, pSess->b.SAP));
RejectFrame (pSess, pFrame);
return;
}
ClearTimeout (pSess);
pSess->fStage |= SABM0UA;
SVSUTIL_ASSERT (pSess->fStage == UP);
SVSUTIL_ASSERT (! pSess->fBusy);
SVSUTIL_ASSERT (! pSess->fWaitAck);
IFDBG(DebugOut (DEBUG_RFCOMM_PACKETS, L"ProcessFrame : responding with UA\n"));
int iRes = SendFrame (NULL, pSess->cid, 0, pSess->fIncoming, CTL_UA);
if ((iRes == ERROR_SUCCESS) && VerifyLink (pSess))
ProcessPendingSignals (pSess);
if ((iRes == ERROR_SUCCESS) && VerifyLink (pSess) && (! pSess->fBusy))
ProcessNextPendingEvent (pSess);
return;
}
SVSUTIL_ASSERT (pSess->fStage == UP);
IFDBG(DebugOut (DEBUG_RFCOMM_PACKETS, L"ProcessFrame : SABM channel = %d\n", pFrame->h.ucAddress >> 3));
if (! IsLocal (pSess, cDLCI)) {
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] trying to SABM non-local channel (0x%02x) session %04x%08x\n", cDLCI, pSess->b.NAP, pSess->b.SAP));
RejectFrame (pSess, pFrame);
return;
}
unsigned char channel = cDLCI >> 1;
DLCI *pDLCI = pSess->pLogLinks;
while (pDLCI && ((! pDLCI->fLocal) || (pDLCI->channel != channel)))
pDLCI = pDLCI->pNext;
if (pDLCI && (pDLCI->fStage != DORMANT)) {
IFDBG(DebugOut (DEBUG_WARN, L"[RFCOMM] dlci 0x%02x session %04x%08x already started!\n", channel, pSess->b.NAP, pSess->b.SAP));
RejectFrame (pSess, pFrame);
return;
}
RFCOMM_CONTEXT *pOwner = pDLCI ? pDLCI->pOwner : NULL;
if (! pOwner) {
pOwner = FindContextByChannel (channel);
if (! pOwner)
pOwner = FindContextForDefault ();
}
int iRes = ERROR_INTERNAL_ERROR;
if (! pDLCI) {
pDLCI = NewLog (pSess, channel, TRUE, pOwner);
if (pDLCI) {
pDLCI->pNext = pSess->pLogLinks;
pSess->pLogLinks = pDLCI;
} else {
IFDBG(DebugOut (DEBUG_ERROR, L"[RFCOMM] ERROR_OUTOFMEMORY in ProcessFrame (channel creation!)\n"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -