]> git.tdb.fi Git - r2c2.git/commitdiff
Add some more range checks in ArduControl and improve existing ones
authorMikko Rasa <tdb@tdb.fi>
Thu, 7 Nov 2013 22:23:32 +0000 (00:23 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 7 Nov 2013 22:23:32 +0000 (00:23 +0200)
source/libr2c2/arducontrol.cpp
source/libr2c2/arducontrol.h

index 9cf8383bf1eadd997f5b58d4b08a68ee782e6a76..e940a2aed14527ed676a6cbb4af1786762411420 100644 (file)
@@ -9,6 +9,11 @@ using namespace Msp;
 
 namespace R2C2 {
 
+ArduControl::ProtocolInfo ArduControl::protocol_info[2] =
+{
+       { 79, 14, 4 }  // MM
+};
+
 ArduControl::ArduControl(const string &dev):
        serial(dev),
        debug(true),
@@ -57,17 +62,15 @@ ArduControl::Protocol ArduControl::map_protocol(const string &proto_name)
 {
        if(proto_name=="MM")
                return MM;
+       else if(proto_name=="MFX")
+               return MFX;
        else
                throw invalid_argument("ArduControl::map_protocol");
 }
 
 unsigned ArduControl::get_protocol_speed_steps(const string &proto_name) const
 {
-       Protocol proto = map_protocol(proto_name);
-       if(proto==MM)
-               return 14;
-       else
-               return 0;
+       return protocol_info[map_protocol(proto_name)].max_speed;
 }
 
 unsigned ArduControl::add_loco(unsigned addr, const string &proto_name, const VehicleType &)
@@ -76,12 +79,8 @@ unsigned ArduControl::add_loco(unsigned addr, const string &proto_name, const Ve
                throw invalid_argument("ArduControl::add_loco");
 
        Protocol proto = map_protocol(proto_name);
-
-       if(proto==MM)
-       {
-               if(addr>=80)
-                       throw invalid_argument("ArduControl::add_loco");
-       }
+       if(addr>protocol_info[proto].max_address)
+               throw invalid_argument("ArduControl::add_loco");
 
        Locomotive loco(proto, addr);
        insert_unique(locomotives, loco.id, loco);
@@ -99,6 +98,9 @@ void ArduControl::remove_loco(unsigned id)
 void ArduControl::set_loco_speed(unsigned id, unsigned speed)
 {
        Locomotive &loco = get_item(locomotives, id);
+       if(speed>protocol_info[loco.proto].max_speed)
+               throw invalid_argument("ArduControl::set_loco_speed");
+
        if(loco.speed.set(speed))
        {
                QueuedCommand cmd(loco, Locomotive::SPEED);
@@ -123,6 +125,9 @@ void ArduControl::set_loco_reverse(unsigned id, bool rev)
 void ArduControl::set_loco_function(unsigned id, unsigned func, bool state)
 {
        Locomotive &loco = get_item(locomotives, id);
+       if(func>protocol_info[loco.proto].max_func)
+               throw invalid_argument("ArduControl::set_loco_function");
+
        unsigned mask = 1<<func;
        if(loco.funcs.set((loco.funcs&~mask)|(mask*state)))
        {
index f0c14f948219afce5bea6c4e2a2559d8a606f375..fb0cb68c6ca03930a571a72dcd248ae00cc8b581 100644 (file)
@@ -66,10 +66,16 @@ private:
 
        enum Protocol
        {
-               NONE,
                MM
        };
 
+       struct ProtocolInfo
+       {
+               unsigned max_address;
+               unsigned max_speed;
+               unsigned max_func;
+       };
+
        template<typename T>
        struct ControlledVariable
        {
@@ -202,6 +208,8 @@ private:
        Msp::Mutex mutex;
        ControlThread thread;
 
+       static ProtocolInfo protocol_info[2];
+
 public:
        ArduControl(const std::string &);
        ~ArduControl();