AT command firmware for MultiTech Dot devices.

Fork of mDot_AT_firmware by MultiTech

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CmdTxChannel.cpp Source File

CmdTxChannel.cpp

00001 #include "CmdTxChannel.h"
00002 #include "ChannelPlan.h"
00003 
00004 namespace {
00005 void parseArgs(const std::vector<std::string>& args, int& index, int& frequency, int& datarateRange) {
00006     sscanf(args[1].c_str(), "%d", &index);
00007     sscanf(args[2].c_str(), "%d", &frequency);
00008     sscanf(args[3].c_str(), "%02x", &datarateRange);
00009 }
00010 
00011 
00012 void printChannel(const char* name, uint32_t channel, uint8_t range_max, uint8_t range_min, int16_t on) {
00013 #if MTS_CMD_TERM_VERBOSE
00014     if (on != -1) {
00015         CommandTerminal::Serial()->writef("  %-6s%9d%7X%4X%5d\r\n", name, channel, range_max, range_min, on);
00016     } else {
00017         CommandTerminal::Serial()->writef("  %-6s%9d%7X%4X\r\n", name, channel, range_max, range_min);
00018     }
00019 #else
00020     CommandTerminal::Serial()->writef("%s,%d,%X,%X,%d\r\n", name, channel, range_max, range_min, on);
00021 #endif
00022 }
00023 
00024 void assignName(char* name, int i) {
00025     if (i > 9) {
00026         int t = i - (i % 10);
00027         name[0] = '0' + (t / 10);
00028         name[1] = '0' + (i - t);
00029     } else {
00030         name[0] = i + '0';
00031         name[1] = '\0';
00032     }
00033 }
00034 
00035 } // namespace
00036 
00037 CmdTxChannel::CmdTxChannel() :
00038 #if MTS_CMD_TERM_VERBOSE
00039     Command("Tx Channels", "AT+TXCH", "List Tx channel frequencies for sub-band", "<INDEX>,<FREQUENCY>,<DR_RANGE>")
00040 #else
00041     Command("AT+TXCH")
00042 #endif
00043 {
00044     _queryable = true;
00045 }
00046 
00047 uint32_t CmdTxChannel::action(const std::vector<std::string>& args) {
00048     if (args.size() == 1) {
00049 
00050         std::vector<uint32_t> channels = CommandTerminal::Dot()->getChannels();
00051         std::vector<uint8_t> ranges = CommandTerminal::Dot()->getChannelRanges();
00052         std::vector<uint16_t> mask = CommandTerminal::Dot()->getChannelMask();
00053 
00054         //channelProps props { "\0\0", 0, 0, 0, 0 };
00055         char name[3] = "\0\0";
00056         uint32_t channel;
00057         uint8_t range_max;
00058         uint8_t range_min;
00059         int16_t on;
00060 
00061 #if MTS_CMD_TERM_VERBOSE
00062         CommandTerminal::Serial()->writef("Index\tFrequency  DR Max Min  On\r\n");
00063 #endif
00064 
00065         if (lora::ChannelPlan::IsPlanDynamic(CommandTerminal::Dot()->getFrequencyBand())) {
00066             for (int8_t i = 0; i < 17; i++) {
00067                 channel = channels[i];
00068                 range_max = ranges[i] >> 4;
00069                 range_min = ranges[i] & 0xF;
00070                 if (i == 16) {
00071                     name[0] = 'R';
00072                     name[1] = '2';
00073                     on = -1;
00074                     if (channels[16] == 0) {
00075                         range_max = ranges[16];
00076                         range_min = ranges[168];
00077                     }
00078                 } else {
00079                     assignName(name, i);
00080                     channel = channels[i];
00081                     if (channels[i] != 0) {
00082                         on = (mask[0] & (0x1 << i)) ? 1 : 0;
00083                     } else {
00084                         on = 0;
00085                     }
00086                 }
00087 
00088                 printChannel(name, channel, range_max, range_min, on);
00089             }
00090         } else {
00091             uint8_t sub_band = CommandTerminal::Dot()->getFrequencySubBand();
00092             if (sub_band > 0) {
00093                 uint8_t offset = (sub_band - 1) * 8;
00094 
00095                 for (int i = 0; i < 10; i++) {
00096                     channel = channels[i];
00097                     if (i == 9) {
00098                         name[0] = 'R';
00099                         name[1] = '2';
00100                         range_max = ranges[i];
00101                         range_min = ranges[i];
00102                         on = -1;
00103                     } else {
00104                         if (i == 8) {
00105                             name[0] = 'U';
00106                             on = (mask[4] & (0x0001 << (sub_band - 1))) ? 1 : 0;
00107                         } else {
00108                             assignName(name, i);
00109                             if ((sub_band % 2) == 1) {
00110                                 on = (mask[(offset + i)/16] & (0x0001 << i)) ? 1 : 0;
00111                             } else {
00112                                 on = (mask[(offset + i)/16] & (0x0001 << (i + 8))) ? 1 : 0;
00113                             }
00114                         }
00115                         range_max = ranges[i] >> 4;
00116                         range_min = ranges[i] & 0xF;
00117                     }
00118                     printChannel(name, channel, range_max, range_min, on);
00119                 }
00120             } else {
00121                 for (size_t i = 0; i < channels.size(); i++) {
00122                     channel = channels[i];
00123                     if (i == channels.size() - 1) {
00124                         name[0] = 'R';
00125                         name[1] = '2';
00126                         range_max = ranges[i];
00127                         range_min = ranges[i];
00128                         on = -1;
00129                     } else {
00130                         assignName(name, i);
00131                         range_max = ranges[i] >> 4;
00132                         range_min = ranges[i] & 0xF;
00133                         on = (mask[i/16] & (0x0001 << (i%16))) ? 1 : 0;
00134                     }
00135                     printChannel(name, channel, range_max, range_min, on);
00136                 }
00137             }
00138         }
00139     }
00140 
00141     if (args.size() == 4) {
00142         int index;
00143         int frequency;
00144         int datarateRange;
00145 
00146         parseArgs(args, index, frequency, datarateRange);
00147 
00148         if (CommandTerminal::Dot()->addChannel(index, frequency, datarateRange) != mDot::MDOT_OK) {
00149 #if MTS_CMD_TERM_VERBOSE
00150             CommandTerminal::setErrorMessage("Failed to add channel");
00151 #endif
00152             return 1;
00153         }
00154     }
00155 
00156     return 0;
00157 }
00158 
00159 bool CmdTxChannel::verify(const std::vector<std::string>& args) {
00160     if (args.size() == 1)
00161         return true;
00162 
00163 
00164     if (args.size() == 4) {
00165 
00166         int index;
00167         int frequency;
00168         int datarateRange;
00169 
00170         parseArgs(args, index, frequency, datarateRange);
00171 
00172         if (lora::ChannelPlan::IsPlanDynamic(CommandTerminal::Dot()->getFrequencyBand())) {
00173             if (frequency != 0 && (frequency < int(CommandTerminal::Dot()->getMinFrequency()) || frequency > int(CommandTerminal::Dot()->getMaxFrequency()))) {
00174 #if MTS_CMD_TERM_VERBOSE
00175                 char tmp[256];
00176                 sprintf(tmp, "Invalid frequency, expects (0,%" SCNu32 "-%" SCNu32 ")", CommandTerminal::Dot()->getMinFrequency(), CommandTerminal::Dot()->getMaxFrequency());
00177                 CommandTerminal::setErrorMessage(tmp);
00178 #endif
00179                 return false;
00180             }
00181         } else {
00182 #if MTS_CMD_TERM_VERBOSE
00183             CommandTerminal::setErrorMessage("Fixed channel plans cannot be changed, use AT+FSB or AT+CHM to limit");
00184 #endif
00185             return false;
00186         }
00187 
00188         return true;
00189     } else {
00190 #if MTS_CMD_TERM_VERBOSE
00191         CommandTerminal::setErrorMessage("Invalid arguments");
00192 #endif
00193         return false;
00194     }
00195 
00196 }