1 #include "fujikininterface.h"
3 std::deque<weak_ptr<XPort> > XFujikinInterface::s_openedPorts;
4 XMutex XFujikinInterface::s_lock;
6 XFujikinInterface::XFujikinInterface(
const char *name,
bool runtime,
const shared_ptr<XDriver> &driver) :
10 setSerialBaudRate(38400);
14 XFujikinInterface::~XFujikinInterface() {
18 XFujikinInterface::open() throw (XInterfaceError &) {
23 for(
auto it = s_openedPorts.begin(); it != s_openedPorts.end();) {
24 if(
auto pt = it->lock()) {
25 if(pt->portString() == (
XString)shot[ *port()]) {
33 it = s_openedPorts.erase(it);
37 XCharInterface::open();
38 m_openedPort = openedPort();
39 s_openedPorts.push_back(m_openedPort);
51 XFujikinInterface::send(uint8_t classid, uint8_t instanceid, uint8_t attributeid, T data) {
55 XFujikinInterface::send(uint8_t classid, uint8_t instanceid, uint8_t attributeid, uint8_t data) {
56 std::vector<uint8_t> wbuf(1);
58 communicate(classid, instanceid, attributeid, wbuf);
62 XFujikinInterface::send(uint8_t classid, uint8_t instanceid, uint8_t attributeid, uint16_t data) {
63 std::vector<uint8_t> wbuf(2);
64 wbuf[0] = data % 0x100u;
65 wbuf[1] = data / 0x100u;
66 communicate(classid, instanceid, attributeid, wbuf);
70 XFujikinInterface::send(uint8_t classid, uint8_t instanceid, uint8_t attributeid, uint32_t data) {
71 std::vector<uint8_t> wbuf(4);
72 wbuf[0] = data % 0x100u;
73 wbuf[1] = (data / 0x100uL) % 0x100u;
74 wbuf[1] = (data / 0x10000uL) % 0x100u;
75 wbuf[1] = data / 0x1000000uL;
76 communicate(classid, instanceid, attributeid, wbuf);
80 XFujikinInterface::query(uint8_t classid, uint8_t instanceid, uint8_t attributeid) {
84 XFujikinInterface::query(uint8_t classid, uint8_t instanceid, uint8_t attributeid) {
85 std::vector<uint8_t> wbuf(0), rbuf;
86 communicate(classid, instanceid, attributeid, wbuf, &rbuf);
88 throw XInterfaceError(
"Fujikin Protocol Wrong Data-Size Error.", __FILE__, __LINE__);
93 XFujikinInterface::query(uint8_t classid, uint8_t instanceid, uint8_t attributeid) {
94 std::vector<uint8_t> wbuf(0), rbuf;
95 communicate(classid, instanceid, attributeid, wbuf, &rbuf);
97 throw XInterfaceError(
"Fujikin Protocol Wrong Data-Size Error.", __FILE__, __LINE__);
98 return rbuf[0] + (uint16_t)rbuf[1] * 0x100u;
102 XFujikinInterface::query(uint8_t classid, uint8_t instanceid, uint8_t attributeid) {
103 std::vector<uint8_t> wbuf(0), rbuf;
104 communicate(classid, instanceid, attributeid, wbuf, &rbuf);
106 return reinterpret_cast<char *
>( &rbuf[0]);
109 XFujikinInterface::communicate(uint8_t classid, uint8_t instanceid, uint8_t attributeid,
110 const std::vector<uint8_t> &data, std::vector<uint8_t> *response) {
111 for(
int retry = 0; ; retry++) {
113 communicate_once(classid, instanceid, attributeid, data, response);
116 catch (XInterfaceError &e) {
118 e.print(
"Retrying after an error: ");
128 const std::vector<uint8_t> &data, std::vector<uint8_t> *response) {
130 bool write = !response;
131 std::vector<uint8_t> buf;
132 buf.push_back( ***address());
134 uint8_t commandcode = write ? 0x81 : 0x80;
135 buf.push_back(commandcode);
136 buf.push_back(3 + data.size());
137 buf.push_back(classid);
138 buf.push_back(instanceid);
139 buf.push_back(attributeid);
140 for(
auto it = data.begin(); it != data.end(); ++it)
143 uint8_t checksum = 0;
144 for(
auto it = buf.begin() + 1; it != buf.end(); ++it)
146 buf.push_back(checksum);
148 auto port = m_openedPort;
151 port->write( reinterpret_cast<char*>( &buf[0]), buf.size());
153 switch(port->buffer()[0]) {
158 throw XInterfaceError(
159 formatString(
"Fujikin Protocol Command Error ret=%x.", (
unsigned int)port->buffer()[0]),
164 switch(port->buffer()[0]) {
169 throw XInterfaceError(
170 formatString(
"Fujikin Protocol Command Error ret=%x.", (
unsigned int)port->buffer()[0]),
176 if((port->buffer()[0] != 0) || (port->buffer()[1] != STX))
177 throw XInterfaceError(
178 formatString(
"Fujikin Protocol Command Error ret=%4s.", (
const char*)&port->buffer()[0]),
180 int len = port->buffer()[3];
181 uint8_t checksum = 0;
182 for(
auto it = port->buffer().begin(); it != port->buffer().end(); ++it)
184 port->receive(len + 2);
187 if((port->buffer()[len] != 0))
188 throw XInterfaceError(
"Fujikin Protocol Format Error.", __FILE__, __LINE__);
189 for(
auto it = port->buffer().begin(); it != port->buffer().end(); ++it)
191 checksum -= port->buffer().back() * 2;
193 throw XInterfaceError(
"Fujikin Protocol Check-Sum Error.", __FILE__, __LINE__);
194 response->resize(len - 3);
195 for(
int i = 0; i < response->size(); ++i) {
196 response->at(i) = port->buffer()[i + 3];