OpenCPN Partial API docs
Loading...
Searching...
No Matches
ipc_api.cpp
1/***************************************************************************
2 * Copyright (C) 2023 Alec Leamas *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
19
20#include <sstream>
21
22#include <wx/filename.h>
23
24#include "model/ipc_api.h"
25#include "model/base_platform.h"
26#include "model/logger.h"
27#include "model/ocpn_utils.h"
28
29IpcServer* IpcConnection::s_instance = nullptr;
30
31// FIXME (leamas) Bad name
32std::string GetSocketPath() {
33 auto const static sep = static_cast<char>(wxFileName::GetPathSeparator());
34 auto dirpath = g_BasePlatform->GetPrivateDataDir();
35 if (!wxFileName::DirExists(dirpath)) wxFileName::Mkdir(dirpath);
36 return dirpath.ToStdString() + sep + "opencpn-ipc";
37}
38
39IpcClient::IpcClient(const std::string& path) {
40 connection = MakeConnection("localhost", path, "OpenCPN");
41 if (!connection)
42 throw LocalApiException(std::string("Cannot connect to: ") + path);
43};
44
45LocalApiResult IpcClient::SendQuit() {
46 if (connection->Execute(wxString("quit"))) {
47 return LocalApiResult(true, "");
48 } else {
49 return LocalApiResult(false, "Server error running quit command");
50 }
51}
52
53LocalApiResult IpcClient::SendRaise() {
54 if (connection->Execute(wxString("raise"))) {
55 return LocalApiResult(true, "");
56 } else {
57 return LocalApiResult(false, "Server error running raise command");
58 }
59}
60
61LocalApiResult IpcClient::SendOpen(const char* path) {
62 const void* reply = connection->Request(wxString("open ") + path);
63 if (reply) return LocalApiResult(true, static_cast<const char*>(reply));
64 return LocalApiResult(false, "");
65}
66
67LocalApiResult IpcClient::GetRestEndpoint() {
68 const void* reply = connection->Request("get_rest_endpoint");
69 if (reply) {
70 return LocalApiResult(true, static_cast<const char*>(reply));
71 }
72 return LocalApiResult(false, "Server error running get_rest_endpoint");
73}
74
75LocalServerApi& IpcConnection::GetInstance() {
76 if (!s_instance) s_instance = new IpcServer(GetSocketPath());
77 return *s_instance;
78}
79
80void IpcConnection::ReleaseInstance() {
81 if (s_instance) {
82 delete s_instance;
83 s_instance = nullptr;
84 }
85}
86
87bool IpcConnection::OnExec(const wxString&, const wxString& data) {
88 if (data == "quit") {
89 server.on_quit.Notify();
90 return true;
91 } else if (data == "raise") {
92 server.on_raise.Notify();
93 return true;
94 } else {
95 return false;
96 }
97}
98
99const void* IpcConnection::OnRequest(const wxString& topic,
100 const wxString& item, size_t* size,
101 wxIPCFormat format) {
102 if (format != wxIPC_TEXT) return 0;
103
104 std::string line = item.ToStdString();
105 if (ocpn::startswith(line, "get_rest_endpoint")) {
106 buffer = server.get_rest_api_endpoint_cb();
107 if (size) *size = buffer.size();
108 return buffer.c_str();
109 } else if (ocpn::startswith(line, "open")) {
110 auto words = ocpn::split(line.c_str(), " ");
111 if (words.size() != 2) {
112 wxLogWarning("Illegal open cmd line: %s", line.c_str());
113 return 0;
114 }
115 bool ok = server.open_file_cb(words[1]);
116 const char* reply = ok ? "ok" : "fail";
117 if (size) *size = strlen(reply);
118 return reply;
119 } else {
120 wxLogWarning("Illegal cmd line: %s", line.c_str());
121 return 0;
122 }
123}
wxString & GetPrivateDataDir()
Return dir path for opencpn.log, etc., respecting -c cli option.
const void Notify()
Notify all listeners, no data supplied.
bool OnExec(const wxString &, const wxString &data)
Handle commands without reply: quit and raise.
Definition ipc_api.cpp:87
const void * OnRequest(const wxString &topic, const wxString &item, size_t *size, wxIPCFormat format)
Handle commands with a reply.
Definition ipc_api.cpp:99
Implement LocalServerApi using a filesystem fifo/socket.
Definition ipc_api.h:102
Base interface for local server command handling.
Definition local_api.h:61
std::function< bool(const std::string &)> open_file_cb
Callback invoked on open command with a file path argument.
Definition local_api.h:76
EventVar on_raise
Notified on the Raise command.
Definition local_api.h:70
EventVar on_quit
Notified on the Quit command.
Definition local_api.h:73
Server and client CLI api implementations.
Enhanced logging interface on top of wx/log.h.