Line 1... |
Line 1... |
// $Id: RlinkPort.cpp 492 2013-02-24 22:14:47Z mueller $
|
// $Id: RlinkPort.cpp 611 2014-12-10 23:23:58Z mueller $
|
//
|
//
|
// Copyright 2011-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
// Copyright 2011-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
//
|
//
|
// This program is free software; you may redistribute and/or modify it under
|
// This program is free software; you may redistribute and/or modify it under
|
// the terms of the GNU General Public License as published by the Free
|
// the terms of the GNU General Public License as published by the Free
|
// Software Foundation, either version 2, or at your option any later version.
|
// Software Foundation, either version 2, or at your option any later version.
|
//
|
//
|
Line 11... |
Line 11... |
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// for complete details.
|
// for complete details.
|
//
|
//
|
// Revision History:
|
// Revision History:
|
// Date Rev Version Comment
|
// Date Rev Version Comment
|
|
// 2014-12-10 611 1.2.4 add time stamps for Read/Write for logs
|
|
// 2014-11-29 607 1.2.3 BUGFIX: fix time handling on RawRead()
|
|
// 2014-11-23 606 1.2.2 use Rtools::TimeOfDayAsDouble()
|
|
// 2014-08-22 584 1.2.1 use nullptr
|
// 2013-02-23 492 1.2 use RparseUrl
|
// 2013-02-23 492 1.2 use RparseUrl
|
// 2013-02-22 491 1.1 use new RlogFile/RlogMsg interfaces
|
// 2013-02-22 491 1.1 use new RlogFile/RlogMsg interfaces
|
// 2013-02-10 485 1.0.5 add static const defs
|
// 2013-02-10 485 1.0.5 add static const defs
|
// 2013-02-03 481 1.0.4 use Rexception
|
// 2013-02-03 481 1.0.4 use Rexception
|
// 2013-01-27 477 1.0.3 add RawRead(),RawWrite() methods
|
// 2013-01-27 477 1.0.3 add RawRead(),RawWrite() methods
|
Line 24... |
Line 28... |
// 2011-01-15 356 0.1 First draft
|
// 2011-01-15 356 0.1 First draft
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
/*!
|
/*!
|
\file
|
\file
|
\version $Id: RlinkPort.cpp 492 2013-02-24 22:14:47Z mueller $
|
\version $Id: RlinkPort.cpp 611 2014-12-10 23:23:58Z mueller $
|
\brief Implemenation of RlinkPort.
|
\brief Implemenation of RlinkPort.
|
*/
|
*/
|
|
|
#include <errno.h>
|
#include <errno.h>
|
#include <unistd.h>
|
#include <unistd.h>
|
#include <poll.h>
|
#include <poll.h>
|
#include <sys/time.h>
|
|
|
|
#include <iostream>
|
#include <iostream>
|
|
|
#include "librtools/RosFill.hpp"
|
#include "librtools/RosFill.hpp"
|
#include "librtools/RosPrintf.hpp"
|
#include "librtools/RosPrintf.hpp"
|
#include "librtools/RosPrintBvi.hpp"
|
#include "librtools/RosPrintBvi.hpp"
|
#include "librtools/Rexception.hpp"
|
#include "librtools/Rexception.hpp"
|
#include "librtools/RlogMsg.hpp"
|
#include "librtools/RlogMsg.hpp"
|
|
#include "librtools/Rtools.hpp"
|
|
|
#include "RlinkPort.hpp"
|
#include "RlinkPort.hpp"
|
|
|
using namespace std;
|
using namespace std;
|
|
|
Line 70... |
Line 74... |
fUrl(),
|
fUrl(),
|
fFdRead(-1),
|
fFdRead(-1),
|
fFdWrite(-1),
|
fFdWrite(-1),
|
fspLog(),
|
fspLog(),
|
fTraceLevel(0),
|
fTraceLevel(0),
|
|
fTsLastRead(-1.),
|
|
fTsLastWrite(-1.),
|
fStats()
|
fStats()
|
{
|
{
|
fStats.Define(kStatNPortWrite, "NPortWrite", "Port::Write() calls");
|
fStats.Define(kStatNPortWrite, "NPortWrite", "Port::Write() calls");
|
fStats.Define(kStatNPortRead, "NPortRead", "Port::Read() calls");
|
fStats.Define(kStatNPortRead, "NPortRead", "Port::Read() calls");
|
fStats.Define(kStatNPortTxByt, "NPortTxByt", "Port Tx bytes send");
|
fStats.Define(kStatNPortTxByt, "NPortTxByt", "Port Tx bytes send");
|
Line 113... |
Line 119... |
int RlinkPort::Read(uint8_t* buf, size_t size, double timeout, RerrMsg& emsg)
|
int RlinkPort::Read(uint8_t* buf, size_t size, double timeout, RerrMsg& emsg)
|
{
|
{
|
if (!IsOpen())
|
if (!IsOpen())
|
throw Rexception("RlinkPort::Read()","Bad state: port not open");
|
throw Rexception("RlinkPort::Read()","Bad state: port not open");
|
if (buf == 0)
|
if (buf == 0)
|
throw Rexception("RlinkPort::Read()","Bad args: buf==NULL");
|
throw Rexception("RlinkPort::Read()","Bad args: buf==nullptr");
|
if (size == 0)
|
if (size == 0)
|
throw Rexception("RlinkPort::Read()","Bad args: size==0");
|
throw Rexception("RlinkPort::Read()","Bad args: size==0");
|
|
|
fStats.Inc(kStatNPortRead);
|
fStats.Inc(kStatNPortRead);
|
|
|
bool rdpoll = PollRead(timeout);
|
bool rdpoll = PollRead(timeout);
|
if (!rdpoll) return kTout;
|
if (!rdpoll) return kTout;
|
|
|
int irc = -1;
|
int irc = -1;
|
while (irc < 0) {
|
while (irc < 0) {
|
irc = read(fFdRead, (void*) buf, size);
|
irc = ::read(fFdRead, (void*) buf, size);
|
if (irc < 0 && errno != EINTR) {
|
if (irc < 0 && errno != EINTR) {
|
emsg.InitErrno("RlinkPort::Read()", "read() failed : ", errno);
|
emsg.InitErrno("RlinkPort::Read()", "read() failed : ", errno);
|
if (fspLog && fTraceLevel>0) fspLog->Write(emsg.Message(), 'E');
|
if (fspLog && fTraceLevel>0) fspLog->Write(emsg.Message(), 'E');
|
return kErr;
|
return kErr;
|
}
|
}
|
}
|
}
|
|
|
if (fspLog && fTraceLevel>0) {
|
if (fspLog && fTraceLevel>0) {
|
RlogMsg lmsg(*fspLog, 'I');
|
RlogMsg lmsg(*fspLog, 'I');
|
lmsg << "port read nchar=" << RosPrintf(irc,"d",4);
|
lmsg << "port read nchar=" << RosPrintf(irc,"d",4);
|
|
double now = Rtools::TimeOfDayAsDouble();
|
|
if (fTsLastRead > 0.)
|
|
lmsg << " dt_rd=" << RosPrintf(now-fTsLastRead,"f",8,6);
|
|
if (fTsLastWrite > 0.)
|
|
lmsg << " dt_wr=" << RosPrintf(now-fTsLastWrite,"f",8,6);
|
|
fTsLastRead = now;
|
if (fTraceLevel>1) {
|
if (fTraceLevel>1) {
|
size_t ncol = (80-5-6)/(2+1);
|
size_t ncol = (80-5-6)/(2+1);
|
for (int i=0; i<irc; i++) {
|
for (int i=0; i<irc; i++) {
|
if ((i%ncol)==0) lmsg << "\n " << RosPrintf(i,"d",4) << ": ";
|
if ((i%ncol)==0) lmsg << "\n " << RosPrintf(i,"d",4) << ": ";
|
lmsg << RosPrintBvi(buf[i],16) << " ";
|
lmsg << RosPrintBvi(buf[i],16) << " ";
|
Line 157... |
Line 169... |
int RlinkPort::Write(const uint8_t* buf, size_t size, RerrMsg& emsg)
|
int RlinkPort::Write(const uint8_t* buf, size_t size, RerrMsg& emsg)
|
{
|
{
|
if (!IsOpen())
|
if (!IsOpen())
|
throw Rexception("RlinkPort::Write()","Bad state: port not open");
|
throw Rexception("RlinkPort::Write()","Bad state: port not open");
|
if (buf == 0)
|
if (buf == 0)
|
throw Rexception("RlinkPort::Write()","Bad args: buf==NULL");
|
throw Rexception("RlinkPort::Write()","Bad args: buf==nullptr");
|
if (size == 0)
|
if (size == 0)
|
throw Rexception("RlinkPort::Write()","Bad args: size==0");
|
throw Rexception("RlinkPort::Write()","Bad args: size==0");
|
|
|
fStats.Inc(kStatNPortWrite);
|
fStats.Inc(kStatNPortWrite);
|
|
|
if (fspLog && fTraceLevel>0) {
|
if (fspLog && fTraceLevel>0) {
|
RlogMsg lmsg(*fspLog, 'I');
|
RlogMsg lmsg(*fspLog, 'I');
|
lmsg << "port write nchar=" << RosPrintf(size,"d",4);
|
lmsg << "port write nchar=" << RosPrintf(size,"d",4);
|
|
double now = Rtools::TimeOfDayAsDouble();
|
|
if (fTsLastRead > 0.)
|
|
lmsg << " dt_rd=" << RosPrintf(now-fTsLastRead,"f",8,6);
|
|
if (fTsLastWrite > 0.)
|
|
lmsg << " dt_wr=" << RosPrintf(now-fTsLastWrite,"f",8,6);
|
|
fTsLastWrite = now;
|
if (fTraceLevel>1) {
|
if (fTraceLevel>1) {
|
size_t ncol = (80-5-6)/(2+1);
|
size_t ncol = (80-5-6)/(2+1);
|
for (size_t i=0; i<size; i++) {
|
for (size_t i=0; i<size; i++) {
|
if ((i%ncol)==0) lmsg << "\n " << RosPrintf(i,"d",4) << ": ";
|
if ((i%ncol)==0) lmsg << "\n " << RosPrintf(i,"d",4) << ": ";
|
lmsg << RosPrintBvi(buf[i],16) << " ";
|
lmsg << RosPrintBvi(buf[i],16) << " ";
|
Line 179... |
Line 197... |
|
|
size_t ndone = 0;
|
size_t ndone = 0;
|
while (ndone < size) {
|
while (ndone < size) {
|
int irc = -1;
|
int irc = -1;
|
while (irc < 0) {
|
while (irc < 0) {
|
irc = write(fFdWrite, (void*) (buf+ndone), size-ndone);
|
irc = ::write(fFdWrite, (void*) (buf+ndone), size-ndone);
|
if (irc < 0 && errno != EINTR) {
|
if (irc < 0 && errno != EINTR) {
|
emsg.InitErrno("RlinkPort::Write()", "write() failed : ", errno);
|
emsg.InitErrno("RlinkPort::Write()", "write() failed : ", errno);
|
if (fspLog && fTraceLevel>0) fspLog->Write(emsg.Message(), 'E');
|
if (fspLog && fTraceLevel>0) fspLog->Write(emsg.Message(), 'E');
|
return kErr;
|
return kErr;
|
}
|
}
|
Line 214... |
Line 232... |
0}}; // revents
|
0}}; // revents
|
|
|
|
|
int irc = -1;
|
int irc = -1;
|
while (irc < 0) {
|
while (irc < 0) {
|
irc = poll(fds, 1, ito);
|
irc = ::poll(fds, 1, ito);
|
if (irc < 0 && errno != EINTR)
|
if (irc < 0 && errno != EINTR)
|
throw Rexception("RlinkPort::PollRead()","poll() failed: rc<0: ", errno);
|
throw Rexception("RlinkPort::PollRead()","poll() failed: rc<0: ", errno);
|
}
|
}
|
|
|
if (irc == 0) return false;
|
if (irc == 0) return false;
|
Line 240... |
Line 258... |
throw Rexception("RlinkPort::RawRead()", "Bad args: size <= 0");
|
throw Rexception("RlinkPort::RawRead()", "Bad args: size <= 0");
|
|
|
fStats.Inc(kStatNPortRawRead);
|
fStats.Inc(kStatNPortRawRead);
|
tused = 0.;
|
tused = 0.;
|
|
|
struct timeval tval;
|
double tnow = Rtools::TimeOfDayAsDouble();
|
gettimeofday(&tval, 0);
|
double tend = tnow + timeout;
|
double tbeg = double(tval.tv_sec) + 1.e-6*double(tval.tv_usec);
|
double tbeg = tnow;
|
double trest = timeout;
|
|
|
|
size_t ndone = 0;
|
size_t ndone = 0;
|
while (trest>0. && ndone<size) {
|
while (tnow < tend && ndone<size) {
|
int irc = Read(buf+ndone, size-ndone, trest, emsg);
|
int irc = Read(buf+ndone, size-ndone, tend-tnow, emsg);
|
gettimeofday(&tval, 0);
|
tnow = Rtools::TimeOfDayAsDouble();
|
double tend = double(tval.tv_sec) + 1.e-6*double(tval.tv_usec);
|
tused = tnow - tbeg;
|
tused = tend - tbeg;
|
|
if (irc <= 0) return irc;
|
if (irc <= 0) return irc;
|
if (!exactsize) break;
|
if (!exactsize) break;
|
|
|
trest -= (tend-tbeg);
|
|
ndone += irc;
|
ndone += irc;
|
}
|
}
|
|
|
return (int)ndone;
|
return (int)ndone;
|
}
|
}
|
Line 283... |
Line 297... |
fUrl.Dump(os, ind+2, "fUrl: ");
|
fUrl.Dump(os, ind+2, "fUrl: ");
|
os << bl << " fFdRead: " << fFdRead << endl;
|
os << bl << " fFdRead: " << fFdRead << endl;
|
os << bl << " fFdWrite: " << fFdWrite << endl;
|
os << bl << " fFdWrite: " << fFdWrite << endl;
|
os << bl << " fspLog: " << fspLog.get() << endl;
|
os << bl << " fspLog: " << fspLog.get() << endl;
|
os << bl << " fTraceLevel: " << fTraceLevel << endl;
|
os << bl << " fTraceLevel: " << fTraceLevel << endl;
|
|
//FIXME_code: fTsLastRead, fTsLastWrite not yet in Dump (get formatter...)
|
fStats.Dump(os, ind+2, "fStats: ");
|
fStats.Dump(os, ind+2, "fStats: ");
|
return;
|
return;
|
}
|
}
|
|
|
//------------------------------------------+-----------------------------------
|
//------------------------------------------+-----------------------------------
|
//! FIXME_docs
|
//! FIXME_docs
|
|
|
void RlinkPort::CloseFd(int& fd)
|
void RlinkPort::CloseFd(int& fd)
|
{
|
{
|
if (fd >= 0) {
|
if (fd >= 0) {
|
close(fd);
|
::close(fd);
|
fd = -1;
|
fd = -1;
|
}
|
}
|
return;
|
return;
|
}
|
}
|
|
|