// TestBoost.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "stdio.h"
#include <afx.h>
#include <WinSock2.h>
#include "StringUtil.h"
#include <string>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/regex.hpp>
wchar_t g_szSourceFile[256];
wchar_t g_szDestFile[256];
//////////////////////////////////////////////////////////////////////////
//
// serial port test
typedef boost::system::error_code boost_error_code;
typedef boost::asio::deadline_timer asio_timer;
typedef boost::asio::serial_port asio_serial;
//////////////////////////////////////////////////////////////////////////
static std::string FileEncodePath(const wchar_t* fs)
{
CW2A aFullPath(fs);
char buffer[1024];
char temptxt[4];
std::string retstr;
int num;
num = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, aFullPath, -1,
(wchar_t *) buffer, sizeof(buffer)/2);
num--; // not count the null
for (int i=0; i<num*2; i++) //fill data
{
if ((i%2)==0)
*((wchar_t*)&(buffer[i])) = htons(*((wchar_t*) &(buffer[i])));
ZeroMemory(temptxt, sizeof(temptxt));
sprintf(temptxt, "%02X", (unsigned char) buffer[i]);
retstr += temptxt;
}
return retstr;
}
static bool check_buffer(boost::asio::streambuf& buf)
{
std::istream is(&buf);
is.unsetf(std::ios_base::skipws);
std::string sz;
sz.append(std::istream_iterator<char>(is), std::istream_iterator<char>());
std::cout << sz;
return (sz.find("\r\nOK\r\n") != -1);
}
static bool send_command(boost::shared_ptr<asio_serial> sp, const char* cmd)
{
boost::regex reg_util("\r\nOK\r\n|\r\nERROR\r\n");
boost::asio::streambuf sbuf;
boost::asio::write(*sp, boost::asio::buffer(cmd, strlen(cmd)));
boost::asio::read_until(*sp, sbuf, reg_util);
return check_buffer(sbuf);
}
#define BLOCK_SIZE 400
// 下载文件实现方式:
static void UploadFile(boost::shared_ptr<asio_serial> sp)
{
// AT+EFSW=0 //create file
// AT+EFSW=2 //write file
// AT+EFSW=1 //close file
std::string strCommand;
CFile fileInput;
std::string strName;
// 切换
strCommand = "AT+ESUO=3\r";
printf("AT+ESUO=3\n");
if (!send_command(sp, strCommand.c_str()))
return;
strCommand = "AT+EFSR\r";
printf("AT+EFSR\n");
if (!send_command(sp, strCommand.c_str()))
goto ESUO;
strCommand = "AT+ESUO=4\r";
printf("AT+ESUO=4\n");
if (!send_command(sp, strCommand.c_str()))
return;
strCommand = "AT+ESLP=0\r";
printf("AT+ESLP=0\n");
if (!send_command(sp, strCommand.c_str()))
goto ESUO;
strCommand = "AT+ESUO=3\r";
printf("AT+ESUO=3\n");
if (!send_command(sp, strCommand.c_str()))
return;
// 创建文件
strName = FileEncodePath(g_szDestFile);
String::format(strCommand, "AT+EFSW=0,\"%s\"\r", strName.c_str());
printf("AT+EFSW=0\n");
if (!send_command(sp, strCommand.c_str()))
goto ESUO;
//写文件
fileInput.Open(g_szSourceFile, CFile::modeRead);
BYTE bufferInput[BLOCK_SIZE];
int nReaded = 0;
while ((nReaded = fileInput.Read(bufferInput, BLOCK_SIZE)) > 0)
{
if (nReaded == BLOCK_SIZE)
{
String::format(strCommand, "AT+EFSW=2, 0, %d, \"", BLOCK_SIZE);
}
else
{
String::format(strCommand, "AT+EFSW=2, 1, %d, \"", nReaded);
}
char tmp[16];
for (int i=0; i<nReaded; i++)
{
sprintf(tmp, "%02X", bufferInput[i]);
strCommand.append(tmp);
}
strCommand.append("\"\r");
if (!send_command(sp, strCommand.c_str()))
{
fileInput.Close();
goto ESUO;
}
double dPos = fileInput.GetPosition();
double dTotal = fileInput.GetLength();
double dPercent = 100 * dPos / dTotal;
printf("percent: %02d\n", (int)dPercent);
}
fileInput.Close();
// 关闭文件
printf("AT+EFSW=1\n");
String::format(strCommand, "AT+EFSW=1,\"%s\"\r", strName.c_str());
send_command(sp, strCommand.c_str());
ESUO:
// 切换回来
printf("AT+ESUO=4\n");
strCommand = "AT+ESUO=4\r";
send_command(sp, strCommand.c_str());
}
//////////////////////////////////////////////////////////////////////////
void handle_read(boost::shared_ptr<boost::asio::streambuf> pbuf,
boost_error_code ec,
std::size_t bytes_transferred,
boost::shared_ptr<asio_timer> t)
{
printf("length readed:%d\n", bytes_transferred);
std::istream is(pbuf.get());
is.unsetf(std::ios_base::skipws);
std::string sz;
sz.append(std::istream_iterator<char>(is), std::istream_iterator<char>());
std::cout << sz;
t->cancel();
}
void handle_wait(boost_error_code& error,
boost::shared_ptr<asio_serial> sp)
{
if (error != boost::asio::error::operation_aborted)
{
//printf("serial port timeout, cancel it\n");
sp->cancel();
}
else
{
//printf("wait has been canceled\n");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
if (argc != 4)
{
std::cout << "upload file to mobile" << std::endl
<< "usage TestBoost <com port> <local file> <mobile file>"
<< std::endl;
return 1;
}
boost::asio::io_service iosev;
// 串口COM1, Linux下为“/dev/ttyS0”
char com[32];
int nComPort = _ttoi(argv[1]);
_tcscpy(g_szSourceFile, argv[2]);
_tcscpy(g_szDestFile, argv[3]);
sprintf(com, "COM%d", nComPort);
boost::shared_ptr<asio_serial> sp(new asio_serial(iosev, com));
// 设置参数
sp->set_option(asio_serial::baud_rate(115200));
sp->set_option(asio_serial::flow_control(asio_serial::flow_control::none));
sp->set_option(asio_serial::parity(asio_serial::parity::none));
sp->set_option(asio_serial::stop_bits(asio_serial::stop_bits::one));
sp->set_option(asio_serial::character_size(8));
/*long t1 = GetTickCount();
for (int i=0; i<1; i++)
{
char* b1 = "AT+CPBR=1\r";
// 向串口写数据
boost::asio::write(*sp, boost::asio::buffer(b1, strlen(b1)));
boost::shared_ptr<asio_timer> t(
new asio_timer(iosev));
t->expires_from_now(boost::posix_time::millisec(3000));
// 向串口读数据
boost::shared_ptr<boost::asio::streambuf> pbuf(new boost::asio::streambuf());
//boost::asio::async_read(*sp, boost::asio::buffer(buf),
// boost::bind(handle_read, buf, _1, _2));
//sp->async_read_some(boost::asio::buffer(buf),
// boost::bind(handle_read, buf, _1, _2, t));
boost::asio::async_read_until(*sp, *pbuf,
boost::regex("\r\nOK\r\n|\r\nERROR\r\n|\r\n>\r\n"),
boost::bind(handle_read, pbuf, _1, _2, t));
t->async_wait(boost::bind(handle_wait, _1, sp));
size_t m = iosev.run();
//printf("#%d run result %d\n", i, m);
iosev.reset();
}
long t2 = GetTickCount();
printf("\r\n\r\ntotal used %d\n", t2-t1);*/
UploadFile(sp);
sp->close();
return 0;
}