qmlhandler.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include <csignal>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <iostream>
  5. #include <poll.h>
  6. #include <sys/prctl.h>
  7. #include <sys/wait.h>
  8. #include <thread>
  9. #include <unistd.h>
  10. #include <QGuiApplication>
  11. #include "qmlhandler.h"
  12. #include <boost/asio.hpp>
  13. #include <iostream>
  14. #include <json/json.h>
  15. using boost::asio::buffer;
  16. using namespace std;
  17. int inpipefd[2];
  18. int outpipefd[2];
  19. char buf[1024];
  20. bool programActive = true;
  21. void QMLHandler::onExit() {
  22. write(outpipefd[1], "disconnect\n", strlen("disconnect\n"));
  23. }
  24. void QMLHandler::handleJSON(string buffer) {
  25. Json::Value root;
  26. Json::CharReaderBuilder builder;
  27. Json::CharReader * reader = builder.newCharReader();
  28. string jsonError;
  29. bool parsingSuccessful = reader->parse(buffer.c_str(), buffer.c_str() + buffer.size(), &root, &jsonError);
  30. if (!parsingSuccessful) {
  31. return;
  32. }
  33. const Json::Value command = root["command"];
  34. string cmd = command.asString();
  35. if (cmd == "status") {
  36. emit footerSetStatus(root["response"].asString().c_str());
  37. }
  38. else if (cmd == "close") {
  39. programActive = false;
  40. }
  41. }
  42. void QMLHandler::readPipeLoop() {
  43. unsigned int readOffset = 0;
  44. unsigned int pollCount = 0;
  45. struct pollfd inPipeStatus;
  46. inPipeStatus.fd = inpipefd[0];
  47. inPipeStatus.events = POLLIN;
  48. while (programActive) {
  49. poll(&inPipeStatus, 1, 100);
  50. if (inPipeStatus.revents & POLLIN) {
  51. readOffset += read(inpipefd[0], buf + readOffset, 1024);
  52. pollCount = 0;
  53. buf[1023] = 0;
  54. buf[strlen(buf)] = 0;
  55. } else {
  56. pollCount++;
  57. }
  58. if (pollCount > 9 && buf[0]) {
  59. string cleanBuffer = buf + strcspn(buf, "\n") + 1;
  60. string receivedData = cleanBuffer.substr(0, cleanBuffer.size() - 1);
  61. emit log(QString::fromStdString(receivedData));
  62. qInfo() << QString::fromStdString(receivedData);
  63. handleJSON(receivedData);
  64. memset(buf, 0, 1024);
  65. pollCount = 0;
  66. readOffset = 0;
  67. }
  68. }
  69. }
  70. QMLHandler::QMLHandler(QObject *parent) : QObject(parent) {}
  71. // Sending
  72. void QMLHandler::onSendingSelectFileButton(QUrl url) {
  73. emit log("File Selected: " + url.toString());
  74. emit sendingSetFileUrlText("Selected File: " + url.toString());
  75. }
  76. void QMLHandler::onSendingSendFileButton() { emit log("Sending File !"); }
  77. // Receiving
  78. // Messages
  79. void QMLHandler::onMessagesSendButton(QString msg) { emit message(msg); }
  80. // Settings
  81. void QMLHandler::onSettingsSwitchServerButton() {
  82. emit settingsOpenSwitchServerPopup();
  83. }
  84. // Ip Popup
  85. void QMLHandler::onIpPopupEnterIp(QString ip) {
  86. pid_t pid = 0;
  87. pipe(inpipefd);
  88. pipe(outpipefd);
  89. pid = fork();
  90. if (pid == 0) {
  91. // Child
  92. dup2(outpipefd[0], STDIN_FILENO);
  93. dup2(inpipefd[1], STDOUT_FILENO);
  94. //dup2(inpipefd[1], STDERR_FILENO);
  95. // ask kernel to deliver SIGTERM in case the parent dies
  96. prctl(PR_SET_PDEATHSIG, SIGTERM);
  97. // Set the path to the CLI - pass argument h (help) for now
  98. // TODO: Change hardcoded path
  99. execl("../../cli/build/ccats-cli", "ccats-cli", ip.toUtf8().constData(),
  100. "--machine", (char *)NULL);
  101. exit(1);
  102. }
  103. // TODO: Not hardcoded
  104. emit footerSetStatus("Connected to " + ip);
  105. close(outpipefd[0]);
  106. close(inpipefd[1]);
  107. std::thread(&QMLHandler::readPipeLoop, this).detach();
  108. }
  109. // Switch Popup
  110. void QMLHandler::onSwitchPopupEnterIp(QString ip) {
  111. qInfo() << "Switching to " << ip;
  112. }
  113. // Footer
  114. void QMLHandler::onFooterGetStatusButton() {
  115. write(outpipefd[1], "status\n", strlen("status\n"));
  116. }