www.pudn.com > DMBDRV.rar > SmsGenDrv.c
#include "SmsGenDrv.h" #include#include "BusDrvIf.h" /////////////////////////////////////////////////////////////////////////////// #define ENABLED_DEBUG_ZONE ZONE_ERROR_SET | ZONE_WARNING_SET | ZONE_INIT_SET | ZONE_INFO_SET DBGPARAM dpCurSettings = { TEXT("Siano Generic Driver"), { /* Note: the order of the following must */ /* match the definitions in debug.h: */ TEXT("Errors"), TEXT("Warnings"), TEXT("Init"), TEXT("Info"), TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"), TEXT("Temporary"), TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined") }, ENABLED_DEBUG_ZONE }; /////////////////////////////////////////////////////////////////////////////// // Sms Message Header Structure typedef struct SmsMsgHdr_S { UINT16 msgType; UINT8 msgSrcId; UINT8 msgDstId; UINT16 msgLength; // Length is of the entire message, including header UINT16 msgFlags; } SmsMsgHdr_ST; // Sms Messages #define MSG_SMS_NON_IP_MSG 607 #define MSG_SMS_IP_MSG 699 #define MSG_SMS_RF_TUNE_REQ 561 // A request to tune to a new frequency #define MSG_SMS_RF_TUNE_RES 562 // A request to tune to a new frequency /////////////////////////////////////////////////////////////////////////////// typedef struct AppNameTransltTable_S { TCHAR* AppName; SIANO_APPLICATION_TYPE_E AppType; }AppNameTransltTable_ST; const TCHAR* FwRegistryEntry[] = { /*DVBH , DVBT , TDMB , ISDBT , CMMB*/ /*SDIO Stellar*/ L"DvbhSdioFw", L"DvbtSdioFw", L"TdmbSdioFw" , L"None" , L"None" , /*SPI Stellar*/ L"DvbhSpiFw" , L"DvbtSpiFw" , L"TdmbSpiFw" , L"None" , L"None" , /*HIF Stellar*/ L"DvbhHifFw" , L"DvbtHifFw" , L"TdmbHifFw" , L"None" , L"None" , /*USB Stellar*/ L"DvbhUsbFw" , L"DvbtUsbFw" , L"TdmbUsbFw" , L"None" , L"None" , /*NoLoad */ L"None" , L"None" , L"None" , L"None" , L"None" , /*SDIO Nova*/ L"DvbNovaFw" , L"DvbNovaFw" , L"TdmbNovaFw" , L"IsdbtNovaFw", L"None" , /*SPI Nova*/ L"DvbNovaFw" , L"DvbNovaFw" , L"TdmbNovaFw" , L"IsdbtNovaFw", L"None" , /*HIF Nova*/ L"DvbNovaFw" , L"DvbNovaFw" , L"TdmbNovaFw" , L"IsdbtNovaFw", L"None" , /*USB Nova*/ L"DvbNovaFw" , L"DvbNovaFw" , L"TdmbNovaFw" , L"IsdbtNovaFw", L"None" , NULL}; const AppNameTransltTable_ST AppNameToAppEnumTable[] = {{L"DVBH", SIANO_DVBH}, {L"DVBT", SIANO_DVBT}, {L"TDMB", SIANO_TDMB}, {L"ISDBT", SIANO_ISDBT}, {L"CMMB", SIANO_CMMB}, {NULL, 0}}; /* Supported applications are DVBH, DVBT and TDBM*/ #define NUM_OF_SUPPORTED_APPLICATIONS 5 typedef struct { HANDLE userHandle; BOOL cancelIo; HANDLE hReadEvent; PUCHAR pFileBuffer; ULONG fileBuffSize; ULONG fileWrIdx; ULONG fileRdIdx; ULONG count; HANDLE semRdWr; UINT32 readTimeOut; } FILE_STREAM_PARAMS, *PFILE_STREAM_PARAMS; /*****************************************************************************/ /* The generic device structure */ /*****************************************************************************/ typedef struct SMS_GEN_DEVICE_S { HANDLE hBdDevice; HANDLE OpenCommThread; HANDLE hTuneEvent; BD_TYPE_E BdType; FILE_STREAM_PARAMS fStreams[SIANO_NUM_OF_FILE_STREAMS]; ULONG fStreamHandleCnt; SmsMsgHdr_ST SmsMsgHdr; BOOL MsgHdrReceived; HINSTANCE hNdisDLL; GEN_ReadIpCBFunc pReadIpCBFunc; DWORD hRdIpContext; TCHAR FwFileName[200]; TCHAR activeReg[40]; SIANO_APPLICATION_TYPE_E AppType; BOOL blockIncommingDataPackets; } SMS_GEN_DEVICE_ST, *PSMS_GEN_DEVICE_ST; /* Global pointer to the only gen driver instance */ PSMS_GEN_DEVICE_ST g_pGenDrvInst = NULL; /////////////////////////////////////////////////////////////////////////////// BOOL SGD_Close(DWORD hOpenContext); PFILE_STREAM_PARAMS HandleToFS(PSMS_GEN_DEVICE_ST pGenDrv,HANDLE Handle); void FileBuffAppend(PSMS_GEN_DEVICE_ST pGenDev,SIANO_FILE_STREAM_TYPE_E fsType,PBYTE dataPtr,ULONG len); void BD_ReadCB(DWORD hContext, void* pBuffer, UINT32 BufSize); DWORD OpenCommToBD_Thread(LPVOID lpParam); void LoadMiniport(PSMS_GEN_DEVICE_ST pGenDev); void UnloadMiniport(PSMS_GEN_DEVICE_ST pGenDev); BOOL ChangeApplication(PSMS_GEN_DEVICE_ST pGenDev, SIANO_APPLICATION_TYPE_E AppType); #ifdef DVBT_CHECK_TS_SEQ_NUM UINT16 PidList[100]; UINT8 SeqNumList[100]; UINT8 seq_err_cnt[100]; UINT32 checked_pid_err_cnt = 0; UINT32 dvbt_ts_pkt_cnt = 0; void CheckTSSeqNum(PBYTE pBuff,DWORD buffSize); #endif /////////////////////////////////////////////////////////////////////////////// //define LOG_TO_FILE #define LOG_FILE TEXT("\\GenDrvLog.txt") #define MAX_REG_KEY_SIZE 100 HANDLE hLogFile = INVALID_HANDLE_VALUE; #ifdef LOG_TO_FILE CRITICAL_SECTION g_CriticalSection; VOID LogStrToFile(TCHAR *pLogStr,...) { va_list argumentList; int length; CHAR charBuffer[500]; TCHAR tcharBuffer[500]; DWORD written; INT i; EnterCriticalSection(&g_CriticalSection); va_start(argumentList, pLogStr); do { length = _vsntprintf(tcharBuffer, (500 - 1), pLogStr, argumentList); if (length < 0) { break; } if (hLogFile == INVALID_HANDLE_VALUE) { break; } for (i = 0; i < length; i++) { if ((CHAR)tcharBuffer != '\n') { charBuffer[i] = (CHAR)tcharBuffer[i]; } else { charBuffer[i] = ' '; } } WriteFile(hLogFile,charBuffer,length,&written,NULL); } while (FALSE); va_end(argumentList); LeaveCriticalSection(&g_CriticalSection); } #endif void FlushAllFileBuf(PSMS_GEN_DEVICE_ST pGenDev) { int i; for (i = 1;i < SIANO_NUM_OF_FILE_STREAMS;i++) { WaitForSingleObject(pGenDev->fStreams[i].semRdWr, INFINITE); if (pGenDev->fStreams[i].userHandle != NULL && i != SIANO_CTRL_FILE_STREAM) { pGenDev->fStreams[i].fileWrIdx = 0; pGenDev->fStreams[i].fileRdIdx = 0; pGenDev->fStreams[i].count = 0; } ReleaseSemaphore(pGenDev->fStreams[i].semRdWr,1,NULL); } } /////////////////////////////////////////////////////////////////////////////// BOOL WINAPI DllMain( HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved ) { BOOL bRc = TRUE; UNREFERENCED_PARAMETER(hDllHandle); UNREFERENCED_PARAMETER(lpreserved); switch (dwReason) { case DLL_PROCESS_ATTACH: REGISTERZONES(hDllHandle); // keep file handle open to indicate that the driver is loaded. // on failure, continue without that indication #ifdef LOG_TO_FILE hLogFile = CreateFile(LOG_FILE, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); InitializeCriticalSection(&g_CriticalSection); #endif // RETAILMSG(1, (TEXT("SmsGenDrv: DLL_PROCESS_ATTACH\r\n"))); break; case DLL_PROCESS_DETACH: RETAILMSG(1, (TEXT("SmsGenDrv: DLL_PROCESS_DETACH\r\n"))); if (hLogFile != INVALID_HANDLE_VALUE) { CloseHandle(hLogFile); } #ifdef LOG_TO_FILE DeleteCriticalSection(&g_CriticalSection); #endif break; default: break; } return bRc; } /////////////////////////////////////////////////////////////////////////////// // SGD_Init - the init entry point // Input: dwContext - the context for this init // Output: // Return: returns a non-zero context // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SGD_Init(DWORD dwContext) { PSMS_GEN_DEVICE_ST pGenDev; PWCHAR activeKeyPath = (PWCHAR)dwContext; HKEY regKey; DWORD keyType = 0; DWORD keyDataSize; int i; DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: +SGD_Init\r\n"))); #ifdef DVBT_CHECK_TS_SEQ_NUM for (i = 0;i < 100;i++) { PidList[i] = 0xFFFF; SeqNumList[i] = 0xF; seq_err_cnt[i] = 0; } #endif if (g_pGenDrvInst != NULL) { DBGMSG(ZONE_ERROR, (TEXT("SmsGenDrv: Currently, SmsGenDrv support only one instance\r\n"))); return 0; } /* Allocate the Gen Device */ pGenDev = (PSMS_GEN_DEVICE_ST)LocalAlloc(LPTR, sizeof(SMS_GEN_DEVICE_ST)); if (pGenDev == NULL) { DBGMSG(ZONE_ERROR, (TEXT("SmsGenDrv: Failed to allocate SMS_GEN_DEVICE_ST\r\n"))); return 0; } wcscpy(pGenDev->activeReg, activeKeyPath); pGenDev->hBdDevice = INVALID_HANDLE_VALUE; /* Read ClientInfo key to detect bus driver type */ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,pGenDev->activeReg,0,KEY_READ,®Key) != ERROR_SUCCESS) { DBGMSG(ZONE_ERROR, (TEXT("SmsGenDrv: Failed to open registry for read\r\n"))); LocalFree(pGenDev); return 0; } keyDataSize = sizeof(BD_TYPE_E); if (RegQueryValueEx(regKey,TEXT("ClientInfo"),NULL,&keyType,(LPBYTE)&pGenDev->BdType,&keyDataSize) != ERROR_SUCCESS) { DBGMSG(ZONE_ERROR, (TEXT("SmsGenDrv: Failed to read ClientInfo\r\n"))); LocalFree(pGenDev); return 0; } if (RegCloseKey(regKey) != ERROR_SUCCESS) { DBGMSG(ZONE_ERROR, (TEXT("SmsGenDrv: Failed to close registry\r\n"))); LocalFree(pGenDev); return 0; } switch(pGenDev->BdType) { case BD_TYPE_SDIO_STELLAR: case BD_TYPE_SPI_STELLAR: case BD_TYPE_HIF_STELLAR: case BD_TYPE_SDIO_NOVA: case BD_TYPE_SPI_NOVA: case BD_TYPE_HIF_NOVA: break; case BD_TYPE_USB_STELLAR: case BD_TYPE_USB_FW: case BD_TYPE_USB_NOVA: default: DBGMSG(ZONE_ERROR, (TEXT("SmsGenDrv: Bus driver type not supported\r\n"))); LocalFree(pGenDev); return 0; } for (i = 0; i < SIANO_NUM_OF_FILE_STREAMS; i++) { PFILE_STREAM_PARAMS pfStream = pGenDev->fStreams + i; pfStream->userHandle = NULL; pfStream->cancelIo = FALSE; pfStream->hReadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); pfStream->fileBuffSize = (i == SIANO_CTRL_FILE_STREAM) ? CTRL_FILE_BUFF_SIZE : DATA_FILE_BUFF_SIZE; pfStream->pFileBuffer = NULL; pfStream->semRdWr = CreateSemaphore(NULL,1,1,NULL); } g_pGenDrvInst = pGenDev; pGenDev->hTuneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (pGenDev->hTuneEvent == NULL) { DBGMSG(ZONE_ERROR, (TEXT("SmsGenDrv: Failed to create tune event.\r\n"))); LocalFree(pGenDev); return 0; } pGenDev->OpenCommThread = CreateThread(NULL,0,OpenCommToBD_Thread,(LPVOID)pGenDev,0,NULL); DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: -SGD_Init\r\n"))); return (DWORD)pGenDev; } /////////////////////////////////////////////////////////////////////////////// // SGD_Deinit - the deinit entry point for this driver // Input: hDeviceContext - the context returned from XXX_Init // Output: // Returns: Succeed or Failed // Notes: /////////////////////////////////////////////////////////////////////////////// BOOL SGD_Deinit(DWORD hDeviceContext) { PSMS_GEN_DEVICE_ST pGenDev = (PSMS_GEN_DEVICE_ST)hDeviceContext; int i; DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: +SGD_Deinit\r\n"))); #ifdef DVBT_CHECK_TS_SEQ_NUM for (i = 0;i < 100;i++) { if (PidList[i] == 0xFFFF) break; DBGMSG(ZONE_ERROR, (TEXT("SmsGenDrv: Pid %d Seq %d Errs %d\r\n"),PidList[i],SeqNumList[i],seq_err_cnt[i])); } DBGMSG(ZONE_ERROR, (TEXT("SmsGenDrv: Seq Errors %d from %d\r\n"),checked_pid_err_cnt,dvbt_ts_pkt_cnt)); #endif for (i = 0;i < SIANO_NUM_OF_FILE_STREAMS;i++) { if (pGenDev->fStreams[i].userHandle != NULL) { SGD_Close((DWORD)pGenDev->fStreams[i].userHandle); pGenDev->fStreams[i].userHandle = NULL; } CloseHandle(pGenDev->fStreams[i].hReadEvent); pGenDev->fStreams[i].hReadEvent = NULL; CloseHandle(pGenDev->fStreams[i].semRdWr); pGenDev->fStreams[i].semRdWr = NULL; } if (pGenDev->hBdDevice != INVALID_HANDLE_VALUE) { CloseHandle(pGenDev->hBdDevice); pGenDev->hBdDevice = INVALID_HANDLE_VALUE; } // for protection, if the card was removed before the thread finished if (pGenDev->OpenCommThread != NULL) { WaitForSingleObject(pGenDev->OpenCommThread,2000); } if (pGenDev->hTuneEvent != NULL) { CloseHandle(pGenDev->hTuneEvent); } UnloadMiniport(pGenDev); LocalFree(pGenDev); pGenDev = NULL; g_pGenDrvInst = NULL; DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: -SGD_Deinit\r\n"))); return TRUE; } /////////////////////////////////////////////////////////////////////////////// // SGD_Open - the open entry point // Input: hDeviceContext - the device context from XXX_Init // AccessCode - the desired access // ShareMode - the desired share mode // Output: // Return: returns an open context // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SGD_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode) { PSMS_GEN_DEVICE_ST pGenDev = (PSMS_GEN_DEVICE_ST)hDeviceContext; DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: +SGD_Open\r\n"))); if (pGenDev->hBdDevice == INVALID_HANDLE_VALUE) { // cummunication with bus briver is not ready yet DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: -SGD_Open cummunication with bus briver is not ready yet\r\n"))); return 0; } pGenDev->fStreamHandleCnt++; DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: -SGD_Open fStreamHandleCnt 0x%X\r\n"),pGenDev->fStreamHandleCnt)); return pGenDev->fStreamHandleCnt; } /////////////////////////////////////////////////////////////////////////////// // SGD_Close - the close entry point // Input: hOpenContext - the context returned from XXX_Open // Output: // Return: Succeed or Failed // Notes: /////////////////////////////////////////////////////////////////////////////// BOOL SGD_Close(DWORD hOpenContext) { PSMS_GEN_DEVICE_ST pGenDev = g_pGenDrvInst; PFILE_STREAM_PARAMS fStream = HandleToFS(pGenDev,(HANDLE)hOpenContext); DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: +SGD_Close\r\n"))); pGenDev->fStreamHandleCnt--; if (fStream == NULL) { DBGMSG(1,(TEXT("SmsGenDrv: SGD_Close failed to get fStream\r\n"))); return FALSE; } WaitForSingleObject(fStream->semRdWr, INFINITE); fStream->userHandle = NULL; fStream->fileWrIdx = 0; fStream->fileRdIdx = 0; LocalFree(fStream->pFileBuffer); fStream->pFileBuffer = NULL; fStream->cancelIo = TRUE; SetEvent(fStream->hReadEvent); ReleaseSemaphore(fStream->semRdWr,1,NULL); DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: -SGD_Close\r\n"))); return TRUE; } /////////////////////////////////////////////////////////////////////////////// // SGD_IOControl - the I/O control entry point // Input: Handle - the context returned from XXX_Open // IoctlCode - the ioctl code // pInBuf - the input buffer from the user // InBufSize - the length of the input buffer // pOutBuf - the output buffer from the user // InBufSize - the length of the output buffer // pBytesReturned - the size of the transfer // Output: // Return: Succeed or Failed // Notes: /////////////////////////////////////////////////////////////////////////////// BOOL SGD_IOControl(DWORD Handle, DWORD IoctlCode, PBYTE pInBuf, DWORD InBufSize, PBYTE pOutBuf, DWORD OutBufSize, PDWORD pBytesReturned) { PSMS_GEN_DEVICE_ST pGenDev = g_pGenDrvInst; BOOL retVal = FALSE; PFILE_STREAM_PARAMS fStream = NULL; SIANO_FILE_STREAM_TYPE_E fsType; DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: +SGD_IOControl IoctlCode=0x%x\r\n"), IoctlCode)); switch (IoctlCode) { case SIANO_GEN_IOCTL_SET_FILE_STREAM_TYPE: /* input format : UINT32 - requested file stream type */ DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: SIANO_GEN_IOCTL_SET_FILE_STREAM_TYPE\r\n"))); if ((NULL == pInBuf) || (InBufSize < sizeof(UINT32)) || ((UINT32*)pInBuf)[0] >= SIANO_NUM_OF_FILE_STREAMS || // is valid type pGenDev->fStreams[((UINT32 *)pInBuf)[0]].userHandle != NULL) // is occupied { RETAILMSG(1, (TEXT("SmsGenDrv: SGD_IOControl SET_FILE_STREAM_TYPE failed %d\r\n"),Handle)); break; } fsType = ((UINT32 *)pInBuf)[0]; pGenDev->fStreams[fsType].userHandle = (HANDLE)Handle; pGenDev->fStreams[fsType].pFileBuffer = (PUCHAR) LocalAlloc(LPTR, pGenDev->fStreams[fsType].fileBuffSize); ResetEvent(pGenDev->fStreams[fsType].hReadEvent); pGenDev->fStreams[fsType].cancelIo = FALSE; pGenDev->fStreams[fsType].fileWrIdx = 0; pGenDev->fStreams[fsType].fileRdIdx = 0; pGenDev->fStreams[fsType].count = 0; pGenDev->fStreams[fsType].readTimeOut = INFINITE; retVal = TRUE; break; case SIANO_GEN_IOCTL_SET_READ_TIMEOUT: DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: SIANO_GEN_IOCTL_SET_READ_TIMEOUT\r\n"))); fStream = HandleToFS(pGenDev,(HANDLE)Handle); if (fStream == NULL) { DBGMSG(ZONE_ERROR, (TEXT("SmsGenDrv: SGD_IOControl SIANO_GEN_IOCTL_SET_READ_TIMEOUT failed %d\r\n"),Handle)); break; } fStream->readTimeOut = ((UINT32 *)pInBuf)[0]; retVal = TRUE; break; case SIANO_GEN_IOCTL_CANCEL_IO: /* input format : None */ DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: SIANO_GEN_IOCTL_CANCEL_IO\r\n"))); fStream = HandleToFS(pGenDev,(HANDLE)Handle); if (fStream == NULL) { DBGMSG(ZONE_ERROR, (TEXT("SmsGenDrv: SGD_IOControl IOCTL_CANCEL_IO failed %d\r\n"),Handle)); break; } WaitForSingleObject(fStream->semRdWr, INFINITE); fStream->cancelIo = TRUE; SetEvent(fStream->hReadEvent); ReleaseSemaphore(fStream->semRdWr,1,NULL); RETAILMSG(1, (TEXT("SmsGenDrv: SGD_IOControl user cancel IO\r\n"))); retVal = TRUE; break; case SIANO_GEN_IOCTL_REGISTER_READ_IP_CB: DBGMSG(1, (TEXT("SmsGenDrv: SIANO_GEN_IOCTL_REGISTER_READ_IP_CB\r\n"))); pGenDev->pReadIpCBFunc = ((PGEN_IOCTL_REGISTER_READ_IP_PARAMS_ST)pInBuf)->pReadIpCBFunc; pGenDev->hRdIpContext = ((PGEN_IOCTL_REGISTER_READ_IP_PARAMS_ST)pInBuf)->hContext; retVal = TRUE; break; case SIANO_IOCTL_CHANGE_APPLICATION: if (pGenDev->AppType != *((SIANO_APPLICATION_TYPE_E*)pInBuf)) { retVal = ChangeApplication(pGenDev, *((SIANO_APPLICATION_TYPE_E*)pInBuf)); } else retVal = TRUE; break; case SIANO_GEN_IOCTL_GET_APP_TYPE: DBGMSG(1, (TEXT("SmsGenDrv: SIANO_GEN_IOCTL_GET_APP_TYPE.\r\n"))); if (pOutBuf && OutBufSize >= sizeof(SIANO_APPLICATION_TYPE_E)) { *((SIANO_APPLICATION_TYPE_E*)pOutBuf) = pGenDev->AppType; if (pBytesReturned) *pBytesReturned = sizeof(SIANO_APPLICATION_TYPE_E); retVal = TRUE; } else { if (pBytesReturned) *pBytesReturned = 0; retVal = FALSE; } break; default: DBGMSG(1, (TEXT("SmsGenDrv: Unknown IOCTL 0x%X 0x%X\r\n"),IoctlCode)); break; } DBGMSG(1, (TEXT("SmsGenDrv: -SGD_IOControl. ret %d\r\n"),retVal)); return retVal; } /////////////////////////////////////////////////////////////////////////////// // SGD_Read - the read entry point // Input: hOpenContext - the context from XXX_Open // pBuffer - the user's buffer // Count - the size of the transfer // Output: // Return: (-1) OS will return FALSE in ReadFile // Notes: Not used /////////////////////////////////////////////////////////////////////////////// DWORD SGD_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count) { PSMS_GEN_DEVICE_ST pGenDev = g_pGenDrvInst; PFILE_STREAM_PARAMS fStream = HandleToFS(pGenDev,(HANDLE)hOpenContext); DWORD bytesRead = 0; DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: +SGD_Read\r\n"))); if (fStream == NULL) { RETAILMSG(1,(TEXT("SmsGenDrv: SGD_Read failed to get fStream\r\n"))); return (DWORD)(-1); } if ((pBuffer == NULL) || (Count == 0)) { return (DWORD)(-1); } WaitForSingleObject(fStream->semRdWr, INFINITE); while (fStream->count == 0) { ReleaseSemaphore(fStream->semRdWr,1,NULL); if (WaitForSingleObject(fStream->hReadEvent,fStream->readTimeOut) != WAIT_OBJECT_0) return 0; //No data, timeout on read. WaitForSingleObject(fStream->semRdWr, INFINITE); // check if cancel was request if (fStream->cancelIo == TRUE) { ReleaseSemaphore(fStream->semRdWr,1,NULL); return (DWORD)(-1); // ReadFile will return FALSE } } // limit the read to the bytes in the buffer if (Count > fStream->count) Count = fStream->count; if (Count > (fStream->fileBuffSize - fStream->fileRdIdx)) { bytesRead = (fStream->fileBuffSize - fStream->fileRdIdx); memcpy(pBuffer,fStream->pFileBuffer + fStream->fileRdIdx,bytesRead); memcpy(((LPBYTE)pBuffer) + bytesRead,fStream->pFileBuffer,Count - bytesRead); } else { memcpy(pBuffer,fStream->pFileBuffer + fStream->fileRdIdx,Count); } bytesRead = Count; fStream->count -= Count; fStream->fileRdIdx += bytesRead; if (fStream->fileRdIdx >= fStream->fileBuffSize) fStream->fileRdIdx -= fStream->fileBuffSize; ReleaseSemaphore(fStream->semRdWr,1,NULL); DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: -SGD_Read bytesRead %d\r\n"),bytesRead)); return bytesRead; } /////////////////////////////////////////////////////////////////////////////// // SGD_Write - the write entry point // Input: hOpenContext - the context from XXX_Open // pBuffer - the user's buffer // Count - the size of the transfer // Output: // Return: Number of bytes written. ? indicates failure // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SGD_Write(DWORD hOpenContext, LPCVOID pBuffer, DWORD Count) { SmsMsgHdr_ST* pMsgHdr = (SmsMsgHdr_ST*)pBuffer; PSMS_GEN_DEVICE_ST pGenDev = g_pGenDrvInst; PFILE_STREAM_PARAMS fStream = HandleToFS(pGenDev,(HANDLE)hOpenContext); DWORD bytesWr = 0; DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: +SGD_Write. Count %d\r\n"),Count)); if (pGenDev->hBdDevice == INVALID_HANDLE_VALUE) { RETAILMSG(1,(TEXT("SmsGenDrv: SGD_Write failed. hBdDevice is invalid\r\n"))); return (DWORD)(-1); } if (fStream == NULL) { RETAILMSG(1,(TEXT("SmsGenDrv: SGD_Write failed to get fStream\r\n"))); return (DWORD)(-1); } // RETAILMSG(1, (TEXT("SmsGenDrv: +SGD_Write. msgtype %d\r\n"),pMsgHdr->msgType));@@@@@@@@@ if (pMsgHdr->msgType == MSG_SMS_RF_TUNE_REQ) { //Tuning SMS freq, so SDIO clk need to avoid harmonics on tunes freq. pGenDev->blockIncommingDataPackets = TRUE; FlushAllFileBuf(pGenDev); } if (WriteFile(pGenDev->hBdDevice,pBuffer,Count,&bytesWr,NULL) == FALSE) { RETAILMSG(1,(TEXT("SmsGenDrv: SGD_Write failed to write buffer\r\n"))); return (DWORD)(-1); } if (pMsgHdr->msgType == MSG_SMS_RF_TUNE_REQ) { //Tuning SMS freq, so SDIO clk need to avoid harmonics on tunes freq. WaitForSingleObject(pGenDev->hTuneEvent, 500); pGenDev->blockIncommingDataPackets = FALSE; } if (bytesWr != Count) { RETAILMSG(1, (TEXT("SmsGenDrv: SGD_Write failed to write all bytes. %d != %d\r\n"),Count,bytesWr)); return (DWORD)(-1); } DBGMSG(ZONE_INFO, (TEXT("SmsGenDrv: -SGD_Write\r\n"))); return bytesWr; } /////////////////////////////////////////////////////////////////////////////// // SGD_PowerDown - the power down entry point event from the OS // Input: hDeviceContext - the device context from XXX_Init // Output: // Return: // Notes: /////////////////////////////////////////////////////////////////////////////// void SGD_PowerDown(DWORD hDeviceContext) { return; } /////////////////////////////////////////////////////////////////////////////// // SGD_PowerUp - the power up entry point event from the OS // Input: hDeviceContext - the device context from XXX_Init // Output: // Return: // Notes: /////////////////////////////////////////////////////////////////////////////// void SGD_PowerUp(DWORD hDeviceContext) { return; } /////////////////////////////////////////////////////////////////////////////// // SGD_Seek - the seek entry point // Input: hOpenContext - the context from XXX_Open // Amount - the amount to seek // Type - the type of seek // Output: // Return: (-1) indicates failure // Notes: Not used /////////////////////////////////////////////////////////////////////////////// DWORD SGD_Seek(DWORD hOpenContext, long Amount, DWORD Type) { return (DWORD)(-1); } /////////////////////////////////////////////////////////////////////////////// PFILE_STREAM_PARAMS HandleToFS(PSMS_GEN_DEVICE_ST pGenDrv,HANDLE Handle) { int i; for (i = 0;i < SIANO_NUM_OF_FILE_STREAMS;i++) { if (pGenDrv->fStreams[i].userHandle == Handle) { return &pGenDrv->fStreams[i]; } } return NULL; } /////////////////////////////////////////////////////////////////////////////// void FileBuffAppend(PSMS_GEN_DEVICE_ST pGenDev,SIANO_FILE_STREAM_TYPE_E fsType,PBYTE dataPtr,ULONG len) { ULONG sizeToWr; PFILE_STREAM_PARAMS fStream = &pGenDev->fStreams[fsType]; if (len == 0) { RETAILMSG(1, (TEXT("SmsGenDrv: File stream error: request to append 0 %d\r\n"),fsType)); return; } WaitForSingleObject(fStream->semRdWr, INFINITE); if (fStream->userHandle == NULL) { ReleaseSemaphore(fStream->semRdWr,1,NULL); return; } if (len > (fStream->fileBuffSize - fStream->count)) { RETAILMSG(1, (TEXT("SmsGenDrv: FileBuffAppend - buffer %d is full\r\n"),fsType)); ReleaseSemaphore(fStream->semRdWr,1,NULL); return; } sizeToWr = len; if ((fStream->fileWrIdx + len) > fStream->fileBuffSize) sizeToWr = fStream->fileBuffSize - fStream->fileWrIdx; memcpy(fStream->pFileBuffer + fStream->fileWrIdx,dataPtr,sizeToWr); fStream->fileWrIdx += len; if (fStream->fileWrIdx >= fStream->fileBuffSize) fStream->fileWrIdx -= fStream->fileBuffSize; dataPtr += sizeToWr; sizeToWr = len - sizeToWr; // copy the residual to the start of the buffer if (sizeToWr > 0) { memcpy(fStream->pFileBuffer,dataPtr,sizeToWr); } fStream->count += len; SetEvent(fStream->hReadEvent); ReleaseSemaphore(fStream->semRdWr,1,NULL); } /////////////////////////////////////////////////////////////////////////////// void BD_ReadCB(DWORD hContext, void* pBuffer, UINT32 BufSize) { PSMS_GEN_DEVICE_ST pGenDev = (PSMS_GEN_DEVICE_ST)hContext; SmsMsgHdr_ST* SmsMsgHdrPtr; PBYTE pMsgData; UINT32 msgDataLen; //RETAILMSG(1,(TEXT("SmsGenDrv: +BD_ReadCB\r\n"))); if (pGenDev->MsgHdrReceived == FALSE) { SmsMsgHdrPtr = (SmsMsgHdr_ST*)pBuffer; if (SmsMsgHdrPtr->msgLength > BufSize) { // message is split. NOTE: support only split of header from message data. if (BufSize < sizeof(SmsMsgHdr_ST)) { RETAILMSG(1, (TEXT("SmsGenDrv: Received len less than msg header size %d\r\n"),BufSize)); return; } // keep the header memcpy(&pGenDev->SmsMsgHdr,SmsMsgHdrPtr,sizeof(SmsMsgHdr_ST)); // Exit. The msg data will should be received in the next call to the function pGenDev->MsgHdrReceived = TRUE; return; } else { pMsgData = (PBYTE)(SmsMsgHdrPtr + 1); } } else { SmsMsgHdrPtr = &pGenDev->SmsMsgHdr; pMsgData = pBuffer; } // check msg total length if (pGenDev->MsgHdrReceived) // split { if (SmsMsgHdrPtr->msgLength > (BufSize + sizeof(SmsMsgHdr_ST))) { RETAILMSG(1, (TEXT("SmsGenDrv: Received less than msg len %d > %d (split)\r\n"), SmsMsgHdrPtr->msgLength,(BufSize + sizeof(SmsMsgHdr_ST)))); pGenDev->MsgHdrReceived = FALSE; return; } } else // not split { if (SmsMsgHdrPtr->msgLength > BufSize) { RETAILMSG(1,(TEXT("SmsGenDrv: Received less than msg len %d > %d\r\n"), SmsMsgHdrPtr->msgLength,BufSize)); return; } } msgDataLen = SmsMsgHdrPtr->msgLength - sizeof(SmsMsgHdr_ST); //RETAILMSG(1,(TEXT("SmsGenDrv: Received msg - MsgType %d SrcId %X DstId %X Len %d Flags %X Size %d bufSize %d\r\n"), // SmsMsgHdrPtr->msgType,SmsMsgHdrPtr->msgSrcId,SmsMsgHdrPtr->msgDstId, // SmsMsgHdrPtr->msgLength,SmsMsgHdrPtr->msgFlags,msgDataLen,BufSize)); switch (SmsMsgHdrPtr->msgType) { case MSG_SMS_IP_MSG: if (pGenDev->pReadIpCBFunc) { if (!pGenDev->blockIncommingDataPackets) { pGenDev->pReadIpCBFunc(pGenDev->hRdIpContext,pMsgData,msgDataLen); } } else { RETAILMSG(1, (TEXT("SmsGenDrv: No ReadIpCB to accept IP msg\r\n"))); } break; case MSG_SMS_NON_IP_MSG: case 729: if (SmsMsgHdrPtr->msgDstId >= SIANO_MIN_DATA_FILE_STREAM && SmsMsgHdrPtr->msgDstId <= SIANO_MAX_DATA_FILE_STREAM) { if (!pGenDev->blockIncommingDataPackets) { #ifdef DVBT_CHECK_TS_SEQ_NUM CheckTSSeqNum(pMsgData,msgDataLen); #endif FileBuffAppend(pGenDev,(SIANO_FILE_STREAM_TYPE_E)SmsMsgHdrPtr->msgDstId,pMsgData,msgDataLen); } } else { RETAILMSG(1,(TEXT("SmsGenDrv: FileBuffAppend : request to append to unknow file stream %d\r\n"), SmsMsgHdrPtr->msgDstId)); } break; case MSG_SMS_RF_TUNE_RES: SetEvent(pGenDev->hTuneEvent); default: // control message if (pGenDev->MsgHdrReceived) // split { FileBuffAppend(pGenDev,SIANO_CTRL_FILE_STREAM,(PBYTE)SmsMsgHdrPtr,sizeof(SmsMsgHdr_ST)); FileBuffAppend(pGenDev,SIANO_CTRL_FILE_STREAM,pMsgData,msgDataLen); //RETAILMSG(1,(TEXT("SmsGenDrv: -BD_ReadCB:control message split\r\n")));@@@@@@@@@ } else // non split { FileBuffAppend(pGenDev,SIANO_CTRL_FILE_STREAM,(PBYTE)SmsMsgHdrPtr,SmsMsgHdrPtr->msgLength); //RETAILMSG(1,(TEXT("SmsGenDrv: -BD_ReadCB:control message non split\r\n")));@@@@@@@@@@@ } break; } pGenDev->MsgHdrReceived = FALSE; // turn off the flag for next message // RETAILMSG(1,(TEXT("SmsGenDrv: -BD_ReadCB\r\n")));@@@@@@@@@@@ } /////////////////////////////////////////////////////////////////////////////// static BOOL genGetRegistrySettings(PSMS_GEN_DEVICE_ST pGenDev) { TCHAR* regKey; BOOL st; HKEY hKey; DWORD dataSize, type, idx; TCHAR AppName[10]; SIANO_APPLICATION_TYPE_E AppType; RETAILMSG(1, (TEXT("SmsGenDrv: +genGetRegistrySettings.\r\n"))); regKey = (TCHAR *)LocalAlloc (LPTR, MAX_REG_KEY_SIZE); if (regKey == NULL) { RETAILMSG(1, (TEXT("SmsGenDrv: Allocating memory for registry reading failed.\r\n"))); return FALSE; } st = RegOpenKeyEx(HKEY_LOCAL_MACHINE, pGenDev->activeReg, 0, 0, &hKey); if(st != ERROR_SUCCESS) { RETAILMSG(1, (TEXT("SmsGenDrv: Could not open active registry key.\r\n"))); LocalFree(regKey); return (FALSE); } dataSize=MAX_REG_KEY_SIZE; st = RegQueryValueEx( hKey, TEXT("Key"), NULL, &type, (LPBYTE)regKey, &dataSize); RegCloseKey(hKey); if(st!=ERROR_SUCCESS) { RETAILMSG(1, (TEXT("SmsGenDrv: Could not get registry key name.\r\n"))); LocalFree(regKey); return (FALSE); } // Now - read all the needed parameters for the driver from the registry. st = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regKey, 0, 0, &hKey); if(st != ERROR_SUCCESS) { RETAILMSG(1, (TEXT("SmsGenDrv: Could not open registry key.\r\n"))); LocalFree(regKey); return (FALSE); } // Read the current mdtv application. /* dataSize=sizeof(AppName); st = RegQueryValueEx( hKey, L"Application", 0, &type, (LPBYTE)&AppName, &dataSize); */ wcscpy(AppName,AppNameToAppEnumTable[2].AppName); for (idx = 0; AppName[idx] != 0 && idx < sizeof(AppName)/2; idx++) AppName[idx] = towupper(AppName[idx]); //Translate the application string into Enum for (idx = 0; AppNameToAppEnumTable[idx].AppName != NULL; idx++) { if (wcscmp(AppName, AppNameToAppEnumTable[idx].AppName) == 0) { AppType = AppNameToAppEnumTable[idx].AppType; break; } } pGenDev->AppType = AppType; // According to Enum and Application - find the Fw file name. idx = pGenDev->BdType * NUM_OF_SUPPORTED_APPLICATIONS + AppType; RETAILMSG(1, (TEXT("SmsGenDrv: Chosen application is %s, RegistryIdx=%d.\r\n"), AppName, idx)); // Read Fw fileName from registry. dataSize=sizeof(pGenDev->FwFileName); st = RegQueryValueEx( hKey, FwRegistryEntry[idx], 0, &type, (LPBYTE)&pGenDev->FwFileName, &dataSize); RETAILMSG(1, (TEXT("SmsGenDrv: Firmware file name is :%s.\r\n"), pGenDev->FwFileName)); LocalFree(regKey); return (TRUE); } /////////////////////////////////////////////////////////////////////////////// BOOL DownloadCardFw(PSMS_GEN_DEVICE_ST pGenDev) { FILE* pf; BOOL found; DWORD fileSize; PBYTE pBuff; found = FALSE; /* Read the registry again to make sure we download the current required FW */ genGetRegistrySettings(pGenDev); /* read inp to memory */ if (pGenDev->FwFileName[0] == 0) { RETAILMSG(1, (TEXT("SmsGenDrv: FW Download failed since FW filename is unknown.\r\n"))); return FALSE; } DBGMSG(1, (TEXT("SmsGenDrv: download FW :%s\r\n"),pGenDev->FwFileName)); pf = _wfopen(pGenDev->FwFileName,TEXT("rb")); if (pf == NULL) { // error open file // MessageBox(NULL,TEXT("Error reading inp file!"),TEXT("Siano Error"),MB_OK); RETAILMSG(1, (TEXT("Error reading inp file!\r\n"))); return FALSE; } fseek(pf,0,SEEK_END); fileSize = ftell(pf); fseek(pf,0,SEEK_SET); pBuff = (PBYTE)LocalAlloc(LPTR, fileSize); if (fread(pBuff,1,fileSize,pf) == fileSize) DBGMSG(1,(TEXT("SmsGenDrv: download file size: %d\r\n"),fileSize)); else DBGMSG(1,(TEXT("SmsGenDrv: fread faild. err %d\r\n"),GetLastError())); fclose(pf); /* write FW buffer to the card */ if (DeviceIoControl(pGenDev->hBdDevice ,SIANO_BD_IOCTL_WRITE_FW_BUFF_TO_DEVICE,pBuff,fileSize, NULL,0,NULL,NULL) == FALSE) { RETAILMSG(1,(TEXT("SmsGenDrv: Failed to download FW. Error %d\r\n"), GetLastError())); return FALSE; } LocalFree(pBuff); return TRUE; } /////////////////////////////////////////////////////////////////////////////// BOOL ChangeApplication(PSMS_GEN_DEVICE_ST pGenDev, SIANO_APPLICATION_TYPE_E AppType) { TCHAR* regKey; BOOL st; HKEY hKey; DWORD dataSize, type; char msg[] = {0xb9, 0x02, 0x96, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; RETAILMSG(1,(TEXT("SmsGenDrv: +genGetRegistrySettings.\r\n"))); regKey = (TCHAR *)LocalAlloc (LPTR, MAX_REG_KEY_SIZE); if (regKey == NULL) { RETAILMSG(1,(TEXT("SmsGenDrv: Allocating memory for registry reading failed.\r\n"))); return FALSE; } st = RegOpenKeyEx(HKEY_LOCAL_MACHINE, pGenDev->activeReg, 0, 0, &hKey); if(st != ERROR_SUCCESS) { RETAILMSG(1,(TEXT("SmsGenDrv: Could not open active registry key.\r\n"))); LocalFree(regKey); return (FALSE); } dataSize=MAX_REG_KEY_SIZE; st = RegQueryValueEx(hKey, TEXT("Key"), NULL, &type, (LPBYTE)regKey, &dataSize); RegCloseKey(hKey); if(st!=ERROR_SUCCESS) { RETAILMSG(1,(TEXT("SmsGenDrv: Could not get registry key name.\r\n"))); LocalFree(regKey); return (FALSE); } // Now - read all the needed parameters for the driver from the registry. st = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regKey, 0, 0, &hKey); if(st != ERROR_SUCCESS) { RETAILMSG(1,(TEXT("SmsGenDrv: Could not open registry key.\r\n"))); LocalFree(regKey); return (FALSE); } st = RegSetValueEx( hKey, L"Application", 0, REG_SZ, (LPBYTE)AppNameToAppEnumTable[AppType].AppName, sizeof(AppNameToAppEnumTable[AppType].AppName) * 2); if(st != ERROR_SUCCESS) { RETAILMSG(1,(TEXT("SmsGenDrv: Could not Change registry key.\r\n"))); LocalFree(regKey); RegCloseKey(hKey); return (FALSE); } st = RegFlushKey(hKey); if(st != ERROR_SUCCESS) { RETAILMSG(1,(TEXT("SmsGenDrv: Could not Change registry key.\r\n"))); LocalFree(regKey); RegCloseKey(hKey); return (FALSE); } RegCloseKey(hKey); /*Reset the device in order to return it to the ROM*/ if (WriteFile(pGenDev->hBdDevice,msg,sizeof(msg),&dataSize,NULL) == FALSE) { DBGMSG(ZONE_ERROR, (TEXT("SmsGenDrv: ChangeApplication failed to send reset.\r\n"))); return (DWORD)(-1); } Sleep (3000); /* Re-Download The FW*/ st = DownloadCardFw(pGenDev); Sleep (100); return st; } /////////////////////////////////////////////////////////////////////////////// DWORD OpenCommToBD_Thread(LPVOID lpParam) { HANDLE hBdFile; BD_IOCTL_REGISTER_READ_PARAMS_ST readParams; PSMS_GEN_DEVICE_ST pGenDev = (PSMS_GEN_DEVICE_ST)lpParam; UINT32 retryCnt = 0; _TCHAR bdName[10]; RETAILMSG(1, (TEXT("SmsGenDrv: +OpenCommToBD_Thread\r\n"))); switch(pGenDev->BdType) { case BD_TYPE_SDIO_STELLAR: case BD_TYPE_SDIO_NOVA: wcscpy(bdName,SIANO_SDIO_PREFIX); break; case BD_TYPE_SPI_STELLAR: case BD_TYPE_SPI_NOVA: wcscpy(bdName,SIANO_SPI_PREFIX); break; case BD_TYPE_HIF_STELLAR: case BD_TYPE_HIF_NOVA: wcscpy(bdName,SIANO_HIF_PREFIX); break; } wcscat(bdName,TEXT("1:")); // for now, support only one device /* open communication to bus driver. try up to three times to assure that the bus driver finish its XXX_Init */ RETAILMSG(1, (TEXT("SmsGenDrv: open communication to %s\r\n"),bdName)); do { retryCnt++; hBdFile = CreateFile(bdName,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); if (hBdFile == INVALID_HANDLE_VALUE) { RETAILMSG(1, (TEXT("SmsGenDrv: Failed to open connection to the bus driver. Try % d Error %d\r\n"), retryCnt,GetLastError())); if (retryCnt == 3) { RETAILMSG(1, (TEXT("SmsGenDrv: Stop trying to open connection to the bus driver.\r\n"))); return 1; } Sleep(100); continue; } break; } while (TRUE); readParams.pBD_ReadCBFunc = BD_ReadCB; readParams.hContext = (DWORD)pGenDev; if (DeviceIoControl(hBdFile,SIANO_BD_IOCTL_REGISTER_READ_CB,&readParams,sizeof(readParams), NULL,0,NULL,NULL) == FALSE) { RETAILMSG(1, (TEXT("SmsGenDrv: Failed to register read callback in the bus driver. Error %d\r\n"), GetLastError())); CloseHandle(hBdFile); return 1; } pGenDev->hBdDevice = hBdFile; /////////////////// if (DownloadCardFw(pGenDev) == FALSE) { pGenDev->hBdDevice = NULL; CloseHandle(hBdFile); return 1; } pGenDev->OpenCommThread = NULL; LoadMiniport(pGenDev); RETAILMSG(1, (TEXT("SmsGenDrv: -OpenCommToBD_Thread\r\n"))); return 0; } /////////////////////////////////////////////////////////////////////////////// void LoadMiniport(PSMS_GEN_DEVICE_ST pGenDev) { NDIS_STATUS ndisStatus; VOID (*pNdisRegisterAdapter)(PNDIS_STATUS, PWSTR,PWSTR); pGenDev->hNdisDLL = LoadLibrary(TEXT("Ndis.dll")); if (pGenDev->hNdisDLL == NULL) { return; } pNdisRegisterAdapter = (VOID (*)(PNDIS_STATUS, PWSTR,PWSTR))GetProcAddress( pGenDev->hNdisDLL,TEXT("NdisRegisterAdapter")); if (pNdisRegisterAdapter == NULL) { RETAILMSG(1, (TEXT("SmsGenDrv: Failed to get NdisRegisterAdapter proc address\r\n"))); FreeLibrary(pGenDev->hNdisDLL); pGenDev->hNdisDLL = NULL; return; } pNdisRegisterAdapter(&ndisStatus,TEXT("SmsNdis"),TEXT("SmsNdis1")); if(ndisStatus != STATUS_SUCCESS) { RETAILMSG(1, (TEXT("SmsGenDrv: Failed to register miniport adapter. status 0x%X\r\n"),ndisStatus)); FreeLibrary(pGenDev->hNdisDLL); pGenDev->hNdisDLL = NULL; return; } RETAILMSG(1, (TEXT("SmsGenDrv: Miniport loaded successfully\r\n"))); } /////////////////////////////////////////////////////////////////////////////// void UnloadMiniport(PSMS_GEN_DEVICE_ST pGenDev) { NDIS_STATUS ndisStatus; VOID (*pNdisDeregisterAdapter)(PNDIS_STATUS, PWSTR); if (pGenDev->hNdisDLL) { pNdisDeregisterAdapter = (VOID (*)(PNDIS_STATUS, PWSTR))GetProcAddress(pGenDev->hNdisDLL,TEXT("NdisDeregisterAdapter")); if (pNdisDeregisterAdapter) { pNdisDeregisterAdapter(&ndisStatus,TEXT("SmsNdis1")); if(ndisStatus != STATUS_SUCCESS) { RETAILMSG(1,(TEXT("SmsGenDrv: Failed to deregister miniport adapter. status %d\r\n"),ndisStatus)); } } else { RETAILMSG(1,(TEXT("SmsGenDrv: Failed to get NdisDeregisterAdapter proc address\r\n"))); } FreeLibrary(pGenDev->hNdisDLL); pGenDev->hNdisDLL = NULL; RETAILMSG(1,(TEXT("SmsGenDrv: Miniport unloaded successfully\r\n"))); } } /////////////////////////////////////////////////////////////////////////////// #ifdef DVBT_CHECK_TS_SEQ_NUM void CheckTSSeqNum(PBYTE pBuff,DWORD buffSize) { int i; UINT16 pid; UINT8 seq_num; PBYTE pTS = pBuff; while (pTS < (pBuff + buffSize)) { dvbt_ts_pkt_cnt++; if (pTS[0] != 0x47) { checked_pid_err_cnt+=1000; pTS += 188; continue; } pid = ((pTS[1] << 8) + pTS[2]) & 0x1FFF; seq_num = pTS[3] & 0xF; if (pid == 0x1FFF) { // skip null packets pTS += 188; continue; } // search if pid exist for (i = 0;i < 100;i++) { if (PidList[i] == 0xFFFF || pid == PidList[i]) { break; } } if (i == 100) { // more than 100 pids pTS += 188; continue; } if (PidList[i] == 0xFFFF) { // pid not exist in the list, add it PidList[i] = pid; SeqNumList[i] = seq_num; seq_err_cnt[i] = 0; } else { // check seq num if (((SeqNumList[i] + 1) & 0xF) != seq_num) { // error checked_pid_err_cnt++; seq_err_cnt[i]++; DBGMSG(ZONE_ERROR, (TEXT("SmsGenDrv: TS Seq Err. %d Prev %d Cur %d\r\n") ,pid,SeqNumList[i],seq_num)); //MessageBeep(0xFFFFFFFF); } SeqNumList[i] = seq_num; } pTS += 188; } } #endif