Advertisement
Alior

Phone controller final version

Jun 2nd, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.00 KB | None | 0 0
  1.  
  2. #include <iostream>
  3. #include <string>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <vector>
  8. #include <errno.h>
  9. #include <string.h>
  10. #include <unistd.h>         //Used for UART
  11. #include <fcntl.h>          //Used for UART
  12. #include <termios.h>        //Used for UART
  13. #include <unistd.h>
  14. #include <sys/wait.h>
  15. #include <stdio.h>
  16. #include <functional>
  17. #include <signal.h>
  18. #include <poll.h>
  19. #include <algorithm>
  20.  
  21. class Logger
  22. {
  23. public:
  24.     static void Log(const std::string & message)
  25.     {
  26.         std::cout << message << std::endl;
  27.     }
  28. };
  29.  
  30. class ProgrammExecutor
  31. {
  32. public:
  33.     void Execute(const char **argv, std::function<bool(void)> continuePredicate)
  34.     {
  35.         pid_t myPid = fork();
  36.        
  37.         if (myPid == 0)
  38.         {
  39.             pid_t pid = execve(argv[0], (char**) argv, NULL);
  40.             if (pid == -1)
  41.             {
  42.                 Logger::Log((std::string)"Error executing program: " + argv[0] + " error: " + std::to_string(errno));
  43.                 return;
  44.             }
  45.             else
  46.             {
  47.                 Logger::Log((std::string)"Executing command " + argv[0]);
  48.             }
  49.         }
  50.         else
  51.         {
  52.             int status = 0;
  53.        
  54.             std::cout << "Waiting" << std::endl;
  55.                
  56.             while (waitpid(myPid, &status, WNOHANG) == 0)
  57.             {
  58.                 sleep(1);
  59.                
  60.                 if (!continuePredicate())
  61.                 {
  62.                     kill(myPid, SIGKILL);
  63.                     while (waitpid(myPid, &status, WNOHANG) == 0);
  64.                     std::cout << "Killed" << std::endl;
  65.                     break;
  66.                 }
  67.             }
  68.            
  69.             std::cout << "The end" << std::endl;
  70.         }
  71.     }
  72. };
  73.  
  74. class AudioPlayer
  75. {
  76. public:
  77.        
  78.     AudioPlayer(const std::string &inFileName, std::function<bool(void)> continuePredicate)
  79.     {
  80.         const std::string path = ((std::string)"/home/pi/Sounds/" + inFileName);
  81.         const char *arguments[64] = {"/usr/bin/aplay", path.c_str(), NULL };
  82.         ProgrammExecutor executor;
  83.         executor.Execute(arguments, continuePredicate);
  84.     }
  85. };
  86.  
  87. class Serial
  88. {
  89. private:
  90.     static const size_t bufferSize = 4096;
  91.  
  92.     int uart = -1;
  93.    
  94. public:
  95.    
  96.     Serial(const std::string & device)
  97.     {
  98.         uart = open(device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
  99.         if (uart != -1)
  100.         {
  101.             Logger::Log("UART has been open.");
  102.            
  103.             termios options = {0};
  104.             tcgetattr(uart, &options);
  105.             options.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
  106.             options.c_iflag = IGNPAR;
  107.             options.c_oflag = 0;
  108.             options.c_lflag = 0;
  109.             options.c_cc[VMIN] = 0;
  110.             tcflush(uart, TCIFLUSH);
  111.             tcsetattr(uart, TCSANOW, &options);
  112.            
  113.             Logger::Log("UART has been configured.");
  114.         }
  115.         else
  116.             Logger::Log("Not abble to open UART. Exiting.");
  117.     }
  118.    
  119.     ~Serial()
  120.     {
  121.         if (uart == -1)
  122.             return;
  123.        
  124.         close (uart);
  125.        
  126.         Logger::Log("Deinitializing Serial");
  127.     }
  128.    
  129.     void Send(const std::string & data) const
  130.     {
  131.         if (uart < 0)
  132.         {
  133.             Logger::Log("Can't send info. UART was not open properly");
  134.             return;
  135.         }
  136.        
  137.         if (write(uart, data.c_str(), data.size()) < 0)
  138.             Logger::Log("Error sending data");
  139.         else
  140.             Logger::Log("Sent \"" + data + "\"");
  141.     }
  142.    
  143.     const std::string Read(bool blocking = true) const
  144.     {
  145.         while (tcdrain(uart) != 0);
  146.        
  147.         int result = 0;
  148.         char rx_buffer[bufferSize];
  149.         while ((result = read(uart, (void*) rx_buffer, bufferSize)) == 0 && blocking);
  150.        
  151.         if (blocking && result < 0)
  152.         {
  153.             Logger::Log("Error reading data");
  154.             return "Error reading data";
  155.         }
  156.         else
  157.         {
  158.             rx_buffer[result] = '\0';
  159.             return std::string(rx_buffer);
  160.         }
  161.     }
  162. };
  163.  
  164. class GSMModule
  165. {
  166. private:
  167.     const Serial * serial;
  168.    
  169.     mutable std::string buffer;
  170.    
  171. public:
  172.     GSMModule(const Serial * inSerialToUse) : serial(inSerialToUse)
  173.     {
  174.         SendCommand("ATE1");
  175.     }
  176.    
  177.     enum CallStatus
  178.     {
  179.         None = -1,
  180.         Talking = 0,
  181.         Held = 1,
  182.         Dialing = 2,
  183.         Alerting = 3
  184.     };
  185.    
  186.     CallStatus GetCallStatus() const
  187.     {
  188.         SendCommand("AT+CLCC");
  189.        
  190.         std::string result;
  191.         while ((result = Receive()).size() == 0);
  192.        
  193.         Logger::Log(result);
  194.        
  195.         const std::string expectedResult = "+CLCC:";
  196.         if (Contains(result, expectedResult))
  197.             return (CallStatus) GetParameters(result)[2];
  198.         else
  199.             return CallStatus::None;
  200.     }
  201.    
  202.     void Response() const
  203.     {
  204.         SendCommand("ATA");
  205.     }
  206.    
  207.     void EndCall() const
  208.     {
  209.         SendCommand("ATH");
  210.     }
  211.    
  212.     void SendAT() const
  213.     {
  214.         SendCommand("AT");
  215.     }
  216.    
  217.     void SendBusy()
  218.     {
  219.         SendCommand("AT+GSMBUSY");
  220.     }
  221.    
  222.     void TurnOn() const
  223.     {
  224.         SendCommand("AT+CPOWD=1");
  225.     }
  226.    
  227.     void TurnOff()
  228.     {
  229.         SendCommand("AT+CPOWD=0");
  230.     }
  231.    
  232.     void Call(const std::string &number) const
  233.     {
  234.         SendCommand("ATD" + number + ";");
  235.     }
  236.    
  237.     void SendCommand(const std::string &inCommand) const
  238.     {
  239.         const std::string commandToSend = inCommand + "\r\n";
  240.         serial->Send(commandToSend);
  241.     }
  242.    
  243.     const std::string Receive() const
  244.     {
  245.         const std::string result = serial->Read(false);
  246.         if (result.size() != 0)
  247.             buffer += result;
  248.            
  249.         if (buffer.size() > 2 && *buffer.rbegin() == '\n' && *(buffer.rbegin() + 1) == '\r')
  250.         {
  251.             std::string fullMessage = buffer;
  252.             fullMessage = fullMessage.substr(0, fullMessage.size() - 2);
  253.            
  254.             buffer = "";
  255.            
  256.             return fullMessage;
  257.         }
  258.        
  259.         return "";
  260.     }
  261.    
  262. private:
  263.  
  264.     const std::vector<int> GetParameters(const std::string &inString) const
  265.     {
  266.         std::vector<int> parameters;
  267.        
  268.         auto start = std::find(inString.begin(), inString.end(), ',');
  269.         if (start == inString.end())
  270.             return parameters;
  271.        
  272.         start--;
  273.        
  274.         for (auto it = start; it != start + 10 && it < inString.end(); it += 2)
  275.         {
  276.             parameters.push_back((*it) - '0');
  277.         }
  278.        
  279.         return parameters;
  280.     }
  281.    
  282.     inline bool Contains(const std::string &inString, const std::string &inSub) const
  283.     {
  284.         if (inSub.size() > inString.size())
  285.             return false;
  286.        
  287.         auto current = inSub.begin();
  288.         for (auto it = inString.begin(); it != inString.end(); it++)
  289.         {
  290.             if (*it == *current)
  291.             {
  292.                 current++;
  293.                 if (current == inSub.end())
  294.                     return true;
  295.             }
  296.             else
  297.                 current = inSub.begin();
  298.         }
  299.        
  300.         return false;
  301.     }
  302. };
  303.  
  304. class NetworkController
  305. {
  306. private:
  307.     static const size_t bufferSize = 4096;
  308.  
  309.     int currentConnection = -1;
  310.  
  311.     int socketId = -1;
  312.    
  313. public:
  314.     NetworkController(int port)
  315.     {
  316.         socketId = socket(AF_INET, SOCK_STREAM | O_NONBLOCK, 0);
  317.         if (socketId < 0)
  318.         {
  319.             Logger::Log((std::string)"Error opening socket: " + strerror(errno));
  320.             return;
  321.         }
  322.        
  323.         sockaddr_in addr = {0};
  324.         addr.sin_family = AF_INET;
  325.         addr.sin_port = htons(port);
  326.         addr.sin_addr.s_addr = htonl(INADDR_ANY);
  327.         int bindResult = 0;
  328.         if ((bindResult = bind(socketId, (sockaddr*) & addr, sizeof(addr))) < 0)
  329.         {
  330.             Logger::Log((std::string)"Error binding socket: " + strerror(bindResult));
  331.             return;
  332.         }
  333.        
  334.         listen(socketId, 1);
  335.     }
  336.    
  337.     bool HasConnection() const
  338.     {
  339.         return currentConnection != -1;
  340.     }
  341.    
  342.     bool SendIdle()
  343.     {
  344.         return SendToConnection("idle");
  345.     }
  346.    
  347.     bool SendToConnection(const std::string &inAnswer) const
  348.     {
  349.         if (currentConnection == -1)
  350.         {
  351.             Logger::Log("No connection");
  352.             return false;
  353.         }
  354.        
  355.         size_t size = inAnswer.size() + 1;
  356.         char * buffer = new char[size];
  357.         memcpy(buffer, inAnswer.c_str(), inAnswer.size());
  358.         buffer[size - 1] = '\0';
  359.        
  360.         int result = sendall(currentConnection, buffer, size, MSG_NOSIGNAL) >= 0;
  361.        
  362.         delete[] buffer;
  363.        
  364.         if (result < 0)
  365.         {
  366.             Logger::Log((std::string)"Error sending repsonse: " + std::to_string(errno));
  367.             return false;
  368.         }
  369.         else
  370.             return true;
  371.     }
  372.    
  373.     const std::string Receive() const
  374.     {
  375.         if (currentConnection == -1)
  376.             return std::string();
  377.        
  378.         char buffer[bufferSize];
  379.        
  380.         std::string results;
  381.         pollfd fd = {0};
  382.         fd.fd = currentConnection;
  383.         fd.events = POLLIN;
  384.        
  385.         poll(&fd, 1, 0);
  386.         if (fd.revents & POLLIN)
  387.         {
  388.             int received = recv(currentConnection, buffer, bufferSize, O_NONBLOCK);
  389.             if (received < 0)
  390.             {
  391.                 Logger::Log((std::string)"Error receiving data: " + strerror(received));
  392.             }
  393.             else if (received != 0)
  394.             {          
  395.                 buffer[received] = '\0';
  396.                 return std::string(buffer);
  397.             }
  398.         }
  399.        
  400.         return std::string();
  401.     }
  402.    
  403.     void Update()
  404.     {
  405.         int accepted = accept(socketId, NULL, NULL);
  406.         if (accepted > 0)
  407.         {
  408.             if (currentConnection != -1)
  409.                 close(currentConnection);
  410.            
  411.             currentConnection = accepted;
  412.         }
  413.     }
  414.  
  415.     ~NetworkController()
  416.     {
  417.         if (currentConnection != -1)
  418.             close(currentConnection);
  419.        
  420.         currentConnection = -1;
  421.         if (socketId < 0)
  422.             return;
  423.            
  424.         close(socketId);
  425.     }
  426.    
  427. private:
  428.     int sendall(const int s, const char *buf, const int len, const int flags) const
  429.     {
  430.         int total = 0;
  431.         int n;
  432.  
  433.         while(total < len)
  434.         {
  435.             n = send(s, buf+total, len-total, flags);
  436.             if(n == -1) { break; }
  437.             total += n;
  438.         }
  439.  
  440.         return (n==-1 ? -1 : total);
  441.     }
  442. };
  443.  
  444. class CommandExecutor
  445. {
  446. private:
  447.     const GSMModule * module = nullptr;
  448.     const NetworkController *networkController = nullptr;
  449.    
  450.     class EndCommandMessageSender
  451.     {
  452.         private:
  453.             const NetworkController * networkController = nullptr;
  454.        
  455.         public:
  456.             EndCommandMessageSender(const NetworkController * inNetworkController) : networkController(inNetworkController)
  457.             {
  458.             }
  459.            
  460.             ~EndCommandMessageSender()
  461.             {
  462.                 if (networkController->HasConnection())
  463.                     networkController->SendToConnection("command finished");
  464.             }
  465.     };
  466.    
  467. public:
  468.    
  469.     CommandExecutor(const GSMModule * inModule, const NetworkController * inNetworkController) : module(inModule), networkController(inNetworkController)
  470.     {
  471.        
  472.     }
  473.    
  474.     bool ExecuteCommand(const std::string &command, const std::vector<std::string> &parameters) const
  475.     {
  476.         EndCommandMessageSender endCommandHandler(networkController);
  477.        
  478.         Logger::Log("Start command execution '" + command + "'");
  479.    
  480.         if (command == "call")
  481.         {
  482.             Logger::Log("Before calling 'call' command");
  483.        
  484.             if (parameters.size() != 2)
  485.             {
  486.                 Logger::Log("Incorrect count of parameters for call command");
  487.                 return false;
  488.             }
  489.            
  490.             SendCalling();
  491.            
  492.             module->Call(parameters[0]);
  493.             while (module->GetCallStatus() == GSMModule::CallStatus::None)
  494.             {
  495.                 SendCalling();
  496.                
  497.                 Logger::Log("Waiting for call");
  498.                 sleep(1);
  499.             }
  500.            
  501.             while (module->GetCallStatus() != GSMModule::CallStatus::Talking)
  502.             {
  503.                 SendCalling();
  504.                
  505.                 sleep(1);
  506.                
  507.                 if (module->GetCallStatus() == GSMModule::CallStatus::None)
  508.                 {
  509.                     Logger::Log("The call has been interrupted");
  510.                     return true;
  511.                 }
  512.             }
  513.            
  514.             SendCalling();
  515.                
  516.             Logger::Log("Call answered");
  517.             AudioPlayer(parameters[1], [&]() { return module->GetCallStatus() == GSMModule::CallStatus::Talking; });
  518.             module->EndCall();
  519.            
  520.             return true;
  521.         }
  522.         else if (command == "at")
  523.         {
  524.             module->SendAT();
  525.             return true;
  526.         }
  527.         else if (command == "raw_command")
  528.         {
  529.             if (parameters.size() != 1)
  530.             {
  531.                 Logger::Log("This command should have only one parameter");
  532.                 return false;
  533.             }
  534.            
  535.             module->SendCommand(parameters[0]);
  536.             return true;
  537.         }
  538.        
  539.         Logger::Log("Unknown command (" + command + ")");
  540.         return false;
  541.     }
  542.    
  543. private:
  544.     bool SendCalling() const
  545.     {
  546.         Logger::Log("Sending call");
  547.         if (!networkController->HasConnection())
  548.             return false;
  549.        
  550.         bool result = networkController->SendToConnection("calling");
  551.         if (!result)
  552.             Logger::Log("Error sending data");
  553.            
  554.         return result;
  555.     }
  556. };
  557.  
  558. class CommandParser
  559. {
  560. public:
  561.     class CommandInfo
  562.     {
  563.         private:
  564.             const std::string commandName;
  565.             const std::vector<std::string> parameters;
  566.            
  567.         public:
  568.             CommandInfo(const std::string &inCommandName, const std::vector<std::string> inParameters) : commandName(inCommandName), parameters(inParameters)
  569.             {
  570.             }
  571.            
  572.             const std::string GetName() const
  573.             {
  574.                 return commandName;
  575.             }
  576.            
  577.             const std::vector<std::string> GetParameters() const
  578.             {
  579.                 return parameters;
  580.             }
  581.     };
  582.    
  583.     const std::vector<std::string> Parse(const std::string & inString) const
  584.     {
  585.         std::vector<std::string> result;
  586.         result.push_back("");
  587.        
  588.         bool previousWasSpace = true;
  589.         for (auto it = inString.begin(); it != inString.end(); it++)
  590.         {
  591.             bool isSpace= isspace(*it);
  592.             if (isSpace && !previousWasSpace)
  593.             {
  594.                 result.push_back("");
  595.                 continue;
  596.             }
  597.            
  598.             previousWasSpace = isSpace;
  599.             if (isSpace)
  600.                 continue;
  601.                
  602.             result[result.size() -1] += (*it);
  603.         }
  604.        
  605.         return result;
  606.     }
  607.    
  608.     const CommandInfo ParseToCommandInfo(const std::string &inString) const
  609.     {
  610.         std::vector<std::string> data = Parse(inString);
  611.         if (data.size() <= 0)
  612.         {
  613.             Logger::Log("Can't parse command. It's empty");
  614.             return CommandInfo("", std::vector<std::string>());
  615.         }
  616.        
  617.         std::string commandName = data[0];
  618.         data.erase(data.begin());
  619.        
  620.         return CommandInfo(commandName, data);
  621.     }
  622. };
  623.  
  624. int main(int argc, char **argv)
  625. {
  626.     Logger::Log("Starting application.");
  627.    
  628.     NetworkController networkController(5551);
  629.     Serial serial("/dev/ttyS0");
  630.     GSMModule module(&serial);
  631.     CommandExecutor executor(&module, &networkController);
  632.     CommandParser parser;
  633.    
  634.     while (true)
  635.     {  
  636.         networkController.Update();
  637.        
  638.         auto received = networkController.Receive();
  639.         if (received.size() != 0)
  640.         {
  641.             CommandParser::CommandInfo info = parser.ParseToCommandInfo(received);
  642.            
  643.             executor.ExecuteCommand(info.GetName(), info.GetParameters());
  644.         }
  645.     }
  646.    
  647.     Logger::Log("Exiting.");
  648.    
  649.     while (true);
  650.    
  651.     return 0;
  652. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement