Derivate socketcan to multiple child depending upon socket CAN type.
authorRomain Forlot <romain.forlot@iot.bzh>
Wed, 3 May 2017 15:52:34 +0000 (17:52 +0200)
committerRomain Forlot <romain.forlot@iot.bzh>
Wed, 3 May 2017 15:52:34 +0000 (17:52 +0200)
Use to initialize raw, bcm and later isotp socket. Now we should have,
1 BCM socket by signal to make filter on them. 1 raw socket by devices is kept
to use diagnostic manager as is.

Change-Id: Icb2daddf67039479f72bc487d53971adc9aba638
Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
CAN-binder/low-can-binding/utils/socketcan-bcm.cpp [new file with mode: 0644]
CAN-binder/low-can-binding/utils/socketcan-bcm.hpp [new file with mode: 0644]
CAN-binder/low-can-binding/utils/socketcan-raw.cpp [new file with mode: 0644]
CAN-binder/low-can-binding/utils/socketcan-raw.hpp [new file with mode: 0644]
CAN-binder/low-can-binding/utils/socketcan.cpp
CAN-binder/low-can-binding/utils/socketcan.hpp

diff --git a/CAN-binder/low-can-binding/utils/socketcan-bcm.cpp b/CAN-binder/low-can-binding/utils/socketcan-bcm.cpp
new file mode 100644 (file)
index 0000000..cab9906
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015, 2016 ,2017 "IoT.bzh"
+ * Author "Romain Forlot" <romain.forlot@iot.bzh>
+ * Author "Loïc Collignon" <loic.collignon@iot.bzh>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "socketcan-bcm.hpp"
+
+namespace utils
+{
+       /// @brief Construct a default, invalid, socket.
+       socketcan_bcm_t::socketcan_bcm_t()
+               : socketcan_t{}
+       {}
+
+       /// @brief Construct a socket by moving an existing one.
+       socketcan_bcm_t::socketcan_bcm_t(socketcan_bcm_t&& s)
+               : socket_{s.socket_}
+       {
+               s.socket_ = INVALID_SOCKET;
+       }
+
+       /// @brief Destruct the socket.
+       socketcan_bcm_t::~socketcan_bcm_t()
+       {
+               if(socket_ != INVALID_SOCKET)
+                       ::close(socket_);
+       }
+
+       /// @brief Open a raw socket CAN.
+       /// @param[in] device_name is the kernel network device name of the CAN interface.
+       ///
+       /// @return Upon successful completion, shall return a non-negative integer, the socket file descriptor. Otherwise, a value of -1 shall be returned and errno set to indicate the error.
+       int socketcan_bcm_t::open(std::string device_name)
+       {
+               close();
+               
+               struct ifreq ifr;
+               socket_ = open(PF_CAN, SOCK_DGRAM, CAN_BCM);
+
+               // Attempts to open a socket to CAN bus
+               ::strcpy(ifr.ifr_name, device_name.c_str());
+               DEBUG(binder_interface, "%s: ifr_name is : %s", __FUNCTION__, ifr.ifr_name);
+               if(::ioctl(socket_, SIOCGIFINDEX, &ifr) < 0)
+               {
+                       ERROR(binder_interface, "%s: ioctl failed. Error was : %s", __FUNCTION__, strerror(errno));
+                       close();
+               }
+               else
+               {
+                       tx_address_.can_family = AF_CAN;
+                       tx_address_.can_ifindex = ifr.ifr_ifindex;
+
+                       if(connect((struct sockaddr *)&tx_address_, sizeof(tx_address_)) < 0)
+                       {
+                               ERROR(binder_interface, "%s: Connect failed. %s", __FUNCTION__, strerror(errno));
+                               close();
+                       }
+               }
+               return socket_;
+       }
+}
\ No newline at end of file
diff --git a/CAN-binder/low-can-binding/utils/socketcan-bcm.hpp b/CAN-binder/low-can-binding/utils/socketcan-bcm.hpp
new file mode 100644 (file)
index 0000000..63c728c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015, 2016 ,2017 "IoT.bzh"
+ * Author "Romain Forlot" <romain.forlot@iot.bzh>
+ * Author "Loïc Collignon" <loic.collignon@iot.bzh>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "socketcan.hpp"
+
+namespace utils
+{
+       struct simple_bcm_msg
+       {
+               struct bcm_msg_head msg_head;
+               struct can_frame frames;
+       };
+
+       struct canfd_bcm_msg
+       {
+               struct bcm_msg_head msg_head;
+               struct canfd_frame frames;
+               canfd_bcm_msg() { msg_head.flags |= CAN_FD_FRAME; }
+       };
+
+       class socketcan_bcm_t : public socketcan_t
+       {
+       public:
+               socketcan_bcm_t();
+               socketcan_bcm_t(const socketcan_bcm_t&) = delete;
+               socketcan_bcm_t(socketcan_bcm_t&&);
+               virtual ~socketcan_bcm_t();
+
+               virtual int open(std::string device_name);
+
+       private:
+               int connect(const struct sockaddr* addr, socklen_t len);
+       };
+//     socketcan_bcm_t& operator<<(socketcan_bcm_t& s, const struct simple_bcm_msg& obj);
+//     socketcan_bcm_t& operator<<(socketcan_bcm_t& s, const struct canfd_bcm_msg& obj);
+}
diff --git a/CAN-binder/low-can-binding/utils/socketcan-raw.cpp b/CAN-binder/low-can-binding/utils/socketcan-raw.cpp
new file mode 100644 (file)
index 0000000..2c2b54e
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015, 2016 ,2017 "IoT.bzh"
+ * Author "Romain Forlot" <romain.forlot@iot.bzh>
+ * Author "Loïc Collignon" <loic.collignon@iot.bzh>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "socketcan-raw.hpp"
+
+namespace utils
+{
+       /// @brief Construct a default, invalid, socket.
+       socketcan_raw_t::socketcan_raw_t()
+               : socketcan_t{}, socket_{INVALID_SOCKET}
+       {}
+
+       /// @brief Construct a socket by moving an existing one.
+       socketcan_raw_t::socketcan_raw_t(socketcan_raw_t&& s)
+               : socket_{s.socket_}
+       {
+               s.socket_ = INVALID_SOCKET;
+       }
+
+       /// @brief Destruct the socket.
+       socketcan_raw_t::~socketcan_raw_t()
+       {
+               if(socket_ != INVALID_SOCKET)
+                       ::close(socket_);
+       }
+
+       /// @brief Open a raw socket CAN.
+       /// @param[in] device_name is the kernel network device name of the CAN interface.
+       ///
+       /// @return Upon successful completion, shall return a non-negative integer, the socket file descriptor. Otherwise, a value of -1 shall be returned and errno set to indicate the error.
+       int socketcan_raw_t::open(std::string device_name)
+       {
+               close();
+               
+               struct ifreq ifr;
+               socket_ = open(PF_CAN, SOCK_RAW, CAN_RAW);
+
+               // Attempts to open a socket to CAN bus
+               ::strcpy(ifr.ifr_name, device_name.c_str());
+               DEBUG(binder_interface, "%s: ifr_name is : %s", __FUNCTION__, ifr.ifr_name);
+               if(::ioctl(socket_, SIOCGIFINDEX, &ifr) < 0)
+               {
+                       ERROR(binder_interface, "%s: ioctl failed. Error was : %s", __FUNCTION__, strerror(errno));
+                       close();
+               }
+               else
+               {
+                       tx_address_.can_family = AF_CAN;
+                       tx_address_.can_ifindex = ifr.ifr_ifindex;
+
+                       if(bind((struct sockaddr *)&tx_address_, sizeof(tx_address_)) < 0)
+                       {
+                               ERROR(binder_interface, "%s: Bind failed. %s", __FUNCTION__, strerror(errno));
+                               close();
+                       }
+               }
+               return socket_;
+       }
+}
\ No newline at end of file
diff --git a/CAN-binder/low-can-binding/utils/socketcan-raw.hpp b/CAN-binder/low-can-binding/utils/socketcan-raw.hpp
new file mode 100644 (file)
index 0000000..3c91029
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015, 2016 ,2017 "IoT.bzh"
+ * Author "Romain Forlot" <romain.forlot@iot.bzh>
+ * Author "Loïc Collignon" <loic.collignon@iot.bzh>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "socketcan.hpp"
+
+namespace utils
+{
+       class socketcan_raw_t : public socketcan_t
+       {
+       public:
+               socketcan_raw_t();
+               socketcan_raw_t(const socketcan_raw_t&) = delete;
+               socketcan_raw_t(socketcan_raw_t&&);
+               virtual ~socketcan_raw_t();
+
+               virtual int open(std::string device_name);
+
+       private:
+               int bind(const struct sockaddr* addr, socklen_t len);
+       };
+}
index 0f2e01f..5a711c3 100644 (file)
@@ -104,39 +104,6 @@ namespace utils
                return socket_;
        }
 
-       /// @brief Open a raw socket CAN.
-       /// @param[in] device_name is the kernel network device name of the CAN interface.
-       ///
-       /// @return Upon successful completion, shall return a non-negative integer, the socket file descriptor. Otherwise, a value of -1 shall be returned and errno set to indicate the error.
-       int socketcan_t::open(std::string device_name)
-       {
-               close();
-               
-               struct ifreq ifr;
-               socket_ = open(PF_CAN, SOCK_DGRAM, CAN_BCM);
-
-               // Attempts to open a socket to CAN bus
-               ::strcpy(ifr.ifr_name, device_name.c_str());
-               DEBUG(binder_interface, "%s: ifr_name is : %s", __FUNCTION__, ifr.ifr_name);
-               if(::ioctl(socket_, SIOCGIFINDEX, &ifr) < 0)
-               {
-                       ERROR(binder_interface, "%s: ioctl failed. Error was : %s", __FUNCTION__, strerror(errno));
-                       close();
-               }
-               else
-               {
-                       tx_address_.can_family = AF_CAN;
-                       tx_address_.can_ifindex = ifr.ifr_ifindex;
-
-                       if(connect((struct sockaddr *)&tx_address_, sizeof(tx_address_)) < 0)
-                       {
-                               ERROR(binder_interface, "%s: Connect failed. %s", __FUNCTION__, strerror(errno));
-                               close();
-                       }
-               }
-               return socket_;
-       }
-
        socketcan_t& operator>>(socketcan_t& s, can_message_t& cm)
        {
                struct {
index 8a71d3a..391fb46 100644 (file)
 
 namespace utils
 {
-       struct simple_bcm_msg
-       {
-               struct bcm_msg_head msg_head;
-               struct can_frame frames;
-       };
-
-       struct canfd_bcm_msg
-       {
-               struct bcm_msg_head msg_head;
-               struct canfd_frame frames;
-               canfd_bcm_msg() { msg_head.flags |= CAN_FD_FRAME; }
-       };
-
        class socketcan_t
        {
        public:
                socketcan_t();
                socketcan_t(const socketcan_t&) = delete;
                socketcan_t(socketcan_t&&);
-               ~socketcan_t();
+               virtual ~socketcan_t();
 
                const struct sockaddr_can& get_tx_address() const;
                explicit operator bool() const;
 
                int socket() const;
-               int open(std::string device_name);
+               virtual int open(std::string device_name) = 0;
                int setopt(int level, int optname, const void* optval, socklen_t optlen);
                int close();
 
-       private:
+       protected:
                int socket_;
                struct sockaddr_can tx_address_;
 
                int open(int domain, int type, int protocol);
-               int bind(const struct sockaddr* addr, socklen_t len);
-               int connect(const struct sockaddr* addr, socklen_t len);
        };
 
        template <typename T>
@@ -83,9 +68,6 @@ namespace utils
                        ERROR(binder_interface, "%s: Error sending : %i %s", __FUNCTION__, errno, ::strerror(errno));
                return s;
        }
-       
-       socketcan_t& operator<<(socketcan_t& s, const struct simple_bcm_msg& obj);
-       socketcan_t& operator<<(socketcan_t& s, const struct canfd_bcm_msg& obj);
 
        socketcan_t& operator>>(socketcan_t& s, can_message_t& cm);
 }