AT command firmware for MultiTech Dot devices.
Fork of mDot_AT_firmware by
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 }
Generated on Wed Dec 6 2023 19:34:05 by 1.7.2