OpenCPN Partial API docs
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
comm_drv_file.cpp
1 /***************************************************************************
2  *
3  * Project: OpenCPN
4  * Purpose: Implement comm_drv_file.h -- driver reading/writing to/from files
5  * Author: David Register, Alec Leamas
6  *
7  ***************************************************************************
8  * Copyright (C) 2022 by David Register, Alec Leamas *
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  * This program is distributed in the hope that it will be useful, *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18  * GNU General Public License for more details. *
19  * *
20  * You should have received a copy of the GNU General Public License *
21  * along with this program; if not, write to the *
22  * Free Software Foundation, Inc., *
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24  **************************************************************************/
25 
26  // For compilers that support precompilation, includes "wx.h".
27 #include <wx/wxprec.h>
28 
29 #ifndef WX_PRECOMP
30 #include <wx/wx.h>
31 #endif // precompiled headers
32 
33 #include <iostream>
34 #include <fstream>
35 #include <string>
36 
37 #include <wx/log.h>
38 
39 #include "model/comm_driver.h"
40 #include "model/comm_drv_registry.h"
41 #include "model/comm_drv_file.h"
42 #include "model/ocpn_utils.h"
43 
45  virtual void Notify(std::shared_ptr<const NavMsg> message) {}
46  virtual void Notify(const AbstractCommDriver& driver) {}
47 };
48 
49 static VoidDriverListener kVoidDriverListener;
50 
51 using namespace std;
52 
53 FileCommDriver::FileCommDriver(const string& opath, const string& ipath,
54  DriverListener& l)
55  : AbstractCommDriver(NavAddr::Bus::TestBus, opath),
56  output_path(opath),
57  input_path(ipath),
58  listener(l) {}
59 
60 FileCommDriver::FileCommDriver(const string& opath)
61  : FileCommDriver(opath, "", kVoidDriverListener) {}
62 
63 std::shared_ptr<NavAddr> FileCommDriver::GetAddress() {
64  return std::make_shared<NavAddr>(NavAddrTest(output_path));
65 }
66 
67 bool FileCommDriver::SendMessage(std::shared_ptr<const NavMsg> msg,
68  std::shared_ptr<const NavAddr> addr) {
69  ofstream f;
70  f.open(output_path, ios::app);
71  if (!f.is_open()) {
72  wxLogWarning("Cannot open file %s for writing", output_path.c_str());
73  return false;
74  }
75  f << msg->to_string();
76  f.close();
77  return true;
78 }
79 
80 static vector<unsigned char> HexToChar(string hex) {
81  if (hex.size() % 2 == 1) hex = string("0") + hex;
82  vector<unsigned char> chars;
83  for (size_t i = 0; i < hex.size(); i += 2) {
84  istringstream ss(hex.substr(i, 2));
85  unsigned ival;
86  ss >> std::hex >> ival;
87  chars.push_back(static_cast<unsigned char>(ival));
88  }
89  return chars;
90 }
91 
92 static shared_ptr<const NavMsg> LineToMessage(const string& line,
93  std::shared_ptr<NavAddr> src) {
94  auto words = ocpn::split(line.c_str(), " ");
95  NavAddr::Bus bus = NavAddr::StringToBus(words[0]);
96  switch (bus) {
97  case NavAddr::Bus::N2000:
98  if (true) { // Create a separate scope.
99  N2kName name(N2kName::Parse(words[2]));
100  vector<unsigned char> payload(HexToChar(words[3]));
101 // FIXME (Leamas)
102 // return make_shared<Nmea2000Msg>(name, payload, src);
103  return make_shared<NullNavMsg>();
104  }
105  break;
106  case NavAddr::Bus::N0183:
107  if (true) { // Create a separate scope.
108  const string id(words[2]);
109  return make_shared<Nmea0183Msg>(id, words[3], src);
110  }
111  break;
112  default:
113  std::cerr << "Cannot parse line: \"" << line << "\"\n" << flush;
114  return make_shared<NullNavMsg>();
115  break;
116  }
117  return make_shared<NullNavMsg>(); // for the compiler.
118 }
119 
121  CommDriverRegistry::GetInstance().Activate(shared_from_this());
122  if (input_path != "") {
123  ifstream f(input_path);
124  string line;
125  while (getline(f, line)) {
126  auto msg = LineToMessage(line, GetAddress());
127  if (msg->bus != NavAddr::Bus::Undef) listener.Notify(msg);
128  }
129  }
130 }
Common interface for all drivers.
Definition: comm_driver.h:58
void Activate(DriverPtr driver)
Add driver to list of active drivers.
Interface implemented by transport layer and possible other parties like test code which should handl...
Definition: comm_driver.h:47
virtual void Notify(std::shared_ptr< const NavMsg > message)=0
Handle a received message.
Read and write data to/from files test driver
Definition: comm_drv_file.h:38
FileCommDriver(const std::string &opath, const std::string &ipath, DriverListener &l)
An instance which can write to file and play data from another.
void Activate() override
Register driver in the driver Registry.
Where messages are sent to or received from.
Definition: comm_navmsg.h:133
N2k uses CAN which defines the basic properties of messages.
Definition: comm_navmsg.h:59