//--------------------------------------------------------------------------------------------------------- // PUCHAR pRxBuffer 临时数据缓存区的空闲空间的起始地址 // ULONG *pBufflen 临时数据缓存区的空闲空间的剩余长度的指针 //--------------------------------------------------------------------------------------------------------- BOOL SerialDataIn::ReceiveInterruptHandler(PUCHAR pRxBuffer,ULONG *pBufflen)
{
Lock();
BOOL bReturn = FALSE;
if (pRxBuffer && pBufflen && *pBufflen) {
DWORD dwBufferSize = *pBufflen ;
*pBufflen = 0 ;
if ( IsFrontArmedTransferComplete () ) { // 上一次数据处理完成的判断
if (m_dwSegDataDataLen[m_dwCurIndex] == 0) { // Have't update the Transfer Status yet.
DWORD dwClientInfo = GetClientInfo();
ASSERT((dwClientInfo & SERIAL_DATAIN_COOKIE_MASK)== SERIAL_DATAIN_COOKIE); // 检验数据包传输的连续性
ASSERT(m_dwCurIndex == (dwClientInfo & (~SERIAL_DATAIN_COOKIE_MASK)));
m_dwCurIndex =(dwClientInfo & (~SERIAL_DATAIN_COOKIE_MASK));
DWORD dwError = USB_NO_ERROR;
DWORD dwLength; // 检测这次数据传输是否正确
if (GetFrontArmedTransferStatus(&dwLength, &dwError) && dwError == USB_NO_ERROR) { // Complete with no error.
m_dwSegDataOffset[m_dwCurIndex] = 0; // 获取这一次数据传输的长度,保存在m_dwSegDataDataLen[m_dwCurIndex]。‘ // 个人感觉应该不会出现 dwLength > m_dwSegmentSize 的情况吧?
m_dwSegDataDataLen[m_dwCurIndex] = min(dwLength,m_dwSegmentSize); // 这一次循环需要拷贝的数据的长度
DWORD dwCopyLength = min(m_dwSegDataDataLen[m_dwCurIndex],dwBufferSize);
memcpy(pRxBuffer,m_VirtualAddress + m_dwSegmentSize*m_dwCurIndex ,dwCopyLength); // 保存当前已经拷贝数据的长度 m_dwSegDataOffset[m_dwCurIndex]。
m_dwSegDataOffset[m_dwCurIndex] = dwCopyLength; // 返回这一数据拷贝的长度。这就是为什么这个数据要以指针传入的原因。
*pBufflen = dwCopyLength;
bReturn = TRUE;
DEBUGMSG(ZONE_READ,(TEXT("ReceiveInterruptHandler:%d Copied ,Transfer Size=%d"),dwCopyLength,dwLength));
}
else {
DEBUGMSG(ZONE_ERROR,(TEXT("ReceiveInterruptHandler:Transfer Error %d ,dwLength=%d"),dwError,dwLength));
}
}
// 进入这个if的情况是 m_dwSegDataDataLen[m_dwCurIndex] > dwBufferSize // 但是我觉得进入这种情况下,数据处理就出错了啊! // 首先, dwBufferSize 在上面的情况中没有做相应的处理,这个时候已经没有代表正确的值了。 // 其次, *pBufflen = dwCopyLen 这个语句也不对了,应该是*pBufflen += dwCopyLen;
if (m_dwSegDataOffset[m_dwCurIndex] < m_dwSegDataDataLen[m_dwCurIndex] ){ // We have Extra.
DWORD dwCopyLen = min (dwBufferSize, m_dwSegDataDataLen[m_dwCurIndex] - m_dwSegDataOffset[m_dwCurIndex]) ;
memcpy(pRxBuffer,m_VirtualAddress + (m_dwSegmentSize*m_dwCurIndex + m_dwSegDataOffset[m_dwCurIndex]) ,dwCopyLen);
*pBufflen = dwCopyLen;
m_dwSegDataOffset[m_dwCurIndex] += m_dwSegDataOffset[m_dwCurIndex];
bReturn = TRUE;
}
if (m_dwSegDataOffset[m_dwCurIndex]>= m_dwSegDataDataLen[m_dwCurIndex] ){
CloseFrontArmedTransfer();
m_dwSegDataOffset[m_dwCurIndex]= m_dwSegDataDataLen[m_dwCurIndex] = 0 ;
BOOL bResult = BulkOrIntrTransfer(USB_NO_WAIT|USB_SHORT_TRANSFER_OK,
m_dwSegmentSize,
m_VirtualAddress+ (m_dwCurIndex * m_dwSegmentSize),
m_PhysicalAddress.LowPart+(m_dwCurIndex*m_dwSegmentSize),
SERIAL_DATAIN_COOKIE+m_dwCurIndex);
ASSERT(bResult==TRUE);
m_dwCurIndex ++;
if (m_dwCurIndex>=NUM_OF_IN_TRANSFER)
m_dwCurIndex = 0;
}
}
}
Unlock();
return bReturn;
}
|