Руслан Урядинский / libuavcan

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers restart_request_server.hpp Source File

restart_request_server.hpp

00001 /*
00002  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
00003  */
00004 
00005 #ifndef UAVCAN_PROTOCOL_RESTART_REQUEST_SERVER_HPP_INCLUDED
00006 #define UAVCAN_PROTOCOL_RESTART_REQUEST_SERVER_HPP_INCLUDED
00007 
00008 #include <uavcan/debug.hpp>
00009 #include <uavcan/node/service_server.hpp>
00010 #include <uavcan/util/method_binder.hpp>
00011 #include <uavcan/protocol/RestartNode.hpp>
00012 
00013 namespace uavcan
00014 {
00015 /**
00016  * Implement this interface in the application to support the standard node restart service.
00017  */
00018 class UAVCAN_EXPORT IRestartRequestHandler
00019 {
00020 public:
00021     virtual ~IRestartRequestHandler() { }
00022 
00023     /**
00024      * This method shall do either:
00025      *  - restart the local node immediately;
00026      *  - initiate the restart procedure to complete it asynchronously;
00027      *  - reject the restart request and return false.
00028      *
00029      * If the restart requets was accepted, this method shall either return true or don't return at all.
00030      */
00031     virtual bool handleRestartRequest(NodeID request_source) = 0;
00032 };
00033 
00034 /**
00035  * Convenience class for supporting the standard node restart service.
00036  * Highly recommended to use.
00037  */
00038 class UAVCAN_EXPORT RestartRequestServer : Noncopyable
00039 {
00040     typedef MethodBinder<const RestartRequestServer*,
00041                          void (RestartRequestServer::*)(const ReceivedDataStructure<protocol::RestartNode::Request>&,
00042                                                         protocol::RestartNode::Response&) const> RestartNodeCallback;
00043 
00044     ServiceServer<protocol::RestartNode, RestartNodeCallback> srv_;
00045     IRestartRequestHandler* handler_;
00046 
00047     void handleRestartNode(const ReceivedDataStructure<protocol::RestartNode::Request>& request,
00048                            protocol::RestartNode::Response& response) const
00049     {
00050         UAVCAN_TRACE("RestartRequestServer", "Request from snid=%i", int(request.getSrcNodeID().get()));
00051         response.ok = false;
00052         if (request.magic_number == protocol::RestartNode::Request::MAGIC_NUMBER)
00053         {
00054             if (handler_)
00055             {
00056                 response.ok = handler_->handleRestartRequest(request.getSrcNodeID());
00057             }
00058             UAVCAN_TRACE("RestartRequestServer", "%s", (response.ok ? "Accepted" : "Rejected"));
00059         }
00060         else
00061         {
00062             UAVCAN_TRACE("RestartRequestServer", "Invalid magic number 0x%llx",
00063                          static_cast<unsigned long long>(request.magic_number));
00064         }
00065     }
00066 
00067 public:
00068     explicit RestartRequestServer(INode& node)
00069         : srv_(node)
00070         , handler_(UAVCAN_NULLPTR)
00071     { }
00072 
00073     /**
00074      * Restart request handler configuration.
00075      * All restart requests will be explicitly rejected if there's no handler installed.
00076      */
00077     IRestartRequestHandler* getHandler() const { return handler_; }
00078     void setHandler(IRestartRequestHandler* handler) { handler_ = handler; }
00079 
00080     /**
00081      * Starts the server.
00082      * Returns negative error code.
00083      */
00084     int start()
00085     {
00086         return srv_.start(RestartNodeCallback(this, &RestartRequestServer::handleRestartNode));
00087     }
00088 };
00089 
00090 }
00091 
00092 #endif // UAVCAN_PROTOCOL_RESTART_REQUEST_SERVER_HPP_INCLUDED