OpenCPN Partial API docs
Loading...
Searching...
No Matches
comm_drv_n0183_android_int.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright (C) 2023 by David Register *
3 * Copyright (C) 2023 Alec Leamas *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
17 **************************************************************************/
18
26#include <mutex>
27#include <queue>
28#include <vector>
29
30// For compilers that support precompilation, includes "wx.h".
31#include <wx/wxprec.h>
32
33#ifndef WX_PRECOMP
34#include <wx/wx.h>
35#endif // precompiled headers
36
37#include <wx/event.h>
38#include <wx/log.h>
39#include <wx/string.h>
40#include <wx/utils.h>
41
42#include "config.h"
46
47#ifdef __ANDROID__
48#include "androidUTIL.h"
49#endif
50
51typedef enum DS_ENUM_BUFFER_STATE {
52 DS_RX_BUFFER_EMPTY,
53 DS_RX_BUFFER_FULL
54} _DS_ENUM_BUFFER_STATE;
55
56using namespace std::literals::chrono_literals;
57
58class CommDriverN0183AndroidInt; // fwd
59
60#define MAX_OUT_QUEUE_MESSAGE_LENGTH 100
61
62template <typename T>
64public:
65 size_t size() {
66 std::lock_guard<std::mutex> lock(m_mutex);
67 return m_queque.size();
68 }
69
70 bool empty() {
71 std::lock_guard<std::mutex> lock(m_mutex);
72 return m_queque.empty();
73 }
74
75 const T& front() {
76 std::lock_guard<std::mutex> lock(m_mutex);
77 return m_queque.front();
78 }
79
80 void push(const T& value) {
81 std::lock_guard<std::mutex> lock(m_mutex);
82 m_queque.push(value);
83 }
84
85 void pop() {
86 std::lock_guard<std::mutex> lock(m_mutex);
87 m_queque.pop();
88 }
89
90private:
91 std::queue<T> m_queque;
92 mutable std::mutex m_mutex;
93};
94
95#define OUT_QUEUE_LENGTH 20
96#define MAX_OUT_QUEUE_MESSAGE_LENGTH 100
97
98wxDEFINE_EVENT(wxEVT_COMMDRIVER_N0183_ANDROID_INT,
100
101CommDriverN0183AndroidIntEvent::CommDriverN0183AndroidIntEvent(
102 wxEventType commandType, int id = 0)
103 : wxEvent(id, commandType) {};
104
105CommDriverN0183AndroidIntEvent::~CommDriverN0183AndroidIntEvent() {};
106
107void CommDriverN0183AndroidIntEvent::SetPayload(
108 std::shared_ptr<std::vector<unsigned char>> data) {
109 m_payload = data;
110}
111std::shared_ptr<std::vector<unsigned char>>
112CommDriverN0183AndroidIntEvent::GetPayload() {
113 return m_payload;
114}
115
116// required for sending with wxPostEvent()
117wxEvent* CommDriverN0183AndroidIntEvent::Clone() const {
120 newevent->m_payload = this->m_payload;
121 return newevent;
122};
123
124CommDriverN0183AndroidInt::CommDriverN0183AndroidInt(
125 const ConnectionParams* params, DriverListener& listener)
126 : CommDriverN0183(NavAddr::Bus::N0183, params->GetStrippedDSPort()),
127 m_bok(false),
128 m_portstring(params->GetDSPort()),
129 m_stats_timer(*this, 2s),
130 m_params(*params),
131 m_listener(listener) {
132 this->attributes["commPort"] = params->Port.ToStdString();
133 this->attributes["userComment"] = params->UserComment.ToStdString();
134 this->attributes["ioDirection"] = DsPortTypeToString(params->IOSelect);
135 m_driver_stats.driver_bus = NavAddr::Bus::N0183;
136 m_driver_stats.driver_iface = params->GetStrippedDSPort();
137
138 // Prepare the wxEventHandler to accept events from the actual hardware thread
139 Bind(wxEVT_COMMDRIVER_N0183_ANDROID_INT,
140 &CommDriverN0183AndroidInt::handle_N0183_MSG, this);
141
142 Open();
143}
144
145CommDriverN0183AndroidInt::~CommDriverN0183AndroidInt() { Close(); }
146
147bool CommDriverN0183AndroidInt::Open() {
148 androidStartGPS(this);
149 m_driver_stats.available = true;
150 return true;
151}
152
153void CommDriverN0183AndroidInt::Close() {
154 wxLogMessage(
155 wxString::Format("Closing NMEA Driver %s", m_portstring.c_str()));
156 m_stats_timer.Stop();
157
158 androidStopGPS();
159 m_driver_stats.available = false;
160
161 Unbind(wxEVT_COMMDRIVER_N0183_ANDROID_INT,
162 &CommDriverN0183AndroidInt::handle_N0183_MSG, this);
163}
164
165bool CommDriverN0183AndroidInt::SendMessage(
166 std::shared_ptr<const NavMsg> msg, std::shared_ptr<const NavAddr> addr) {
167 return false;
168}
169
170void CommDriverN0183AndroidInt::handle_N0183_MSG(
172 auto p = event.GetPayload();
173 std::vector<unsigned char>* payload = p.get();
174
175 m_driver_stats.rx_count += payload->size();
176
177 // Extract the NMEA0183 sentence
178 std::string full_sentence = std::string(payload->begin(), payload->end());
179
180 if ((full_sentence[0] == '$') || (full_sentence[0] == '!')) { // Sanity check
181 // notify message listener
182 if (m_params.SentencePassesFilter(full_sentence, FILTER_INPUT)) {
183 // We notify based on full message, including the Talker ID
184 std::string id = full_sentence.substr(1, 5);
185 auto msg =
186 std::make_shared<const Nmea0183Msg>(id, full_sentence, GetAddress());
187 m_listener.Notify(std::move(msg));
188 }
189 }
190}
NMEA0183 basic parsing common parts:
Interface for handling incoming messages.
Definition comm_driver.h:50
virtual void Notify(std::shared_ptr< const NavMsg > message)=0
Handle a received message.
Where messages are sent to or received from.
Android internal nmea0183 driver.
Driver registration container, a singleton.
Raw messages layer, supports sending and recieving navmsg messages.
std::string DsPortTypeToString(dsPortType type)
Return textual representation for use in driver ioDirection attribute.
unsigned rx_count
Number of bytes received since program start.