Broker.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef __ccp_Broker_h__
00041 #define __ccp_Broker_h__
00042
00043 #include "mw/nl/can/constants.h"
00044 #include "mw/nl/can/canETAGS.h"
00045 #include "mw/common/UID.h"
00046
00047
00048 namespace famouso {
00049 namespace mw {
00050 namespace nl {
00051 namespace CAN {
00052 namespace ccp {
00053 using namespace famouso::mw::nl::CAN::detail;
00054
00055
00056
00057
00058
00059
00060 template < class CAN_Driver >
00061 class Broker {
00062
00063 typedef typename CAN_Driver::MOB::IDType IDType;
00064
00065 UID knownNodes [constants::ccp::count];
00066 uint8_t ccp_stage;
00067 UID uid;
00068
00069 uint8_t search_tx_node(const UID &uid) {
00070 uint8_t freeplace = 0xff;
00071 for (uint8_t i = 0; i < constants::ccp::count; ++i) {
00072 if (knownNodes[i] == UID()) {
00073 freeplace = i;
00074 } else {
00075 if (knownNodes[i] == uid) return i;
00076 }
00077 }
00078 if (freeplace != 0xff)
00079 knownNodes[freeplace] = uid;
00080 return freeplace;
00081 }
00082
00083 bool handle_ccp_rsi(typename CAN_Driver::MOB &mob) {
00084 IDType *id = &mob.id();
00085
00086 uint8_t nibble = id->ccp_nibble();
00087 uint8_t stage = id->ccp_stage();
00088 uint8_t tx_node = constants::Broker_tx_node;
00089
00090
00091 if (!(ccp_stage == stage)) {
00092 ::logging::log::emit< ::logging::Error>()
00093 << PROGMEMSTRING("received ccp rsi for stage ")
00094 << static_cast<uint32_t>(stage)
00095 << PROGMEMSTRING(" but I am in stage ")
00096 << static_cast<uint32_t>(ccp_stage)
00097 << PROGMEMSTRING(" dropping it.")
00098 << ::logging::log::endl;
00099 return false;
00100 } else {
00101
00102 --ccp_stage;
00103
00104
00105
00106 uid.tab()[7] = (uid.tab()[7] & 0xF0) | stage;
00107
00108 uid.tab()[7-(stage>>1)] |= (stage & 0x1) ? (nibble << 4) : nibble;
00109
00110
00111 id->prio(0xFD);
00112 id->etag(famouso::mw::nl::CAN::detail::ETAGS::CCP_SSI);
00113 mob.len(8);
00114
00115
00116 for (uint8_t i = 0; i < 8; ++i) {
00117 mob.data()[i] = uid.tab()[i];
00118 }
00119
00120 if (!stage) {
00121
00122
00123 if ((tx_node = search_tx_node(uid)) > constants::Broker_tx_node) {
00124 ::logging::log::emit< ::logging::Error>()
00125 << PROGMEMSTRING("more than ")
00126 << static_cast<short>(constants::Broker_tx_node)
00127 << PROGMEMSTRING(" nodes configured that means something went wrong")
00128 << ::logging::log::endl;
00129 return false;
00130 } else {
00131 ::logging::log::emit() << PROGMEMSTRING("CCP")
00132 << ::logging::log::tab << ::logging::log::tab
00133 << ::logging::log::tab << PROGMEMSTRING("-- NodeID [");
00134 for (uint8_t i = 0;i < 8;++i) {
00135 uint8_t c = uid.tab()[i];
00136 if ((c < 32) || (c > 126)) c = 32;
00137 ::logging::log::emit() << c ;
00138 }
00139 ::logging::log::emit() << PROGMEMSTRING("] -> ")
00140 << ::logging::log::hex
00141 << PROGMEMSTRING("tx_node [")
00142 << static_cast<uint16_t>(tx_node)
00143 << PROGMEMSTRING("] ")
00144 << uid.value()
00145 << ::logging::log::endl;
00146 }
00147 ccp_stage = 15;
00148 uid = UID();
00149 }
00150
00151
00152 id->tx_node(tx_node);
00153 }
00154 return true;
00155 }
00156 public:
00157 Broker() : ccp_stage(15), uid() {}
00158
00159 bool handle_ccp_configure_request(typename CAN_Driver::MOB &mob, CAN_Driver& canDriver) {
00160 if (mob.id().etag() == famouso::mw::nl::CAN::detail::ETAGS::CCP_RSI) {
00161 if (handle_ccp_rsi(mob))
00162 canDriver.transmit(mob);
00163 return true;
00164 } else {
00165 return false;
00166 }
00167 }
00168
00169 uint8_t ccp_configure_tx_node(const UID &uid, CAN_Driver& canDriver) {
00170 return search_tx_node(uid);
00171 }
00172 };
00173
00174 }
00175 }
00176 }
00177 }
00178 }
00179
00180
00181 #endif