KiCad PCB EDA Suite
Loading...
Searching...
No Matches
api_client.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <api/api_client.h>
21
22#include <cstring>
23
24#include <fmt/format.h>
25#include <wx/log.h>
26#include <wx/translation.h>
27
28
29KICAD_API_CLIENT::KICAD_API_CLIENT( int aTimeoutMs, bool aBlock ) :
30 m_socket(),
31 m_isOpen( false ),
32 m_isConnected( false ),
33 m_block( aBlock )
34{
35 int ret = nng_req0_open( &m_socket );
36
37 if( ret == 0 )
38 {
39 m_isOpen = true;
40 nng_socket_set_ms( m_socket, NNG_OPT_RECVTIMEO, aTimeoutMs );
41 nng_socket_set_ms( m_socket, NNG_OPT_SENDTIMEO, aTimeoutMs );
42 }
43 else
44 {
45 m_lastError = wxString::Format( wxS( "nng_req0_open failed: %s" ), wxString::FromUTF8( nng_strerror( ret ) ) );
46 }
47}
48
49
51{
52 if( m_isOpen )
53 nng_close( m_socket );
54}
55
56
57bool KICAD_API_CLIENT::Connect( const wxString& aSocketUrl )
58{
59 if( !m_isOpen )
60 return false;
61
62 if( m_isConnected )
63 return true;
64
65 int ret = nng_dial( m_socket, aSocketUrl.ToStdString().c_str(), nullptr, 0 );
66
67 if( ret != 0 )
68 {
69 m_lastError = wxString::Format( wxS( "nng_dial failed: %s" ), wxString::FromUTF8( nng_strerror( ret ) ) );
70 return false;
71 }
72
73 m_isConnected = true;
74 return true;
75}
76
77
79{
80 if( m_isOpen )
81 {
82 nng_close( m_socket );
83 m_isOpen = false;
84 m_isConnected = false;
85
86 int ret = nng_req0_open( &m_socket );
87
88 if( ret == 0 )
89 {
90 m_isOpen = true;
91 nng_socket_set_ms( m_socket, NNG_OPT_RECVTIMEO, 10000 );
92 nng_socket_set_ms( m_socket, NNG_OPT_SENDTIMEO, 10000 );
93 }
94 }
95}
96
97
98bool KICAD_API_CLIENT::Send( const google::protobuf::Message& aRequest, kiapi::common::ApiResponse& aResponse,
99 const std::string& aClientName )
100{
101 if( !IsConnected() )
102 {
103 m_lastError = wxS( "API client is not connected" );
104 return false;
105 }
106
107 kiapi::common::ApiRequest request;
108 request.mutable_header()->set_client_name( aClientName );
109
110 if( !request.mutable_message()->PackFrom( aRequest ) )
111 {
112 m_lastError = wxS( "Failed to pack command into ApiRequest" );
113 return false;
114 }
115
116 std::string requestStr = request.SerializeAsString();
117 void* sendBuf = nng_alloc( requestStr.size() );
118
119 if( !sendBuf )
120 {
121 m_lastError = wxS( "nng_alloc failed" );
122 return false;
123 }
124
125 std::memcpy( sendBuf, requestStr.data(), requestStr.size() );
126
127 int ret = nng_send( m_socket, sendBuf, requestStr.size(), NNG_FLAG_ALLOC );
128
129 if( ret != 0 )
130 {
131 nng_free( sendBuf, requestStr.size() );
132 m_lastError = wxString::Format( wxS( "nng_send failed: %s" ), wxString::FromUTF8( nng_strerror( ret ) ) );
133 return false;
134 }
135
136 char* reply = nullptr;
137 size_t replySize = 0;
138 int flags = m_block ? 0 : NNG_FLAG_NONBLOCK;
139
140 ret = nng_recv( m_socket, &reply, &replySize, NNG_FLAG_ALLOC | flags );
141
142 if( ret != 0 )
143 {
144 m_lastError = wxString::Format( wxS( "nng_recv failed: %s" ), wxString::FromUTF8( nng_strerror( ret ) ) );
145 return false;
146 }
147
148 std::string responseStr( reply, replySize );
149 nng_free( reply, replySize );
150
151 if( !aResponse.ParseFromString( responseStr ) )
152 {
153 m_lastError = wxS( "Failed to parse reply from KiCad" );
154 return false;
155 }
156
157 return true;
158}
KICAD_API_CLIENT(int aTimeoutMs=1000, bool aBlock=true)
wxString m_lastError
Definition api_client.h:62
bool Connect(const wxString &aSocketUrl)
nng_socket m_socket
Definition api_client.h:59
bool Send(const google::protobuf::Message &aRequest, kiapi::common::ApiResponse &aResponse, const std::string &aClientName="kicad")
Send a protobuf request to the KiCad API server and wait for a response.
bool IsConnected() const
Definition api_client.h:43