14 template <
class HalType,
class List0Type>
class Device;
16 class ActionCommandMsg;
20 template<
class HalType,
class List1Type,
class List3Type,
class List4Type,
int PeerCount,
class List0Type=List0,
class List2Type=EmptyList>
29 typedef List1Type List1;
30 typedef List2Type List2;
31 typedef List3Type List3;
32 typedef List4Type List4;
36 Channel () : dev(0), change(
false), inhi(
false), num(0), addr(0) {}
40 const DeviceType& device ()
const {
return *dev; }
42 uint8_t number ()
const {
return num; }
44 uint16_t address ()
const {
return addr; }
46 uint8_t peers ()
const {
return PeerCount; }
48 bool changed ()
const {
return change; }
50 void changed (
bool c) { change = c; }
52 void inhibit (
bool value) { inhi = value; }
54 bool inhibit ()
const {
return inhi; }
56 bool aesActive ()
const {
return getList1().aesActive(); }
64 uint16_t size ()
const {
65 uint16_t size =
sizeof(
Peer);
66 size += List3::size() + List4::size();
68 size += List1::size();
72 bool has (
const Peer& p)
const {
73 for( uint8_t i=0; i<peers(); ++i ) {
81 uint8_t peerfor (
const HMID& hmid)
const {
82 for( uint8_t i=0; i<peers(); ++i ) {
83 if( hmid == peer(i) ) {
90 Peer peer (uint8_t idx)
const {
92 uint16_t paddr = peerAddress(idx);
94 storage().getData(paddr,&result);
100 bool peer (
const Peer& p) {
102 uint8_t pidx = findpeer();
104 storage().setData(peerAddress(pidx),p);
105 getList3(pidx).single();
111 bool peer (
const Peer& p1,
const Peer& p2)
const {
114 uint8_t pidx1 = findpeer();
115 if( pidx1 != 0xff ) {
116 storage().setData(peerAddress(pidx1),p1);
117 uint8_t pidx2 = findpeer();
118 if( pidx2 != 0xff ) {
119 storage().setData(peerAddress(pidx2),p2);
120 if( p1.odd() ==
true ) {
121 getList3(pidx1).odd();
122 getList3(pidx2).even();
125 getList3(pidx2).odd();
126 getList3(pidx1).even();
138 bool deletepeer (uint8_t idx)
const {
139 return storage().setData(peerAddress(idx),
Peer());
142 uint8_t findpeer ()
const {
143 for(
int i=0; i<peers(); ++i ) {
144 if( peer(i).valid()==false ) {
151 bool deletepeer (
const Peer& p)
const {
152 for( uint8_t i=0; i<peers(); ++i ) {
161 storage().clearData(address(),size());
162 List1Type cl1 = getList1();
163 List2Type cl2 = getList2();
168 List1Type getList1 ()
const {
170 return List1Type(address());
173 List2Type getList2 ()
const {
174 return List2Type(address()+List1::size());
177 List3Type getList3 (
const Peer& p)
const {
178 uint16_t liststart = 0x00;
179 if( hasList3() ==
true ) {
180 for( uint8_t i=0; i<peers(); ++i ) {
182 liststart = peerAddress(i) +
sizeof(
Peer);
187 return List3Type(liststart);
190 List4Type getList4 (
const Peer& p)
const {
191 uint16_t liststart = 0x00;
192 if( hasList4() ==
true ) {
193 for( uint8_t i=0; i<peers(); ++i ) {
195 liststart = peerAddress(i) +
sizeof(
Peer) + List3::size();
200 return List4Type(liststart);
203 List3Type getList3 (uint8_t pidx)
const {
204 uint16_t liststart = 0x00;
205 if( hasList3() ==
true && pidx < peers() ) {
206 liststart = peerAddress(pidx) +
sizeof(
Peer);
208 return List3Type(liststart);
211 List4Type getList4 (uint8_t pidx)
const {
212 uint16_t liststart = 0x00;
213 if( hasList4() ==
true && pidx < peers() ) {
214 liststart = peerAddress(pidx) +
sizeof(
Peer) + List3::size();
216 return List4Type(liststart);
219 static bool hasList3 () {
220 return List3Type::size() > 0;
223 static bool hasList4 () {
224 return List4Type::size() > 0;
229 bool process (__attribute__((unused))
const ActionSetMsg& msg) {
237 bool process (__attribute__((unused))
const RemoteEventMsg& msg) {
241 bool process (__attribute__((unused))
const SensorEventMsg& msg) {
245 void patchStatus (__attribute__((unused))
Message& msg) {}
247 void configChanged () {}
250 uint16_t peerAddress (uint8_t pidx)
const {
251 if( pidx < PeerCount ) {
252 uint16_t offset =
sizeof(
Peer);
253 offset += List3::size() + List4::size();
255 offset += List1::size() + List2::size();
256 return addr + offset;
262 template <
class HalType,
class List1Type,
class List3Type,
int PeerCount,
class List0Type,
class StateMachine,
class List2Type=EmptyList>
272 bool changed ()
const {
return StateMachine::changed(); }
273 void changed (
bool c) { StateMachine::changed(c); }
276 BaseChannel::setup(dev,number,addr);
277 StateMachine::setup(this->getList1());
280 uint8_t status ()
const {
281 return StateMachine::status();
284 uint8_t flags ()
const {
285 uint8_t flags = StateMachine::flags();
286 if( this->device().battery().low() ==
true ) {
292 void status (uint8_t stat, uint16_t delay) {
293 StateMachine::status(stat,delay);
298 StateMachine::stop();
306 StateMachine::set( msg.value(), msg.ramp(), msg.delay() );
311 bool lg = msg.isLong();
313 uint8_t cnt = msg.counter();
314 List3Type l3 = BaseChannel::getList3(p);
315 if( l3.valid() ==
true ) {
317 typename List3Type::PeerList pl = lg ? l3.lg() : l3.sh();
319 if( lg ==
false || cnt != lastmsgcnt || pl.multiExec() ==
true ) {
321 StateMachine::remote(pl,cnt);
329 bool lg = msg.isLong();
331 uint8_t cnt = msg.counter();
332 uint8_t value = msg.value();
333 List3Type l3 = BaseChannel::getList3(p);
334 if( l3.valid() ==
true ) {
336 typename List3Type::PeerList pl = lg ? l3.lg() : l3.sh();
338 StateMachine::sensor(pl,cnt,value);
346 template <
class HalType,
class List0Type=List0>
353 virtual uint16_t size ()
const = 0;
354 virtual uint8_t number ()
const = 0;
355 virtual uint16_t address ()
const = 0;
356 virtual uint8_t peers ()
const = 0;
357 virtual bool changed ()
const = 0;
358 virtual void changed (
bool c) = 0;
359 virtual void inhibit (
bool value) = 0;
360 virtual bool inhibit ()
const = 0;
361 virtual bool aesActive ()
const = 0;
362 virtual bool has (
const Peer& p)
const = 0;
363 virtual Peer peer (uint8_t idx)
const = 0;
364 virtual bool peer (
const Peer& p) = 0;
365 virtual bool peer (
const Peer& p1,
const Peer& p2) = 0;
366 virtual bool deletepeer (
const Peer& p) = 0;
367 virtual void firstinit () = 0;
370 virtual void stop () = 0;
376 virtual uint8_t status () = 0;
377 virtual uint8_t flags () = 0;
379 virtual void patchStatus (
Message& msg) = 0;
380 virtual void configChanged () = 0;
386 virtual bool hasList3 ()
const = 0;
387 virtual bool hasList4 ()
const = 0;
391 template <
class HalType,
class ChannelType,
class List0Type=List0>
398 operator ChannelType& () {
return ch; }
401 virtual uint16_t size ()
const {
return ch.size(); }
402 virtual uint8_t number ()
const {
return ch.number(); }
403 virtual uint16_t address ()
const {
return ch.address(); }
404 virtual uint8_t peers ()
const {
return ch.peers(); }
405 virtual bool changed ()
const {
return ch.changed(); }
406 virtual void changed (
bool c) { ch.changed(c); }
407 virtual void inhibit (
bool value) { ch.inhibit(value); }
408 virtual bool inhibit ()
const {
return ch.inhibit(); }
409 virtual bool aesActive ()
const {
return ch.aesActive(); }
410 virtual bool has (
const Peer& p)
const {
return ch.has(p); };
411 virtual Peer peer (uint8_t idx)
const {
return ch.peer(idx); }
412 virtual bool peer (
const Peer& p) {
return ch.peer(p); }
413 virtual bool peer (
const Peer& p1,
const Peer& p2) {
return ch.peer(p1,p2); }
414 virtual bool deletepeer (
const Peer& p) {
return ch.deletepeer(p); }
415 virtual void firstinit () { ch.firstinit(); }
418 virtual void stop () { ch.stop(); };
419 virtual bool process (
const ActionSetMsg& msg) {
return ch.process(msg); }
420 virtual bool process (
const ActionCommandMsg& msg) {
return ch.process(msg); }
421 virtual bool process (
const RemoteEventMsg& msg) {
return ch.process(msg); }
422 virtual bool process (
const SensorEventMsg& msg) {
return ch.process(msg); }
424 virtual uint8_t status () {
return ch.status(); }
425 virtual uint8_t flags () {
return ch.flags(); }
427 virtual void patchStatus (
Message& msg) { ch.patchStatus(msg); }
428 virtual void configChanged () { ch.configChanged(); }
430 virtual GenericList getList1 ()
const {
return ch.getList1(); }
431 virtual GenericList getList2 ()
const {
return ch.getList2(); }
432 virtual GenericList getList3 (
const Peer& p)
const {
return ch.getList3(p); }
433 virtual GenericList getList4 (
const Peer& p)
const {
return ch.getList4(p); }
434 virtual bool hasList3 ()
const {
return ChannelType::hasList3(); }
435 virtual bool hasList4 ()
const {
return ChannelType::hasList4(); }
438 #define channelISR(chan,pin,mode,type) class __##pin##ISRHandler { \
440 static void isr () { chan.handleISR(); } \
443 enableInterrupt(pin,__##pin##ISRHandler::isr,type);