Apollo 10.0
自动驾驶开放平台
socket_can_monitor.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 The Apollo Authors. All Rights Reserved.
3 *
4 * 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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * 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 *****************************************************************************/
16
18
19#include <linux/can.h>
20#include <linux/can/raw.h>
21#include <net/if.h>
22#include <sys/ioctl.h>
23#include <sys/socket.h>
24#include <sys/types.h>
25#include <unistd.h>
26#include <string>
27
28#include "cyber/common/file.h"
29#include "cyber/common/log.h"
33
34DEFINE_string(socket_can_monitor_name, "SocketCanMonitor",
35 "Name of the CAN monitor.");
36DEFINE_double(socket_can_monitor_interval, 3,
37 "Socket CAN status checking interval seconds.");
38DEFINE_string(socket_can_component_name, "SocketCAN",
39 "Name of the Socket CAN component in SystemStatus.");
40
41namespace apollo {
42namespace monitor {
43namespace {
44
45// Test Socket CAN on an open handler.
46bool SocketCanHandlerTest(const int dev_handler, std::string* message) {
47 // init config and state
48 // 1. set receive message_id filter, ie white list
49 struct can_filter filter[1];
50 filter[0].can_id = 0x000;
51 filter[0].can_mask = CAN_SFF_MASK;
52
53 int ret = setsockopt(dev_handler, SOL_CAN_RAW, CAN_RAW_FILTER, &filter,
54 sizeof(filter));
55 if (ret < 0) {
56 *message = "set message filter failed";
57 return false;
58 }
59
60 // 2. enable reception of can frames.
61 const int enable = 1;
62 ret = setsockopt(dev_handler, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &enable,
63 sizeof(enable));
64 if (ret < 0) {
65 *message = "Enable reception of can frames failed";
66 return false;
67 }
68
69 struct ifreq ifr;
70 std::strncpy(ifr.ifr_name, "can0", IFNAMSIZ);
71 if (ioctl(dev_handler, SIOCGIFINDEX, &ifr) < 0) {
72 *message = "ioctl failed";
73 return false;
74 }
75
76 // bind socket to network interface
77 struct sockaddr_can addr;
78 addr.can_family = AF_CAN;
79 addr.can_ifindex = ifr.ifr_ifindex;
80 ret = bind(dev_handler, reinterpret_cast<struct sockaddr*>(&addr),
81 sizeof(addr));
82
83 if (ret < 0) {
84 *message = "bind socket can failed";
85 return false;
86 }
87
88 return true;
89}
90
91// Open a Socket CAN handler and test.
92bool SocketCanTest(std::string* message) {
93 const int dev_handler = socket(PF_CAN, SOCK_RAW, CAN_RAW);
94 if (dev_handler < 0) {
95 *message = "Open can device failed";
96 return false;
97 }
98 const bool ret = SocketCanHandlerTest(dev_handler, message);
99 close(dev_handler);
100 return ret;
101}
102
103} // namespace
104
106 : RecurrentRunner(FLAGS_socket_can_monitor_name,
107 FLAGS_socket_can_monitor_interval) {}
108
109void SocketCanMonitor::RunOnce(const double current_time) {
110 auto manager = MonitorManager::Instance();
111 Component* component = apollo::common::util::FindOrNull(
112 *manager->GetStatus()->mutable_components(),
113 FLAGS_socket_can_component_name);
114 if (component == nullptr) {
115 // Canbus is not monitored in current mode, skip.
116 return;
117 }
118 auto* status = component->mutable_other_status();
119 status->clear_status();
120
121 std::string message;
122 const bool ret = SocketCanTest(&message);
124 ret ? ComponentStatus::OK : ComponentStatus::ERROR, message, status);
125}
126
127} // namespace monitor
128} // namespace apollo
void RunOnce(const double current_time) override
static void EscalateStatus(const ComponentStatus::Status new_status, const std::string &message, ComponentStatus *current_status)
Some map util functions.
class register implement
Definition arena_queue.h:37
DEFINE_string(socket_can_monitor_name, "SocketCanMonitor", "Name of the CAN monitor.")
DEFINE_double(socket_can_monitor_interval, 3, "Socket CAN status checking interval seconds.")