- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试使用 C++ 代码将 AT 命令发送到通过 USB 连接的调制解调器。我正在使用“AT+MDN”进行测试,它在这个特定的调制解调器上返回其电话号码,并且在通过连接到其串行端口的 Putty 进行测试时正常工作。 GetComPort 确定调制解调器连接到的 com 端口号并为其创建句柄。 sendCommand() 方法打开端口、发送命令、刷新缓冲区然后尝试读取结果但只接收回发送的命令,因此在本例中它接收到“AT+MDN”。我尝试了我能找到的针对此问题的所有各种修复方法(刷新缓冲区,在写入和读取之间添加休眠)但没有一个奏效。
串行ATDT.cpp
#include "SerialATDT.h"
#include "EventSem.h"
#include "Traces.h"
#include <setupapi.h>
#include <devguid.h>
#include <regstr.h>
SerialATDT::SerialATDT(String ident) : mComPortIdentifier(ident)
{
}
SerialATDT::~SerialATDT(void)
{
}
String SerialATDT::getComPortId()
{
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
int devOffset = 0;
DWORD propertyDataType;
HKEY devKey;
DWORD portNameSize;
DWORD result;
String comPort = "";
BYTE friendlyName[4096];
TCHAR devName[4096];
TCHAR portName[4096];
// Create a HDEVINFO with all present devices.
hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_MODEM, 0, 0, DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE)
{
TRACE_L(TEXT("\nSetupDiGetClassDevs() failed: %d\n"), GetLastError());
return "";
}
// Enumerate through all devices in Set.
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
while (SetupDiEnumDeviceInfo(hDevInfo, devOffset++, &DeviceInfoData))
{
if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME,
&propertyDataType, friendlyName, sizeof(friendlyName), NULL))
{
TRACE_L(TEXT("\nSetupDiEnumDeviceInfo() failed: %d\n"), GetLastError());
continue;
}
// Look for identifying info in the name
if ( mComPortIdentifier.size() > 0 ) {
const char *temp = strstr((const char*)friendlyName, mComPortIdentifier.c_str());
if ( temp == 0 ) {
continue;
}
}
// Get the device name.
if (!SetupDiGetDeviceInstanceId(hDevInfo, &DeviceInfoData, devName, MAX_PATH, NULL))
{
TRACE_L(TEXT("\nSetupDiGetDeviceInstanceId() failed: %d\n"), GetLastError());
continue;
}
// Open the registry key associated with the device.
devKey = SetupDiOpenDevRegKey(hDevInfo, &DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
if (devKey == INVALID_HANDLE_VALUE)
{
TRACE_L(TEXT("\nSetupDiOpenDevRegKey() failed: %d\n"), GetLastError());
continue;
}
// Read the PortName registry key.
portNameSize = sizeof(portName);
result = RegQueryValueEx(devKey, TEXT("PortName"), NULL, NULL, (LPBYTE) portName, &portNameSize);
if(result != ERROR_SUCCESS)
{
TRACE_L(TEXT("\nRegQueryValueEx() failed: %d\n"), result);
continue;
}
// We are not guaranteed a null terminated string from RegQueryValueEx, so explicitly NULL-terminate it.
portName[portNameSize / sizeof(TCHAR)] = TEXT('\0');
// Close the registry key.
result = RegCloseKey(devKey);
if (result != ERROR_SUCCESS)
{
TRACE_L(TEXT("\nRegCloseKey() failed: %d\n"), result);
continue;
}
// Try to open the COM port.
comPort = portName;
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return comPort;
}
bool SerialATDT::getComPort(HANDLE *hFile)
{
String comPort = getComPortId();
*hFile = INVALID_HANDLE_VALUE;
if ( comPort.size() > 0 ) {
String comPortStr;
comPortStr.Format("\\\\.\\%s", comPort.c_str());
*hFile = ::CreateFile( comPortStr.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL );
if ( *hFile == INVALID_HANDLE_VALUE ) {
TRACE_L("AT file open error %ld", GetLastError());
}
}
return *hFile != INVALID_HANDLE_VALUE;
}
bool SerialATDT::sendCommand(String command, String &response)
{
bool retFlag = true;
HANDLE hFile = NULL;
response = "";
if ( !getComPort(&hFile) ) {
TRACE("SerialATDT-Unable to get comport");
return false;
}
::SetupComm( hFile, 2048, 2048 );
DCB dcb = { 0 };
dcb.DCBlength = sizeof(DCB);
::GetCommState( hFile, &dcb );
dcb.BaudRate = 9600;
// set additional parameters for 8-bit, no parity, one stop bit, no flow control
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
::SetCommState( hFile, &dcb );
// Retrieve the timeout parameters for all read and write operations on the port.
COMMTIMEOUTS CommTimeouts;
::GetCommTimeouts (hFile, &CommTimeouts);
#define BUFFER_LENGTH 256
// Change the COMMTIMEOUTS structure settings.
CommTimeouts.ReadIntervalTimeout = 50;
CommTimeouts.ReadTotalTimeoutMultiplier = (2000/BUFFER_LENGTH); // Only wait 2 seconds (2000ms).
CommTimeouts.ReadTotalTimeoutConstant = 50;
CommTimeouts.WriteTotalTimeoutMultiplier = 50;
CommTimeouts.WriteTotalTimeoutConstant = 50;
// Set the timeout parameters for all read and write operations on the port.
::SetCommTimeouts (hFile, &CommTimeouts);
char buffer[BUFFER_LENGTH+1];
OVERLAPPED m_ReadSync;
unsigned error = 0;
EventSem readWait;
bool finished = false;
memset(&m_ReadSync, 0, sizeof(OVERLAPPED));
m_ReadSync.hEvent = readWait.GetHandle();
m_ReadSync.Pointer = (void*)buffer;
static int index = 0;
// Edited here
command += "\r";
// First write the command out to the serial port
UInt32 numBytesWritten = 0;
UInt32 totalBytesWritten = 0;
do {
if ( !::WriteFile(hFile, command.c_str(), command.length(), &numBytesWritten, NULL) ) {
TRACE("SerialATDT-sendCommand failed on sending.");
retFlag = false;
break;
}
totalBytesWritten += numBytesWritten;
} while (totalBytesWritten < command.length() );
::FlushFileBuffers(hFile);
// Read in the response
if ( retFlag ) {
Sleep(1000);
while ( !finished ) {
UInt32 numBytesRead = 0;
buffer[0] = '\0';
if ( !::ReadFile(hFile, buffer, BUFFER_LENGTH, &numBytesRead, &m_ReadSync ) )
{
if ( ( error = ::GetLastError() ) == ERROR_IO_PENDING )
{
error = 0;
if ( !::GetOverlappedResult( hFile, &m_ReadSync, &numBytesRead, true ) )
{
error = ::GetLastError();
}
}
}
// We read something
if ( numBytesRead > 0 ) {
buffer[numBytesRead] = '\0';
response += buffer;
} else { // We timed out so just drop out
finished = true;
}
}
}
// Remove the command from what we read in the response
if ( response.find(command) != std::string::npos ) {
response = response.substr(command.length());
}
if ( hFile != INVALID_HANDLE_VALUE ) {
::CloseHandle( hFile );
}
return retFlag;
}
和SerialATDT.h
#ifndef SERIALATDT_H
#define SERIALATDT_H
#pragma once
#include "SgiString.h"
#include "FileSystem.h"
using namespace sgi;
class SerialATDT
{
private:
String mComPortIdentifier;
bool getComPort(HANDLE *hFile);
String getComPortId();
public:
SerialATDT(String ident);
~SerialATDT(void);
bool sendCommand(String command, String &response);
};
#endif
最佳答案
当您取回写入的字符串时,这可能是调制解调器有意回显(这是您可以查看在 Putty 中键入的内容的一种方式)。你试过再读一遍吗?另外,您是否检查过写入字符串上的不同行结尾。有些调制解调器只需要一个换行符“\n”,有些则需要一个回车换行符“\r\n”。如果没有正确的行结尾,调制解调器可能不会执行您的 AT 命令。
关于c++ - WriteFile 到调制解调器后的 ReadFile 仅返回通过 WriteFile 发送的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14989283/
我正在尝试使用 C++ 代码将 AT 命令发送到通过 USB 连接的调制解调器。我正在使用“AT+MDN”进行测试,它在这个特定的调制解调器上返回其电话号码,并且在通过连接到其串行端口的 Putty
为了测试并确保我已经把所有东西都放下了,以便以后可以开始扩展,我正在尝试创建一个文件句柄,将给定的字节缓冲区写入该文件句柄,然后读取部分该文件放入新的测试缓冲区。 我有代码: const size_t
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我正在设计一个将时间序列数据写入文件的系统。数据是 8 字节的 block ,分为两个 4 字节的部分:时间和负载。 根据 MSDN,如果写入的数据大小小于一个扇区,则 WriteFile 函数是原子
我不知道如何在 JSON 文件上写入。我正在开发一个单一应用程序页面,主要使用 AngularJS 和 Node.js 这是我的代码: --index.html-- ... --a
作为学习练习,我正在编写一个在运行时输出 DLL 的程序。 我已经编写了 PE header ,并使用 WriteFile 成功将 DOS header 、NT header 、可选节 header
我正在尝试将参数发送到我的arduino。所以我编写了这段代码: #include #include #include #include HANDLE serialPortHandler;
代码: #include #include #include #include HANDLE creatFile(void); long WriteBuffer(HANDLE); char *
一般来说,我是 node.js 和 javascript 的新手,但我无法理解为什么 writeFile 函数正在写入一个空白文件。我认为 for 循环应该是一个 Promise,但我不确定如何编写它
我正在尝试使用 WriteFile 函数将 wstring 写入 UTF-8 文件。我希望文件包含这些字符“ÑÁ”,但我得到的是“�”。 这是代码 #include #include #inclu
嘿,我的 write 和 readFile 方法有问题。这些方法不做任何事情。该方法应该将动态数组的元素写入名为 C++ 的文件中。然后对于读取文件,该方法应该读取 ArrayList 的元素。 这是
我正在尝试将文件从资源复制到 %localappdata%。我有这样的东西: HINSTANCE hInstance = GetModuleHandle(NULL); HANDLE hFile = I
我正在尝试写入文本文件。我可以写入控制台,但是无法写入文本文件。我注意到的一件事是,如果我只是打印到控制台,则 String data 不包含任何数据,这可能就是我的文本文件中没有出现任何内容的原因。
我遇到了一个很奇怪的问题。 我正在连接到 Xbox 360 上的 Winsock 功能,发送。在我试图从中转储 Http 请求信息的应用程序中多次调用此函数。 首先我将展示代码并解释我的问题: Wri
我正在编写一个 activex 控件,它将访问并行端口并将字节写入其中。我能够成功打开端口,但是当我写入时它卡在 WriteFile 函数上。我在这里错过了什么吗?我正在使用 Windows 7 HA
我正在尝试将 16 字节数据写入串行端口,但我无法将值转换为 lpcvoid,这是我的代码, unsigned char Buffer[16]; for (int i=0; i<16; i++
我想写入一个随机输出,其中STD_OUTPUT_FILE即可。我想用WriteFile,但是好像什么都没写。 HANDLE outH = GetStdHandle ( STD_OUTPUT_HANDL
我正在尝试移植一些使用 read() 和 write() 函数发送套接字的 C。我正在尝试将其移植到 Windows,建议(根据我所阅读的内容)使用 WriteFile 和 ReadFile 来完成我
我正在尝试将 unsigned short 和 unsigned char 数组内容写入 .img 文件。我正在使用 WriteFile 方法来做同样的事情。似乎 WriteFile 函数成功地将数组
我想创建一个包含一些文本的简单文本文件。 import java.io.*; class TextFileWriter{ public static void writeTextFile(String
我是一名优秀的程序员,十分优秀!