#include "cdutils_core.h" #include "cdutils_parser.h" #include "piconfig.h" #include "piiobytearray.h" #include "piiostring.h" #include "pifile.h" using namespace CDUtils; const char CDCore::app_config[] = "include = cd_ip.conf\n\ port_rec = 2\n\ port_send = 1\n\ [connection]\n\ device.cd = peer://cd_app:cd_pult #s\n\ []\n\ connectionmodel = AAAM2Xja7VXLTttAFD12QpsikKjUSixYlLbKEpIUtVIlVEfqhk2FWuiGRRolUYtoHgrmpYiv6IItf8AveMMH9E/YsG6Ph3sde5hGoQoblLGuPHfunTPjc49nADxDA110+LTYC7FrPCAPeAO+vZu+aX7c/8PGd45WCJC0OGcfT6FDnmfSTPtwhZFt3HjgDs/Qtu5jPbZHtI/x50XfIzMQbdwEolbg9INP4ku++myPaUtCHYRaT2j1ldIh3VP60/Qff8vSfXLu9BP6JX9K/0TVH6jqVe22P1X/fao/oddWu/paDs1vBf9Jv/EZ91clbyHqv7BL6sscDOd4v4WTqs6jzaHGJ8QJerxlpJSpdZ7IWFJvDW7I2JxZqIM62k6A57RZmMQGmlyrxdV+WGBnmR01mXPI267hBKwp4FeBeo9VPtssxyb7rzHg1B7T9nCMU45U8BZlWuVWtIcD/CRGOqtsbW09851tXsHN0UTlLIAdASjSXnLyLn+H7L2+xbGYvC63Ezqg543egkLmn8qnRF6USbM4Qp9godkhzI777Ne5bCIt/5UtGz2o/yGby0nKpjqmbOa1ynkjmyzIrzvIZUeBPjvlUmbh32EFJbGyJZhR8YcvlS+3TpjhqeWSyvUkpbI9plSWtcKLcsK05beOJVEnhaEFfHEH+RwpeMcpn1JKGqWMNOL+G6wZyahlpdVOtufKfbDS+guLke9O\n\ "; const char CDCore::pult_config[] = "include = cd_ip.conf\n\ port_rec = 1\n\ port_send = 2\n\ [connection]\n\ device.cd = peer://cd_pult:cd_app #s\n\ []\n\ connectionmodel = AAAM2Xja7VXLTttAFD12QpsikKjUSixYlLbKEpIUtVIlVEfqhk2FWuiGRRolUYtoHgrmpYiv6IItf8AveMMH9E/YsG6Ph3sde5hGoQoblLGuPHfunTPjc49nADxDA110+LTYC7FrPCAPeAO+vZu+aX7c/8PGd45WCJC0OGcfT6FDnmfSTPtwhZFt3HjgDs/Qtu5jPbZHtI/x50XfIzMQbdwEolbg9INP4ku++myPaUtCHYRaT2j1ldIh3VP60/Qff8vSfXLu9BP6JX9K/0TVH6jqVe22P1X/fao/oddWu/paDs1vBf9Jv/EZ91clbyHqv7BL6sscDOd4v4WTqs6jzaHGJ8QJerxlpJSpdZ7IWFJvDW7I2JxZqIM62k6A57RZmMQGmlyrxdV+WGBnmR01mXPI267hBKwp4FeBeo9VPtssxyb7rzHg1B7T9nCMU45U8BZlWuVWtIcD/CRGOqtsbW09851tXsHN0UTlLIAdASjSXnLyLn+H7L2+xbGYvC63Ezqg543egkLmn8qnRF6USbM4Qp9godkhzI777Ne5bCIt/5UtGz2o/yGby0nKpjqmbOa1ynkjmyzIrzvIZUeBPjvlUmbh32EFJbGyJZhR8YcvlS+3TpjhqeWSyvUkpbI9plSWtcKLcsK05beOJVEnhaEFfHEH+RwpeMcpn1JKGqWMNOL+G6wZyahlpdVOtufKfbDS+guLke9O\n\ "; int __Core_Initializer__::count_(0); CDCore * __Core_Initializer__::__instance__(0); const uchar header_direct = 0x80; const uchar header_transfer = 0x81; __Core_Initializer__::__Core_Initializer__() { count_++; //piCout << "try create Core" << count_; if (count_ > 1) return; //piCout << "create Core"; __instance__ = new CDCore(); } __Core_Initializer__::~__Core_Initializer__() { count_--; //piCout << "try delete Core" << count_; if (count_ > 0) return; //piCout << "delete Core"; if (__instance__ != 0) { delete __instance__; __instance__ = 0; } } CDCore::CDCore() { setName("CDCore"); datatr.setPacketSize(960); CONNECTU(&connection, dataReceivedEvent, this, dataReceived); /*PIString s(app_config); connection.configureFromString(&s); connection.start();*/ k_.cd_type_ = CDType::cdK; x_.cd_type_ = CDType::cdX; c_.cd_type_ = CDType::cdC; initRoot(&k_); initRoot(&x_); initRoot(&c_); CONNECTU(&datatr, sendRequest, this, dtSendRequest) CONNECTU(&datatr, receiveFinished, this, dtReceiveFinished) CONNECTU(&sendt, started, this, sendThread) CONNECTU(&x_timer, tickEvent, this, xTimerTick) /*k_[1] = KType(1, "123", "120+3", "comment"); k_[2] = KType(2, "1", "2", "comm"); k_[4] = KType(4, "-0.6", "-6/10", "mment"); k_.section(10)[5] = KType(5, "8", "2*2*2", "88"); k_.section(10).section(50)[100] = KType(100, "8", "2*2*2", "88"); k_.section(11)[3] = KType(3, "1", "1", "88"); k_.section(11)[4] = KType(4, "0", "0", "88"); k_.section(11)[6] = KType(6, "0", "0", "88");*/ //piCout << s; } CDCore::~CDCore() { datatr.stop(); x_timer.stop(); sendt.stop(); sendt.waitForFinish(10); connection.stop(); } void CDCore::cd_write(CDSection * cd, PIIODevice * d) { cd->write(d, PIString()); } void CDCore::cd_read(CDSection * cd, PIIODevice * d) { PIConfig conf(d, PIIODevice::ReadOnly); cd->read(&(conf.rootEntry())); initRoot(cd); K_ChangedGlobal(); /*PIVector ds = connection.allDevices(); piForeach(PIIODevice * d, ds) { if (d) piCoutObj << d->constructFullPath() << d->isOpened(); }*/ } void CDCore::cd_parse(CDSection * cd, PIIODevice * d) { *cd = CDParser::parse(d, cd->cd_type_); initRoot(cd); K_ChangedGlobal(); } void CDCore::cd_update(CDSection * cd, PIIODevice * d, UpdateModeFlags mode) { CDSection ucd = *cd; cd_parse(cd, d); /*bool kn = true; if (!ucd.isEmpty()) if (!ucd.isSameStructure(k_)) { piCout << "ask for save names"; K_KeepNamesRequest(&kn); }*/ ucd.update(*cd, mode); //piCout << k_.count() << ucd.count(); *cd = ucd; initRoot(cd); K_ChangedGlobal(); } void CDCore::cd_calculate(CDSection * cd) { cd->calculate(); K_ChangedGlobal(); } void CDCore::cd_send(CDSection * cd, CDPacketType pt, bool direct) { PIByteArray ba, sba; PIIOByteArray iob(&ba, PIIODevice::ReadWrite); cd_write(cd, &iob); //piCoutObj << PIString(ba); sba = makeHeader(pt, 0); sba << ba; if (direct) sendDirect(sba); else sendThreaded(sba); } void CDCore::initApp() { init(appConfig()); } void CDCore::initPult() { init(pultConfig()); } void CDCore::init(const PIString & configuration) { PIString c = configuration; //piCoutObj << "init" << c; connection.stop(); connection.removeAllDevices(); connection.configureFromString(&c); connection.start(); } void CDCore::startPing() { x_timer.start(1.0); } CDSection * CDCore::root(CDType::cdT cdt) { switch (cdt) { case CDType::cdK: return &k_; break; case CDType::cdX: return &x_; break; case CDType::cdC: return &c_; break; default: break; } return 0; } PIString CDCore::typeLetter(CDType::cdT cdt) { switch (cdt) { case CDType::cdK: return PIStringAscii("k"); break; case CDType::cdX: return PIStringAscii("x"); break; case CDType::cdC: return PIStringAscii("c"); break; default: break; } return PIString(); } CDCore * CDCore::instance() { /*static CDCore * ret = new CDCore(); return ret;*/ return __Core_Initializer__::__instance__; } void CDCore::K_Send() { piCoutObj << "K_Send"; cd_send(&k_, CD_KSend); } void CDCore::K_Request() { piCoutObj << "K_Request"; PIByteArray sba = makeHeader(CD_KQuery, 0); sendThreaded(sba); } void CDUtils::CDCore::K_DirectChange(PIDeque path, PIString value) { piCoutObj << "K_DirectChange"; PacketKDirectChange p; p.path = path; p.value = value; PIByteArray sba = makeHeader(CD_KDirectChange, 0); sba << p; sendDirect(sba); } void CDCore::sendThread() { if (send_data.size_s() < 4) return; PacketHeader h; memcpy(&h, send_data.data(), sizeof(h)); bool ok = datatr.send(send_data); switch (h.type) { case CD_KSend: if (ok) K_Sended(); else K_SendFail(); break; case CD_KQuery: if (!ok) K_ReceiveFail(); break; default: break; } } void CDCore::xTimerTick() { PacketHeader ph; ph.type = CD_Ping; ph.session_id = 0; PIByteArray ba; ba << ph; connection.writeByName("cd", ba); } void CDCore::initRoot(CDSection * r) { r->name = "__root__"; r->alias = "root"; r->makePath(); r->calculate(); } PIByteArray CDCore::makeHeader(CDPacketType type, int session_id) const { PacketHeader h; h.type = type; h.session_id = session_id; PIByteArray ret; ret << h; return ret; } void CDCore::sendDirect(PIByteArray & ba) { ba.push_front(header_direct); connection.writeByName("cd", ba); } void CDCore::sendThreaded(PIByteArray & ba) { if (sendt.isRunning()) { piCoutObj << "Send in process, abort"; return; } send_data = ba; sendt.startOnce(); } void CDCore::procReceivedPacket(PIByteArray & ba) { PacketHeader h; ba >> h; switch(h.type) { case CD_Ping: //piCoutObj << "ping"; break; case CD_KQuery: K_Send(); break; case CD_KSend: { piCoutObj << "K received"; PIByteArray k; ba >> k; k << uchar(0); PIString s = PIString::fromUTF8((const char *)k.data()); PIIOString ios(&s); cd_read(&k_, &ios); K_Received(); } break; case CD_KDirectChange: { PacketKDirectChange p; ba >> p; k_[p.path].setValue(p.value); } break; default: break; } } void CDUtils::CDCore::dataReceived(const PIString & from, const PIByteArray & data) { //piCoutObj << "dataReceived" << from << data.size(); PIIODevice * d = connection.deviceByName("cd"); if (d && d == connection.deviceByFullPath(from)) { if (data.size() >= sizeof(4)) { PIByteArray ba = data; uchar header = ba.take_front(); if (header == header_transfer) { datatr.received(ba); } if (header == header_direct) { procReceivedPacket(ba); } } } } void CDCore::dtSendRequest(PIByteArray & data) { data.push_front(header_transfer); connection.writeByName("cd", data); //piCoutObj << "send" << data.size() << ret; } void CDCore::dtReceiveFinished(bool ok) { if (!ok) return; PIByteArray ba = datatr.data(); procReceivedPacket(ba); }