⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfcomm.cxx

📁 三星2440原版bsp
💻 CXX
📖 第 1 页 / 共 5 页
字号:
				}

				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 + -