📄 ecostestdownloadfilter.cpp
字号:
switch (buf[i] & 0xff)
{
case '$':
case '#':
case 0x7d:
/* These must be escaped */
escaped++;
*p++ = 0x7d;
*p++ = (unsigned char) ((buf[i] & 0xff) ^ 0x20);
break;
default:
*p++ = (unsigned char) (buf[i] & 0xff);
break;
}
}
if (i < todo)
{
/* Escape chars have filled up the buffer prematurely,
and we have actually sent fewer bytes than planned.
Fix-up the length field of the packet. */
/* FIXME: will fail if new len is a shorter string than
old len. */
plen += hexnumstr (plen, i);
*plen++ = ':';
}
// Calculate checksum
p2 = (unsigned char*)buf2.Data();
p2++; // skip $
csum = 0;
while (p2 < p)
csum = (unsigned char)(csum + *p2++);
*p++ = '#';
*p++ = (unsigned char) tohex ((csum >> 4) & 0xf);
*p++ = (unsigned char) tohex (csum & 0xf);
/* Send it over and over until we get a positive ack. */
int resend = 1;
const unsigned char* write_ptr = (const unsigned char*) buf2.Data();
int write_len = (int)p-(int)buf2.Data();
while (resend)
{
unsigned int __written;
Trace("Sending bytes for %p-%p\n", dl_address, dl_address+i);
TargetWrite(serial, write_ptr, write_len);
/* read until either a timeout occurs (-2) or '+' is read */
for(;;)
{
unsigned int __read;
serial.Read(&ch, 1, __read);
if (0 == __read) {
tcount ++;
if (tcount > 3) {
Trace("Timeout in putpkt_binary\n");
return 0;
}
break; /* Retransmit buffer */
}
switch (ch)
{
case '+':
// Now expect OK packet from target
unsigned char ok_msg[6];// $OK#9a
serial.Read(ok_msg, 6, __read);
// Reply with ACK
serial.Write((void*)"+", 1, __written);
// And process next packet.
resend = 0;
break;
case '-':
// Bad packet CRC. Retransmit.
Trace ("Bad CRC\n");
break;
default:
Trace("Got junk..%02x\n", ch);
continue; // keep reading
}
break; /* Here to retransmit */
}
}
len -= i;
dl_address += i;
buf += i;
}
return 1;
}
bool CALLBACK
DownloadFilterFunction(void*& pBuf,
unsigned int& nRead,
CeCosSerial& serial,
CeCosSocket& socket,
void* pParem)
{
CeCosTestDownloadFilter* p = (CeCosTestDownloadFilter*) pParem;
bool res = false;
try {
res = p->FilterFunctionProper(pBuf, nRead, serial, socket);
}
catch (LPCTSTR s) {
TRACE(_T("Download filter caught string: %s\n"), s);
}
catch (...) {
TRACE(_T("Download filter caught unknown exception\n"));
}
return res;
}
bool
CeCosTestDownloadFilter::FilterFunctionProper(void*& pBuf,
unsigned int& nRead,
CeCosSerial& serial,
CeCosSocket& socket)
{
char* buffer = (char*) pBuf;
// Assume the worst - don't allow session to continue until a successful
// download.
m_bContinueSession = false;
// Output the serial data if option enabled
if (m_bOptSerDebug)
PrintHex((unsigned char*) buffer, nRead);
// Stop here if in NULL-filter mode
if (m_bNullFilter)
return true;
// Command handling.
// Be strict here; very first byte we see must be the start marker,
// else go into NULL-filter mode
unsigned int i = 0;
if (!m_bCmdFlag) {
if ('@' != buffer[i]) {
m_bNullFilter = true;
return true;
}
m_bCmdFlag = true;
}
// If reading a command, look for the end marker.
if (m_bCmdFlag) {
char c = 0;
while (i < nRead && m_nCmdIndex < MAX_CMD_LEN) {
c = buffer[i++];
m_aCmd[m_nCmdIndex++] = c;
if ('!' == c) {
if (i != nRead) {
throw _T("Extra bytes after command packet!?!");
}
}
}
if (MAX_CMD_LEN == m_nCmdIndex) {
Trace("Received too long command. Ignoring it!\n");
m_nCmdIndex = 0;
m_bCmdFlag = false;
} else if ('!' == c) {
// Was the command completed?
m_aCmd[m_nCmdIndex - 1] = 0;// terminate cmd
m_nCmdIndex = 0;
m_bCmdFlag = false;
// command now in m_aCmd[]
Trace("Got command %s\n", m_aCmd);
// After this, never interfere.
m_bNullFilter = true;
// Get arguments: @<length>:<dl_address>:<start_address>!
int length, packet_size;
unsigned long dl_addr, start_addr;
INIT_VALUE(&m_aCmd[1]);
SET_VALUE(int, length);
SET_VALUE(unsigned long, dl_addr);
SET_VALUE(unsigned long, start_addr);
SET_VALUE(int, packet_size);
Trace("len %d, dl %08x, start %08x, packet_size %d\n",
length, dl_addr, start_addr, packet_size);
// Reply so host will send file.
socket.send("@", 1);
// Read file from host
Buffer buf(length);
if (socket.recv(buf.Data(), length)) {
// Remember old blocking state, and set serial to
// blocking reads.
bool __blocking = serial.GetBlockingReads();
serial.SetBlockingReads(true);
serial.Flush();
// Send + to target, acking whatever packet was pending
unsigned int __written = 0;
serial.Write((void*)"+", 1, __written);
// Convert to packets and transfer to target.
if (put_binary((unsigned char*) buf.Data(),
length, dl_addr, packet_size, serial)) {
// Send detach signal to target
unsigned char ch;
unsigned int __read;
serial.Write((void*)"$D#44", 5, __written);
serial.Read(&ch, 1, __read);
// Reply to host marking end of download
socket.send("+", 1);
// Let server know it's OK to accept another connection
// in this session.
m_bContinueSession = true;
} else {
// Reply to host marking failed download
socket.send("-", 1);
}
// Reset previous blocking mode
serial.SetBlockingReads(__blocking);
} else {
// Reply to host marking failed file transfer
socket.send("?", 1);
}
}
nRead = 0; // Never leave anything for caller
// This is a violation of the intended
// filter function behavior.
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -