blob: 68cce10e5430cda184c53cea76cbfc8d97919463 [file] [log] [blame]
Shad Ansari01b0e652018-04-05 21:02:53 +00001/*
Girish Gowdraa707e7c2019-11-07 11:36:13 +05302 * Copyright 2018-present Open Networking Foundation
Shad Ansari01b0e652018-04-05 21:02:53 +00003
Girish Gowdraa707e7c2019-11-07 11:36:13 +05304 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Shad Ansari01b0e652018-04-05 21:02:53 +00007
Girish Gowdraa707e7c2019-11-07 11:36:13 +05308 * http://www.apache.org/licenses/LICENSE-2.0
Shad Ansari01b0e652018-04-05 21:02:53 +00009
Girish Gowdraa707e7c2019-11-07 11:36:13 +053010 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Shad Ansari01b0e652018-04-05 21:02:53 +000016
17#include <iostream>
18#include <memory>
19#include <string>
nick7be062f2018-05-25 17:52:56 -040020#include <time.h>
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -040021#include <pthread.h>
Shad Ansari01b0e652018-04-05 21:02:53 +000022
23#include "Queue.h"
24#include <iostream>
25#include <sstream>
26
27#include "server.h"
Shad Ansarib7b0ced2018-05-11 21:53:32 +000028#include "core.h"
Nicolas Palpacuer3cad49d2018-07-02 14:03:24 -040029#include "state.h"
Orhan Kupusoglu1fd77072021-03-23 08:13:25 -070030#include "../src/core_utils.h"
Shad Ansari01b0e652018-04-05 21:02:53 +000031
Shad Ansarib7b0ced2018-05-11 21:53:32 +000032#include <grpc++/grpc++.h>
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +000033#include <voltha_protos/openolt.grpc.pb.h>
34#include <voltha_protos/tech_profile.grpc.pb.h>
Shad Ansari01b0e652018-04-05 21:02:53 +000035
36using grpc::Server;
37using grpc::ServerBuilder;
Girish Gowdra252f4972020-09-07 21:24:01 -070038using grpc::ResourceQuota;
Shad Ansari01b0e652018-04-05 21:02:53 +000039using grpc::ServerContext;
40using grpc::ServerWriter;
Shad Ansarib7b0ced2018-05-11 21:53:32 +000041using grpc::Status;
Shad Ansari01b0e652018-04-05 21:02:53 +000042
43const char *serverPort = "0.0.0.0:9191";
nick7be062f2018-05-25 17:52:56 -040044int signature;
Shad Ansari01b0e652018-04-05 21:02:53 +000045
Shad Ansari627b5782018-08-13 22:49:32 +000046Queue<openolt::Indication> oltIndQ;
47
Shad Ansari01b0e652018-04-05 21:02:53 +000048class OpenoltService final : public openolt::Openolt::Service {
49
Nicolas Palpacuere3fc0d22018-08-02 16:51:05 -040050 Status DisableOlt(
51 ServerContext* context,
52 const openolt::Empty* request,
53 openolt::Empty* response) override {
54 return Disable_();
55 }
56
57 Status ReenableOlt(
58 ServerContext* context,
59 const openolt::Empty* request,
60 openolt::Empty* response) override {
61 return Reenable_();
62 }
63
Shad Ansari01b0e652018-04-05 21:02:53 +000064 Status ActivateOnu(
65 ServerContext* context,
66 const openolt::Onu* request,
67 openolt::Empty* response) override {
68 return ActivateOnu_(
69 request->intf_id(),
70 request->onu_id(),
71 ((request->serial_number()).vendor_id()).c_str(),
kesavandc1f2db92020-08-31 15:32:06 +053072 ((request->serial_number()).vendor_specific()).c_str(), request->pir(), request->omcc_encryption());
Shad Ansari01b0e652018-04-05 21:02:53 +000073 }
74
Jonathan Davis70c21812018-07-19 15:32:10 -040075 Status DeactivateOnu(
76 ServerContext* context,
77 const openolt::Onu* request,
78 openolt::Empty* response) override {
79 return DeactivateOnu_(
80 request->intf_id(),
81 request->onu_id(),
82 ((request->serial_number()).vendor_id()).c_str(),
83 ((request->serial_number()).vendor_specific()).c_str());
84 }
85
86 Status DeleteOnu(
87 ServerContext* context,
88 const openolt::Onu* request,
89 openolt::Empty* response) override {
90 return DeleteOnu_(
91 request->intf_id(),
92 request->onu_id(),
93 ((request->serial_number()).vendor_id()).c_str(),
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -070094 ((request->serial_number()).vendor_specific()).c_str());
Jonathan Davis70c21812018-07-19 15:32:10 -040095 }
96
Shad Ansari01b0e652018-04-05 21:02:53 +000097 Status OmciMsgOut(
98 ServerContext* context,
99 const openolt::OmciMsg* request,
100 openolt::Empty* response) override {
101 return OmciMsgOut_(
102 request->intf_id(),
103 request->onu_id(),
104 request->pkt());
105 }
106
Shad Ansarif2e27a42018-04-26 22:37:38 +0000107 Status OnuPacketOut(
108 ServerContext* context,
109 const openolt::OnuPacket* request,
110 openolt::Empty* response) override {
111 return OnuPacketOut_(
112 request->intf_id(),
113 request->onu_id(),
Craig Lutgen967a1d02018-11-27 10:41:51 -0600114 request->port_no(),
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800115 request->gemport_id(),
Shad Ansarif2e27a42018-04-26 22:37:38 +0000116 request->pkt());
117 }
118
Nicolas Palpacuerb78def42018-06-07 12:55:26 -0400119 Status UplinkPacketOut(
120 ServerContext* context,
121 const openolt::UplinkPacket* request,
122 openolt::Empty* response) override {
123 return UplinkPacketOut_(
124 request->intf_id(),
125 request->pkt());
126 }
127
Shad Ansari01b0e652018-04-05 21:02:53 +0000128 Status FlowAdd(
129 ServerContext* context,
130 const openolt::Flow* request,
131 openolt::Empty* response) override {
Girish Gowdra252f4972020-09-07 21:24:01 -0700132 return FlowAddWrapper_(request);
133
Shad Ansari01b0e652018-04-05 21:02:53 +0000134 }
135
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -0400136 Status FlowRemove(
137 ServerContext* context,
138 const openolt::Flow* request,
139 openolt::Empty* response) override {
Girish Gowdra252f4972020-09-07 21:24:01 -0700140 return FlowRemoveWrapper_(request);
Nicolas Palpacueredfaa0c2018-07-05 15:05:27 -0400141 }
142
Shad Ansari01b0e652018-04-05 21:02:53 +0000143 Status EnableIndication(
144 ServerContext* context,
145 const ::openolt::Empty* request,
146 ServerWriter<openolt::Indication>* writer) override {
Shad Ansariedef2132018-08-10 22:14:50 +0000147
nick7be062f2018-05-25 17:52:56 -0400148 std::cout << "Connection to Voltha established. Indications enabled"
149 << std::endl;
Nicolas Palpacuer3cad49d2018-07-02 14:03:24 -0400150
Burak Gurdag30db4822021-03-10 21:30:01 +0000151 if (state.previously_connected()) {
Nicolas Palpacuerfbc0d7d2018-08-23 14:46:42 -0400152 // Reconciliation / recovery case
Nicolas Palpacuer135ce812018-08-30 09:04:34 -0400153 std::cout << "Reconciliation / Recovery case" << std::endl;
Nicolas Palpacuerfbc0d7d2018-08-23 14:46:42 -0400154 if (state.is_activated()){
155 // Adding extra olt indication of current state
156 openolt::Indication ind;
157 openolt::OltIndication* oltInd = new openolt::OltIndication();
158 if (state.is_activated()) {
159 oltInd->set_oper_state("up");
Nicolas Palpacuer135ce812018-08-30 09:04:34 -0400160 std::cout << "Extra OLT indication up" << std::endl;
Nicolas Palpacuerfbc0d7d2018-08-23 14:46:42 -0400161 } else {
162 oltInd->set_oper_state("down");
Nicolas Palpacuer135ce812018-08-30 09:04:34 -0400163 std::cout << "Extra OLT indication down" << std::endl;
Nicolas Palpacuerfbc0d7d2018-08-23 14:46:42 -0400164 }
165 ind.set_allocated_olt_ind(oltInd);
166 oltIndQ.push(ind);
167 }
168 }
169
Shad Ansariedef2132018-08-10 22:14:50 +0000170 state.connect();
171
172 while (state.is_connected()) {
Girish Gowdra96461052019-11-22 20:13:59 +0530173 std::pair<openolt::Indication, bool> ind = oltIndQ.pop(COLLECTION_PERIOD*1000, 1000);
Shad Ansariedef2132018-08-10 22:14:50 +0000174 if (ind.second == false) {
175 /* timeout - do lower priority periodic stuff like stats */
176 stats_collection();
177 continue;
178 }
179 openolt::Indication oltInd = ind.first;
Nicolas Palpacuer3cad49d2018-07-02 14:03:24 -0400180 bool isConnected = writer->Write(oltInd);
Nicolas Palpacuer58d252c2018-06-06 11:19:04 -0400181 if (!isConnected) {
182 //Lost connectivity to this Voltha instance
183 //Put the indication back in the queue for next connecting instance
184 oltIndQ.push(oltInd);
Shad Ansariedef2132018-08-10 22:14:50 +0000185 state.disconnect();
Nicolas Palpacuer58d252c2018-06-06 11:19:04 -0400186 }
Shad Ansari01b0e652018-04-05 21:02:53 +0000187 //oltInd.release_olt_ind()
188 }
Nicolas Palpacuer3cad49d2018-07-02 14:03:24 -0400189
Shad Ansari01b0e652018-04-05 21:02:53 +0000190 return Status::OK;
191 }
nick7be062f2018-05-25 17:52:56 -0400192
193 Status HeartbeatCheck(
194 ServerContext* context,
195 const openolt::Empty* request,
196 openolt::Heartbeat* response) override {
197 response->set_heartbeat_signature(signature);
198
199 return Status::OK;
200 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400201
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400202 Status EnablePonIf(
203 ServerContext* context,
204 const openolt::Interface* request,
205 openolt::Empty* response) override {
206
207 return EnablePonIf_(request->intf_id());
208 }
209
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000210 /*Status GetPonIf(
Shad Ansaricb208782019-07-02 20:53:40 +0000211 ServerContext* context,
212 const openolt::Interface* request,
213 openolt::IntfIndication* response) override {
214
215 // TODO - Return the oper status of the pon interface
216 return Status::OK;
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000217 }*/
Shad Ansaricb208782019-07-02 20:53:40 +0000218
Nicolas Palpacuer05ea0ea2018-07-06 11:47:21 -0400219 Status DisablePonIf(
220 ServerContext* context,
221 const openolt::Interface* request,
222 openolt::Empty* response) override {
223
224 return DisablePonIf_(request->intf_id());
225 }
Nicolas Palpacuer0f19b1a2018-06-07 17:29:31 -0400226
Nicolas Palpacuer65d04472018-09-06 15:53:37 -0400227 Status CollectStatistics(
228 ServerContext* context,
229 const openolt::Empty* request,
230 openolt::Empty* response) override {
231
232 stats_collection();
233
234 return Status::OK;
235 }
236
Nicolas Palpacuer45180662018-08-02 14:01:51 -0400237 Status Reboot(
238 ServerContext* context,
239 const openolt::Empty* request,
240 openolt::Empty* response) override {
241
Thiyagarajan Subramani89fffc02019-05-13 21:33:20 +0000242 uint8_t ret = system("shutdown -r now");
Nicolas Palpacuer45180662018-08-02 14:01:51 -0400243
244 return Status::OK;
245
246 }
247
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400248 Status GetDeviceInfo(
249 ServerContext* context,
250 const openolt::Empty* request,
251 openolt::DeviceInfo* response) override {
252
253 GetDeviceInfo_(response);
254
255 return Status::OK;
256
257 }
258
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800259 Status CreateTrafficSchedulers(
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700260 ServerContext* context,
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800261 const tech_profile::TrafficSchedulers* request,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700262 openolt::Empty* response) override {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800263 CreateTrafficSchedulers_(request);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700264 return Status::OK;
265 };
Nicolas Palpacuerdff96792018-09-06 14:59:32 -0400266
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800267 Status RemoveTrafficSchedulers(
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700268 ServerContext* context,
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800269 const tech_profile::TrafficSchedulers* request,
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700270 openolt::Empty* response) override {
Girish Gowdruc8ed2ef2019-02-13 08:18:44 -0800271 RemoveTrafficSchedulers_(request);
272 return Status::OK;
273 };
274
275 Status CreateTrafficQueues(
276 ServerContext* context,
277 const tech_profile::TrafficQueues* request,
278 openolt::Empty* response) override {
279 CreateTrafficQueues_(request);
280 return Status::OK;
281 };
282
283 Status RemoveTrafficQueues(
284 ServerContext* context,
285 const tech_profile::TrafficQueues* request,
286 openolt::Empty* response) override {
287 RemoveTrafficQueues_(request);
Girish Gowdru7c4ec2d2018-10-25 00:29:54 -0700288 return Status::OK;
289 };
Nicolas Palpacuer45180662018-08-02 14:01:51 -0400290
Burak Gurdagc78b9e12019-11-29 11:14:51 +0000291 Status PerformGroupOperation(
292 ServerContext* context,
293 const openolt::Group* request,
294 openolt::Empty* response) override {
295 return PerformGroupOperation_(request);
296 };
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800297
Burak Gurdageb4ca2e2020-06-15 07:48:26 +0000298 Status DeleteGroup(
299 ServerContext* context,
300 const openolt::Group* request,
301 openolt::Empty* response) override {
302 return DeleteGroup_(request->group_id());
303 };
304
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800305 Status OnuItuPonAlarmSet(
306 ServerContext* context,
kesavandc1f2db92020-08-31 15:32:06 +0530307 const config::OnuItuPonAlarm* request,
Jason Huang5d9ab1a2020-04-15 16:53:49 +0800308 openolt::Empty* response) override {
309 return OnuItuPonAlarmSet_(request);
310 };
Jason Huang1d9cfce2020-05-20 22:58:47 +0800311
312 Status GetLogicalOnuDistanceZero(
313 ServerContext* context,
314 const openolt::Onu* request,
315 openolt::OnuLogicalDistance* response) override {
316 return GetLogicalOnuDistanceZero_(
317 request->intf_id(),
318 response);
319 };
320
321 Status GetLogicalOnuDistance(
322 ServerContext* context,
323 const openolt::Onu* request,
324 openolt::OnuLogicalDistance* response) override {
325 return GetLogicalOnuDistance_(
326 request->intf_id(),
327 request->onu_id(),
328 response);
329 };
Burak Gurdag74e3ab82020-12-17 13:35:06 +0000330
331 Status GetOnuStatistics(
332 ServerContext* context,
333 const openolt::Onu* request,
334 openolt::OnuStatistics* response) override {
335 return GetOnuStatistics_(
336 request->intf_id(),
337 request->onu_id(),
338 response);
339 }
340
341 Status GetGemPortStatistics(
342 ServerContext* context,
343 const openolt::OnuPacket* request,
344 openolt::GemPortStatistics* response) override {
345 return GetGemPortStatistics_(
346 request->intf_id(),
347 request->gemport_id(),
348 response);
349 }
Shad Ansari01b0e652018-04-05 21:02:53 +0000350};
351
Orhan Kupusoglu1fd77072021-03-23 08:13:25 -0700352bool RunServer(int argc, char** argv) {
Thiyagarajan Subramani03bc66f2020-04-01 15:58:53 +0530353 std::string ipAddress = "0.0.0.0";
Orhan Kupusoglu1fd77072021-03-23 08:13:25 -0700354 bool tls_enabled = false;
355 std::pair<grpc_ssl_client_certificate_request_type, bool> grpc_security;
356 std::shared_ptr<grpc::ServerCredentials> credentials;
Shad Ansari01b0e652018-04-05 21:02:53 +0000357
Thiyagarajan Subramani03bc66f2020-04-01 15:58:53 +0530358 for (int i = 1; i < argc; ++i) {
359 if(strcmp(argv[i-1], "--interface") == 0 || (strcmp(argv[i-1], "--intf") == 0)) {
360 ipAddress = get_ip_address(argv[i]);
361 break;
362 }
363 }
Shad Ansari01b0e652018-04-05 21:02:53 +0000364
Orhan Kupusoglu1fd77072021-03-23 08:13:25 -0700365 for (int i = 1; i < argc; ++i) {
366 if (strcmp(argv[i-1], "--enable-tls") == 0) {
367 grpc_security = get_grpc_tls_option(argv[i]);
368 if (grpc_security.second) {
369 tls_enabled = true;
370 } else {
371 std::cerr << "unknown security option: \"" << argv[i-1] << " " << argv[i] << "\"\n";
372 return false;
373 };
374 break;
375 }
376 }
377
378 if (tls_enabled) {
379 std::string dir_cert{"./keystore"};
380 auto read_root_crt = read_from_txt_file(dir_cert + "/root.crt");
381 auto read_server_key = read_from_txt_file(dir_cert + "/server.key");
382 auto read_server_crt = read_from_txt_file(dir_cert + "/server.crt");
383
384 if (read_root_crt.second && read_server_key.second && read_server_crt.second) {
385 std::cout << "certificate files read successfully\n";
386 } else {
387 std::cerr << std::boolalpha << "certificate files read failed - root.crt: " << read_root_crt.second
388 << ", server.key: " << read_server_key.second
389 << ", server.crt: " << read_server_crt.second << '\n';
390 return false;
391 }
392
393 std::string root_crt = read_root_crt.first;
394 std::string server_key = read_server_key.first;
395 std::string server_crt = read_server_crt.first;
396
397 grpc::SslServerCredentialsOptions ssl_opts{grpc_security.first};
398 ssl_opts.pem_root_certs = root_crt;
399 grpc::SslServerCredentialsOptions::PemKeyCertPair keycert = {server_key, server_crt};
400 ssl_opts.pem_key_cert_pairs.push_back(keycert);
401 credentials = grpc::SslServerCredentials(ssl_opts);
402 } else {
403 credentials = grpc::InsecureServerCredentials();
404 }
405
Thiyagarajan Subramani03bc66f2020-04-01 15:58:53 +0530406 serverPort = ipAddress.append(":9191").c_str();
407 OpenoltService service;
408 std::string server_address(serverPort);
Girish Gowdra252f4972020-09-07 21:24:01 -0700409 ::ServerBuilder builder;
410 ::ResourceQuota quota;
411 quota.SetMaxThreads(GRPC_THREAD_POOL_SIZE);
412 builder.SetResourceQuota(quota);
Orhan Kupusoglu1fd77072021-03-23 08:13:25 -0700413 builder.AddListeningPort(server_address, credentials);
Thiyagarajan Subramani03bc66f2020-04-01 15:58:53 +0530414 builder.RegisterService(&service);
nick7be062f2018-05-25 17:52:56 -0400415
Thiyagarajan Subramani03bc66f2020-04-01 15:58:53 +0530416 std::unique_ptr<Server> server(builder.BuildAndStart());
nick7be062f2018-05-25 17:52:56 -0400417
Thiyagarajan Subramani03bc66f2020-04-01 15:58:53 +0530418 time_t now;
419 time(&now);
420 signature = (int)now;
Shad Ansari01b0e652018-04-05 21:02:53 +0000421
Thiyagarajan Subramani03bc66f2020-04-01 15:58:53 +0530422 std::cout << "Server listening on " << server_address
423 << ", connection signature : " << signature << std::endl;
424
Orhan Kupusoglu1fd77072021-03-23 08:13:25 -0700425#ifdef TEST_MODE
426 server->Shutdown();
427#else
Thiyagarajan Subramani03bc66f2020-04-01 15:58:53 +0530428 server->Wait();
Orhan Kupusoglu1fd77072021-03-23 08:13:25 -0700429#endif
430
431 return true;
Shad Ansari01b0e652018-04-05 21:02:53 +0000432}