Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mac_commands.cpp
00001 /* 00002 * Copyright (c) 2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 #include "mac_commands.h" 00018 00019 //Need to disable filtering until mac_filter_api.h in mbed-os is updated 00020 #define DISABLE_FILTERING 00021 00022 #define TRACE_GROUP "MAC" 00023 00024 #define MAN_MAC_START "start <options> --- Starts a PAN\n"\ 00025 " --pan_id <value> PAN id in hex, default: 0x1234\n"\ 00026 " --logical_channel <value> Operated logical channel, default: 11 (0-26)\n"\ 00027 " --channel_page <value> Operated channel page, default: 0 (0-2)\n"\ 00028 " --start_time <value> Time at which to start sending beacons\n"\ 00029 " default: 0\n"\ 00030 " --beacon_order <value> How often are beacons transmitted\n"\ 00031 " default: 15 (0-15, 15 = never)\n"\ 00032 " --super_frame_order <value> Length of the superframe's active portion\n"\ 00033 " if beacon_order is 15, this option is ignored\n"\ 00034 " default: 15 (0-15)\n"\ 00035 " --pan_coordinator <bool> Is this device the PAN coordinator?\n"\ 00036 " default: true\n"\ 00037 " --battery_life_extension <bool> Disable beaconing device periodically\n"\ 00038 " to save power? default: false\n"\ 00039 " --coord_realignment <bool> If true, coordinator realignment command\n"\ 00040 " is sent prior to changing\n"\ 00041 " the superframe configuration default: false\n" 00042 00043 #define MAN_MAC_SCAN "scan <options> --- Perform a scan\n"\ 00044 " --scan_type <value> What type of scan to perform, 0=ED, 1=active\n"\ 00045 " 2=passive, 3=orphan, default: 1\n"\ 00046 " --channel_page_enum <value> default: 0 (0-10)\n"\ 00047 " --channel_mask <value> Bitmap of the channels on which to perform\n"\ 00048 " the scan, lower 27-bits are used\n"\ 00049 " bit 0 corresponds to channel 0 and so forth\n"\ 00050 " default: 0x07FFF800 (channels 11-26)\n"\ 00051 " --scan_duration <value> How long to spend in each channel,\n"\ 00052 " aBaseSuperFrameDuration * (2^n + 1) symbols\n"\ 00053 " default: 5 (0-14)\n"\ 00054 " --channel_page <value> The channel page on which to perform the scan\n"\ 00055 " default: 0 (0-31)\n"\ 00056 MAN_MAC_SECURITY 00057 00058 #define MAN_MAC_DATA "data <options> --- Send arbitrary data\n"\ 00059 " --src_addr_mode <value> Source addressing mode, 0=no address, 1=reserved\n"\ 00060 " 2=16-bit address, 3=64-bit address\n"\ 00061 " default: 3 (0-3)\n"\ 00062 " --dst_addr_mode <value> Destination addressing mode, same as above\n"\ 00063 " default: 3 (0-3)\n"\ 00064 " --dst_pan_id <value> Destination PAN id in hex\n"\ 00065 " default: 0x1234 (0x0-0xFFFF)\n"\ 00066 " --dst_addr <bytes> Destination address, default: 00:00:00:...\n"\ 00067 " --msdu_length <value> Length of the data to send, default: 0 (0-255)\n"\ 00068 " --msdu <text> Data to transmit, default: <NULL>\n"\ 00069 " --msdu_handle <value> Handle of this MSDU, default: 0 (0-255)\n"\ 00070 " --tx_ack_req <bool> Is ack required for this transmission?\n"\ 00071 " default: true\n"\ 00072 " --indirect_tx <bool> Transmit indirectly? default: false\n"\ 00073 " --pending_bit <bool> Specifies whether more fragments (higher layer)\n"\ 00074 " are to be sent, default: false\n"\ 00075 " --wait_for_confirm <bool> Should we block further commands until we have\n"\ 00076 " received a data confirmation, default: true\n"\ 00077 MAN_MAC_SECURITY 00078 00079 #define MAN_MAC_POLL "poll <options> --- Poll the coordinator for data\n"\ 00080 " --coord_addr_mode <value> Coordinator addressing mode, 2=16-bit address\n"\ 00081 " 3=64-bit address, default: 3 (2-3)\n"\ 00082 " --coord_pan_id <value> Coordinator PAN id in hex\n"\ 00083 " default: 0x1234 (0x0-0xFFFF)\n"\ 00084 " --coord_address <bytes> Coordinator address, default 00:00:00:...\n"\ 00085 MAN_MAC_SECURITY 00086 00087 #define MAN_MAC_PURGE "purge <options> --- Remove a transmission from the queue\n"\ 00088 " --msdu_handle <value> Handle of the MSDU to be removed\n"\ 00089 " default: 0 (0-255)\n"\ 00090 00091 #define MAN_MAC_SET "mlme-set <options> --- Set a specified PIB attribute\n"\ 00092 " --attr <value> ID of the attribute to set in hex (0x0-0xFF)\n"\ 00093 " --attr_index <0-255> Index of the attribute, default: 0 (0-255)\n"\ 00094 " --value_ascii <text> Specify the set value as an ASCII string\n"\ 00095 " --value_bytes <bytes> Value as a string of bytes\n"\ 00096 " --value_uint8/16/32 <value> Value as a uint8, uint16, or uint32\n"\ 00097 " Max value for uint32 is the max value for int32\n"\ 00098 " --value_size <value> Size of the value in bytes (0-255)\n" 00099 00100 #define MAN_MAC_GET "mlme-get <options> --- Get a specified PIB attribute\n"\ 00101 " --attr <value> ID of the attribute we want to get in hex (0x0-0xFF)\n"\ 00102 " --attr_index <value> Index of the attribute, default: 0 (0-255)\n" 00103 00104 #define MAN_MAC_RESET "mlme-reset --- Reset the MAC sublayer\n"\ 00105 " --set_default_pib <bool> When set to true, PIB attributes are set to\n"\ 00106 " their default values\n"\ 00107 " If set to false, PIB attributes retain\n"\ 00108 " their values, default: true\n" 00109 00110 #define MAN_MAC_ADDR "addr <options> --- Configure 16/64-bit MAC addresses\n"\ 00111 " having no options will display the addresses\n"\ 00112 " --16-bit <value> 16-bit MAC address in hex (0x0-0xFFFF)\n"\ 00113 " --64-bit <bytes> 64-bit MAC address\n" 00114 00115 #define MAN_MAC_SECURITY " --security_level <value> 0=no security, 1=MIC32, 2=MIC64, 3=MIC128,\n"\ 00116 " 4=ENC, 5=ENC+MIC32, 6=ENC+MIC64, 7=ENC+MIC128\n"\ 00117 " default: 0\n"\ 00118 " --key_id_mode <value> 0=implicit, 1=default key source\n"\ 00119 " 2=2-byte key source\n"\ 00120 " 3=8-byte key source, default: 0 (0-3)\n"\ 00121 " --key_index <value> Which key to use, default: 0 (0-255)\n"\ 00122 " --key_source <AA:BB...> The originator of the key to be used\n" 00123 00124 #define MAN_MAC_KEY "key <cmd> <options> --- Configure or add key descriptors\n"\ 00125 "config --- Configure parameters for key descriptor\n"\ 00126 " --key <bytes> Actual security key, 16 bytes\n"\ 00127 " default: C0:C1:C2:...:CF\n"\ 00128 " --key_id_lookup_list_entries <value> Amount of entries in the key's lookup\n"\ 00129 " --key_device_list_entries <value> ...device...\n"\ 00130 " --key_usage_list_entries <value> and usage list, default: 2 (0-255)\n"\ 00131 " --lookup_index <value> Which entry of the lookup list\n"\ 00132 " are we accessing? default: 0 (0-255)\n"\ 00133 " --lookup_data <bytes> The lookup data for this key\n"\ 00134 " length is 9 bytes regardless of\n"\ 00135 " the next option\n"\ 00136 " --lookup_data_size <value> How large is the lookup data? (0-1)\n"\ 00137 " 0=5 bytes, 1=9 bytes\n"\ 00138 " --device_list_index <value> Which entry of the device list\n"\ 00139 " are we accessing, default: 0 (0-255)\n"\ 00140 " --device_descriptor_handle <value> Which entry in our neighbour table\n"\ 00141 " do we want to use this key with\n"\ 00142 " default: 0 (0-255)\n"\ 00143 " --unique_device <bool> Is the device unique to the key?\n"\ 00144 " --blacklisted <bool> Is the device blacklisted?\n"\ 00145 " --usage_list_index <value> Which entry of the usage list\n"\ 00146 " are we accessing, default: 0 (0-255)\n"\ 00147 " --frame_type <value> What type of frame do we want to\n"\ 00148 " use this key with? (0-3)\n"\ 00149 " 0=beacon, 1=data, 2=ACK, 3=command\n"\ 00150 " --command_frame_identifier <value> Type of the command frame (1-9)\n"\ 00151 " 1=association request\n"\ 00152 " 2=association response\n"\ 00153 " 3=disassociation notification\n"\ 00154 " 4=data request\n"\ 00155 " 5=PAN id conflict notification\n"\ 00156 " 6=orphan notification\n"\ 00157 " 7=beacon request\n"\ 00158 " 8=coordinator realigment\n"\ 00159 " 9=GTS request\n"\ 00160 "add --- Add the key into the key descriptor table\n"\ 00161 " --index <value> Index in the key table (0-255)\n" 00162 00163 #define MAN_MAC_ADD_NEIGHBOUR "add-neigh <options> --- Add an entry to the neighbour table\n"\ 00164 " --frame_ctr <value> Frame counter for this neighbour\n"\ 00165 " --mac16 <value> 16-bit MAC address in hex (0x0-0xFFFF)\n"\ 00166 " --mac64 <bytes> 64-bit MAC address\n"\ 00167 " --pan_id <value> PAN id (0x0-0xFFFF)\n"\ 00168 " --index <value> Index in the neighbour table (0-255)\n" 00169 00170 #define MAN_MAC_FILTER "filter <cmd> <options> --- Configure MAC layer filtering\n"\ 00171 "start --- Start a generic filter in blacklist, whitelist or fixed mode\n"\ 00172 " --mode <value> Set the filtering mode, values: allow|block|fixed\n"\ 00173 " --lqi_m <value> LQI multiplier (fixed mode only)\n"\ 00174 " --dbm_m <value> dBm multiplier (fixed mode only)\n"\ 00175 "add --- Add a filter by manually supplying values, or using a preset mode\n"\ 00176 " --lqi_m <value> LQI multiplier\n"\ 00177 " --lqi_add <value> Value added to the LQI\n"\ 00178 " --dbm_m <value> dBm multiplier\n"\ 00179 " --dbm_add <value> Value added to the dBm\n"\ 00180 " --mode <value> Filtering mode, values: allow|block|fixed\n"\ 00181 " --short <value> 16-bit address in hex to filter (0x0-0xFFFF)\n"\ 00182 " --long <bytes> 64-bit address as bytes to filter\n"\ 00183 "remove --- Remove a filter\n"\ 00184 " --short <value> 16-bit address to remove from filter (0x0-0xFFFF)\n"\ 00185 " --long <bytes> 64-bit address to remove from filter\n"\ 00186 "clear --- Clear all filters excluding the default one\n"\ 00187 "stop --- Stop filtering completely\n"\ 00188 00189 #define MAN_MAC_CONFIG_STATUS "config-status <options> --- Configure expected status codes\n"\ 00190 " having no options will display configured statuses\n"\ 00191 " default: 0 (MLME_SUCCESS) for all\n"\ 00192 " --data_conf <value> MCPS-DATA.confirm (0-255)\n"\ 00193 " --data_ind <text> MCPS-DATA.indication (0-255)\n"\ 00194 " --get <value> MLME-GET.confirm (0-255)\n"\ 00195 " --scan <value> MLME-SCAN.confirm (0-255)\n"\ 00196 " --poll <value> MLME-POLL.confirm (0-255)\n"\ 00197 " --purge <value> MCPS-PURGE.confirm (0-255)\n"\ 00198 " --comm_status <value> MLME-COMM-STATUS.indication (0-255)\n"\ 00199 " --list List all statuses\n"\ 00200 " --reset Reset all statuses to default values\n" 00201 00202 #define MAN_MAC_FIND_BEACON "find-beacon <options> --- Search for a PAN in the\n"\ 00203 " results of the last scan\n"\ 00204 " --data <text> Beacon data transmitted in the beacon\n" 00205 00206 #define MAN_MAC_WAIT "wait <options> --- Wait for data sent directly for a\n"\ 00207 " specified amount of milliseconds\n"\ 00208 " --timeout <value> Milliseconds to wait, default: 1000\n" 00209 00210 #define MAN_MAC_ED_ANALYZE "analyze-ed <options --- Analyze the results of the last ED scan\n"\ 00211 " --channel <value> Channel to analyze (11-26)\n"\ 00212 " --above <value> Check if the ED value is above a given value\n"\ 00213 " --below <value> Check if the ED value is below a given value\n" 00214 00215 #define MAN_RESET "reset <options> --- Reset MCPS and MLME structures to default values\n" 00216 00217 #define MAN_SILENT "silent-mode <on/off> --- When enabled, doesn't print extended information\n"\ 00218 " of MCPS/MLME primitives\n" 00219 00220 mac_api_s *mac_interface = NULL; 00221 static bool wait_for_confirm = true; 00222 static bool silent_mode = false; 00223 static volatile unsigned int data_count = 0; 00224 00225 static mlme_start_t start_req = { 00226 0x1234, /*PANId*/ 00227 11, /*LogicalChannel*/ 00228 0, /*ChannelPage*/ 00229 0, /*StartTime*/ 00230 15, /*BeaconOrder*/ 00231 15, /*SuperframeOrder*/ 00232 true, /*PANCoordinator*/ 00233 false, /*BatteryLifeExtension*/ 00234 false, /*CoordRealignment*/ 00235 }; 00236 00237 static mlme_scan_t scan_req = { 00238 MAC_ACTIVE_SCAN, /*ScanType*/ 00239 { 00240 CHANNEL_PAGE_0, /*channel_page (enum)*/ 00241 0x07FFF800 /*channel_mask*/ 00242 }, 00243 5, /*ScanDuration*/ 00244 0, /*ChannelPage*/ 00245 { 00246 0, /*SecurityLevel*/ 00247 0, /*KeyIdMode*/ 00248 0, /*KeyIndex*/ 00249 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*Keysource*/ 00250 } 00251 }; 00252 00253 static mcps_data_req_t data_req = { 00254 3, /*SrcAddrMode*/ 00255 3, /*DstAddrMode*/ 00256 0x1234, /*DstPANId*/ 00257 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*DstAddr*/ 00258 0, /*msduLength*/ 00259 NULL, /*msdu*/ 00260 0, /*msduHandle*/ 00261 true, /*TxAckReq*/ 00262 false, /*IndirectTx*/ 00263 false, /*PendingBit*/ 00264 false, /*SeqNumSuppressed*/ 00265 false, /*PanIdSuppressed*/ 00266 { 00267 0, /*SecurityLevel*/ 00268 0, /*KeyIdMode*/ 00269 0, /*KeyIndex*/ 00270 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*Keysource*/ 00271 } 00272 }; 00273 00274 static mlme_poll_t poll_req = { 00275 3, /*CoordAddrMode*/ 00276 0x1234, /*CoordPANId*/ 00277 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*CoordAddress*/ 00278 { 00279 0, /*SecurityLevel*/ 00280 0, /*KeyIdMode*/ 00281 0, /*KeyIndex*/ 00282 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*Keysource*/ 00283 } 00284 }; 00285 00286 static mcps_purge_t purge_req = { 00287 0 /*msduHandle*/ 00288 }; 00289 00290 static mlme_set_t set_req = { 00291 (mlme_attr_t)0x39, /*attr*/ 00292 0, /*attr_index*/ 00293 NULL, /*value_pointer*/ 00294 0 /*value_size*/ 00295 }; 00296 00297 static mlme_get_t get_req = { 00298 (mlme_attr_t)0x39, /*attr*/ 00299 0 /*attr_index*/ 00300 }; 00301 00302 static mlme_reset_t reset_req = { 00303 true /*SetDefaultPIB*/ 00304 }; 00305 00306 static mlme_key_id_lookup_descriptor_t lookup_descriptors[LOOKUP_DESCRIPTOR_TABLE_SIZE]; 00307 static mlme_key_device_descriptor_t device_descriptors[DEVICE_DESCRIPTOR_TABLE_SIZE]; 00308 static mlme_key_usage_descriptor_t usage_descriptors[USAGE_DESCRIPTOR_TABLE_SIZE]; 00309 static mlme_key_descriptor_entry_t key_descriptor = { 00310 lookup_descriptors, /*KeyIdLookupList*/ 00311 LOOKUP_DESCRIPTOR_TABLE_SIZE, /*KeyIdLookupListEntries*/ 00312 device_descriptors, /*KeyDeviceList*/ 00313 DEVICE_DESCRIPTOR_TABLE_SIZE, /*KeyDeviceListEntries*/ 00314 usage_descriptors, /*KeyUsageList*/ 00315 USAGE_DESCRIPTOR_TABLE_SIZE, /*KeyUsageListEntries*/ 00316 {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF} /*Key*/ 00317 }; 00318 00319 struct status_list_t { 00320 uint8_t data_conf; 00321 uint8_t get_conf; 00322 uint8_t scan_conf; 00323 uint8_t poll_conf; 00324 uint8_t purge_conf; 00325 uint8_t comm_status_ind; 00326 uint8_t data_ind_len; 00327 uint8_t *data_ind; 00328 }; 00329 00330 static struct status_list_t expected_statuses = { 00331 MLME_SUCCESS, 00332 MLME_SUCCESS, 00333 MLME_SUCCESS, 00334 MLME_SUCCESS, 00335 MLME_SUCCESS, 00336 MLME_SUCCESS, 00337 0, 00338 NULL 00339 }; 00340 00341 struct beacon_list_t { 00342 size_t count; 00343 char *beacons[MLME_MAC_RES_SIZE_MAX]; 00344 uint8_t beacon_lengths[MLME_MAC_RES_SIZE_MAX]; 00345 }; 00346 00347 static struct beacon_list_t received_beacons = {}; 00348 00349 struct ed_scan_result_list_t { 00350 uint8_t count; 00351 uint8_t channel[MLME_MAC_RES_SIZE_MAX]; 00352 uint8_t ED_values[MLME_MAC_RES_SIZE_MAX]; 00353 }; 00354 00355 static struct ed_scan_result_list_t last_ed_results; 00356 00357 static void print_security(const mlme_security_t *key) 00358 { 00359 if (key->SecurityLevel > 0) { 00360 cmd_printf("Key.SecurityLevel: %u\n", key->SecurityLevel); 00361 cmd_printf("Key.KeyIdMode: %u\n", key->KeyIdMode); 00362 cmd_printf("Key.KeyIndex: %hhu\n", key->KeyIndex); 00363 cmd_printf("Key.Keysource %s\n", trace_array(key->Keysource, 8)); 00364 } 00365 } 00366 00367 static void print_PAN_descriptor(const mlme_pan_descriptor_t *desc) 00368 { 00369 cmd_printf("PANDescriptor.CoordAddrMode: %u\n", desc->CoordAddrMode); 00370 cmd_printf("PANDescriptor.CoordPANId: 0x%04X\n", desc->CoordPANId); 00371 cmd_printf("PANDescriptor.CoordAddress: %s\n", trace_array(desc->CoordAddress, 8)); 00372 cmd_printf("PANDescriptor.LogicalChannel: %hhu\n", desc->LogicalChannel); 00373 cmd_printf("PANDescriptor.ChannelPage: %hhu\n", desc->ChannelPage); 00374 cmd_printf("PANDescriptor.SuperframeSpec: %02x:%02x\n", desc->SuperframeSpec[0], desc->SuperframeSpec[1]); 00375 cmd_printf("PANDescriptor.GTSPermit: %s\n", desc->GTSPermit ? "true" : "false"); 00376 cmd_printf("PANDescriptor.LinkQuality: %hhu\n", desc->LinkQuality); 00377 cmd_printf("PANDescriptor.Timestamp: %lu\n", desc->Timestamp); 00378 cmd_printf("PANDescriptor.SecurityFailure: %hhu\n", desc->SecurityFailure); 00379 print_security(&desc->Key); 00380 } 00381 00382 static int handle_security_args(int argc, char *argv[], mlme_security_t *key) 00383 { 00384 char *str; 00385 int32_t val; 00386 00387 if (cmd_parameter_int(argc, argv, "--security_level", &val)) { 00388 if (val >= 0 && val <= 7) { 00389 key->SecurityLevel = val; 00390 } else { 00391 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00392 } 00393 } 00394 if (cmd_parameter_int(argc, argv, "--key_id_mode", &val)) { 00395 if (val >= 0 && val <= 3) { 00396 key->KeyIdMode = val; 00397 } else { 00398 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00399 } 00400 } 00401 if (cmd_parameter_int(argc, argv, "--key_index", &val)) { 00402 if (val >= 0 && val <= 255) { 00403 key->KeyIndex = val; 00404 } else { 00405 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00406 } 00407 } 00408 if (cmd_parameter_val(argc, argv, "--key_source", &str)) { 00409 if (strlen(str) == 2*8+7) { 00410 if (string_to_bytes(str, key->Keysource, 8) != 0) { 00411 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00412 } 00413 } else { 00414 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00415 } 00416 } 00417 return CMDLINE_RETCODE_SUCCESS; 00418 } 00419 00420 static void add_beacon(const uint8_t *beacon, uint8_t len) 00421 { 00422 if (received_beacons.count >= MLME_MAC_RES_SIZE_MAX) { 00423 tr_warn("List of received beacons is full. Discarding %s <%.*s>", trace_array(beacon, len), len, beacon); 00424 return; 00425 } 00426 unsigned int cur_beacon = received_beacons.count; 00427 received_beacons.beacon_lengths[cur_beacon] = len; 00428 received_beacons.beacons[cur_beacon] = (char*)ns_dyn_mem_temporary_alloc(len <= 75 ? 75:len); 00429 if (len != 0) { 00430 std::memcpy(received_beacons.beacons[cur_beacon], beacon, len); 00431 } 00432 ++received_beacons.count; 00433 } 00434 00435 static void clear_beacons(void) 00436 { 00437 for (unsigned int i = 0; i < received_beacons.count; ++i) { 00438 ns_dyn_mem_free(received_beacons.beacons[i]); 00439 received_beacons.beacons[i] = NULL; 00440 received_beacons.beacon_lengths[i] = 0; 00441 } 00442 received_beacons.count = 0; 00443 } 00444 00445 void mac_commands_init(void) 00446 { 00447 cmd_add("start", mac_start_command, "Start a PAN", MAN_MAC_START); 00448 cmd_add("scan", mac_scan_command, "Perform a scan", MAN_MAC_SCAN); 00449 cmd_add("data", mac_data_command, "Send data", MAN_MAC_DATA); 00450 cmd_add("poll", mac_poll_command, "Poll for data", MAN_MAC_POLL); 00451 cmd_add("purge", mac_purge_command, "Purge data from the transmission queue", MAN_MAC_PURGE); 00452 cmd_add("mlme-set", mac_set_command, "Writes a given value to the PIB attribute", MAN_MAC_SET); 00453 cmd_add("mlme-get", mac_get_command, "Gets the value of a given PIB attribute", MAN_MAC_GET); 00454 cmd_add("mlme-reset", mac_reset_command, "Resets the MAC sublayer to default values", MAN_MAC_RESET); 00455 cmd_add("addr", mac_address_command, "Configure MAC addresses", MAN_MAC_ADDR); 00456 cmd_add("key", mac_key_command, "Configure or add security keys", MAN_MAC_KEY); 00457 cmd_add("add-neigh", mac_add_neighbour_command, "Add a device to the neighbour table", MAN_MAC_ADD_NEIGHBOUR); 00458 cmd_add("filter", mac_filter_command, "Add or remove filters based on MAC addresses", MAN_MAC_FILTER); 00459 cmd_add("config-status", mac_config_status_command, "Set expected return statuses for confirmations and indications", MAN_MAC_CONFIG_STATUS); 00460 cmd_add("find-beacon", mac_find_beacon_command, "Find a PAN by beacon data", MAN_MAC_FIND_BEACON); 00461 cmd_add("wait", mac_wait_command, "Wait for data", MAN_MAC_WAIT); 00462 cmd_add("analyze-ed", mac_analyze_ed_command, "Analyze the results of the last ED scan", MAN_MAC_ED_ANALYZE); 00463 cmd_add("reset", reset_command, "Reset MCPS/MLME structures to default values", MAN_RESET); 00464 cmd_add("silent-mode", silent_mode_command, "Stop printing fields of MCPS/MLME structures", MAN_SILENT); 00465 } 00466 00467 void mac_data_confirm_handler(const mac_api_t *api, const mcps_data_conf_t *data) 00468 { 00469 cmd_printf("MCPS-DATA.confirm\n"); 00470 if (!silent_mode) { 00471 cmd_printf("msduHandle: %hhu\n", data->msduHandle); 00472 cmd_printf("status: %hhu (%s)\n", data->status, mlme_status_string(data->status)); 00473 cmd_printf("timestamp: %lu\n", data->timestamp); 00474 cmd_printf("cca_retries:%hhu\n", data->cca_retries); 00475 cmd_printf("tx_retries: %hhu\n", data->tx_retries); 00476 } 00477 if (data->status == expected_statuses.data_conf) { 00478 cmd_ready(CMDLINE_RETCODE_SUCCESS); 00479 } else { 00480 cmd_ready(CMDLINE_RETCODE_FAIL); 00481 } 00482 } 00483 00484 void mac_data_indication_handler(const mac_api_t *api, const mcps_data_ind_t *data) 00485 { 00486 cmd_printf("MCPS-DATA.indication\n"); 00487 if (!silent_mode) { 00488 cmd_printf("SrcAddrMode: %u\n", data->SrcAddrMode); 00489 cmd_printf("SrcPANId: 0x%04X\n", data->SrcPANId); 00490 cmd_printf("SrcAddr: %s\n", trace_array(data->SrcAddr, 8)); 00491 cmd_printf("DstAddrMode: %u\n", data->DstAddrMode); 00492 cmd_printf("DstPANId: 0x%04X\n", data->DstPANId); 00493 cmd_printf("DstAddr: %s\n", trace_array(data->DstAddr, 8)); 00494 cmd_printf("mpduLinkQuality:%hhu\n", data->mpduLinkQuality); 00495 cmd_printf("signal_dbm: %hhi\n", data->signal_dbm); 00496 cmd_printf("timestamp: %lu\n", data->timestamp); 00497 cmd_printf("DSN: %hhi\n", data->DSN); 00498 print_security(&data->Key); 00499 cmd_printf("msduLength %hu\n", data->msduLength); 00500 cmd_printf("msdu_ptr: %s <%.*s>\n", trace_array(data->msdu_ptr, data->msduLength), data->msduLength, data->msdu_ptr); 00501 } 00502 if (data->msdu_ptr && expected_statuses.data_ind) { 00503 if (data->msduLength != expected_statuses.data_ind_len) { 00504 return; 00505 } 00506 if (strncmp((const char*)data->msdu_ptr, (const char*)expected_statuses.data_ind, expected_statuses.data_ind_len) == 0) { 00507 ++data_count; 00508 } else { 00509 tr_warn("Received unexpected data!"); 00510 } 00511 } 00512 } 00513 00514 void mac_purge_confirm_handler(const mac_api_t *api, mcps_purge_conf_t *data) 00515 { 00516 cmd_printf("MCPS-PURGE.confirm\n"); 00517 if (!silent_mode) { 00518 cmd_printf("msduHandle: %hhu\n", data->msduHandle); 00519 cmd_printf("status: %hhu (%s)\n", data->status, mlme_status_string(data->status)); 00520 } 00521 if (data->status == expected_statuses.purge_conf) { 00522 cmd_ready(CMDLINE_RETCODE_SUCCESS); 00523 } else { 00524 cmd_ready(CMDLINE_RETCODE_FAIL); 00525 } 00526 } 00527 00528 void mac_mlme_confirm_handler(const mac_api_t *api, mlme_primitive id, const void *data) 00529 { 00530 switch (id) { 00531 case MLME_ASSOCIATE: { 00532 break; 00533 } 00534 case MLME_DISASSOCIATE: { 00535 break; 00536 } 00537 case MLME_GET: { 00538 mlme_get_conf_t *get_data = (mlme_get_conf_t*)data; 00539 cmd_printf("MLME-GET.confirm\n"); 00540 if (!silent_mode) { 00541 cmd_printf("status: %hhu (%s)\n", get_data->status, mlme_status_string(get_data->status)); 00542 cmd_printf("attr: %hhu\n", get_data->attr); 00543 cmd_printf("attr_index: %hhu\n", get_data->attr_index); 00544 cmd_printf("value_pointer: %s\n", trace_array((uint8_t*)get_data->value_pointer, get_data->value_size)); 00545 cmd_printf("value_size: %hhu\n", get_data->value_size); 00546 } 00547 if (get_data->status == expected_statuses.get_conf) { 00548 cmd_ready(CMDLINE_RETCODE_SUCCESS); 00549 } else { 00550 cmd_ready(CMDLINE_RETCODE_FAIL); 00551 } 00552 break; 00553 } 00554 case MLME_GTS: { 00555 break; 00556 } 00557 case MLME_RESET: { 00558 break; 00559 } 00560 case MLME_RX_ENABLE: { 00561 break; 00562 } 00563 case MLME_SCAN: { 00564 mlme_scan_conf_t *scan_data = (mlme_scan_conf_t*)data; 00565 cmd_printf("MLME-SCAN.confirm\n"); 00566 if (!silent_mode) { 00567 cmd_printf("status: %hhu (%s)\n", scan_data->status, mlme_status_string(scan_data->status)); 00568 cmd_printf("ScanType: %u\n", scan_data->ScanType); 00569 cmd_printf("ChannelPage: %hhu\n", scan_data->ChannelPage); 00570 cmd_printf("UnscannedChannels: 0x%08lX\n", scan_data->UnscannedChannels.channel_mask[0]); 00571 cmd_printf("ResultListSize: %hhu\n", scan_data->ResultListSize); 00572 } 00573 for (unsigned int i = 0; i < scan_data->ResultListSize; ++i) { 00574 if (scan_data->ScanType == MAC_ED_SCAN_TYPE) { 00575 cmd_printf("Channel %d ED value: %hhu\n", channel_from_mask(scan_req.ScanChannels.channel_mask[0], i), scan_data->ED_values[i]); 00576 memcpy(last_ed_results.ED_values, scan_data->ED_values, scan_data->ResultListSize); 00577 last_ed_results.count = scan_data->ResultListSize; 00578 for (int i = 0; i < scan_data->ResultListSize; ++i) { 00579 last_ed_results.channel[i] = channel_from_mask(scan_req.ScanChannels.channel_mask[0], i); 00580 } 00581 } else if (scan_data->ScanType == MAC_PASSIVE_SCAN) { 00582 print_PAN_descriptor(scan_data->PAN_values[i]); 00583 } 00584 } 00585 if (scan_data->status == expected_statuses.scan_conf || scan_data->status == MLME_LIMIT_REACHED) { 00586 cmd_ready(CMDLINE_RETCODE_SUCCESS); 00587 } else { 00588 cmd_ready(CMDLINE_RETCODE_FAIL); 00589 } 00590 break; 00591 } 00592 case MLME_SET: { 00593 break; 00594 } 00595 case MLME_START: { 00596 break; 00597 } 00598 case MLME_POLL: { 00599 mlme_poll_conf_t *poll_data = (mlme_poll_conf_t*)data; 00600 cmd_printf("MLME-POLL.confirm\n"); 00601 if (!silent_mode) { 00602 cmd_printf("status: %hhu (%s)\n", poll_data->status, mlme_status_string(poll_data->status)); 00603 cmd_printf("data_count %u\n", data_count); 00604 } 00605 if (expected_statuses.poll_conf == MLME_SUCCESS) { 00606 if (data_count == 1 && poll_data->status == MLME_SUCCESS) { 00607 cmd_ready(CMDLINE_RETCODE_SUCCESS); 00608 } else { 00609 cmd_ready(CMDLINE_RETCODE_FAIL); 00610 } 00611 } else if (expected_statuses.poll_conf == poll_data->status) { 00612 cmd_ready(CMDLINE_RETCODE_SUCCESS); 00613 } else { 00614 cmd_ready(CMDLINE_RETCODE_FAIL); 00615 } 00616 break; 00617 } 00618 default: { 00619 cmd_ready(CMDLINE_RETCODE_COMMAND_NOT_IMPLEMENTED); 00620 break; 00621 } 00622 } 00623 } 00624 00625 void mac_mlme_indication_handler(const mac_api_t *api, mlme_primitive id, const void *data) 00626 { 00627 switch (id) { 00628 case MLME_ASSOCIATE: { 00629 break; 00630 } 00631 case MLME_DISASSOCIATE: { 00632 break; 00633 } 00634 case MLME_BEACON_NOTIFY: { 00635 const mlme_beacon_ind_t *beacon_ind = (mlme_beacon_ind_t*)data; 00636 cmd_printf("MLME-BEACON-NOTIFY.indication\n"); 00637 if (!silent_mode) { 00638 cmd_printf("BSN: %hhu\n", beacon_ind->BSN); 00639 print_PAN_descriptor(&beacon_ind->PANDescriptor); 00640 cmd_printf("PendAddrSpec.short_address_count %u\n", beacon_ind->PendAddrSpec.short_address_count); 00641 cmd_printf("PendAddrSpec.extended_address_count %u\n", beacon_ind->PendAddrSpec.extended_address_count); 00642 cmd_printf("AddrList %s\n", trace_array(beacon_ind->AddrList, beacon_ind->PendAddrSpec.short_address_count * 2 + 00643 beacon_ind->PendAddrSpec.extended_address_count * 8)); 00644 cmd_printf("beacon_data_length %hu\n", beacon_ind->beacon_data_length); 00645 cmd_printf("beacon_data %s\n", trace_array(beacon_ind->beacon_data, beacon_ind->beacon_data_length)); 00646 } 00647 add_beacon(beacon_ind->beacon_data, beacon_ind->beacon_data_length); 00648 break; 00649 } 00650 case MLME_GTS: { 00651 break; 00652 } 00653 case MLME_ORPHAN: { 00654 break; 00655 } 00656 case MLME_COMM_STATUS: { 00657 cmd_printf("MLME-COMM-STATUS.indication\n"); 00658 const mlme_comm_status_t *comm_status_ind_data = (mlme_comm_status_t*)data; 00659 if (!silent_mode) { 00660 cmd_printf("PANId: 0x%04X\n", comm_status_ind_data->PANId); 00661 cmd_printf("SrcAddrMode: %u\n", comm_status_ind_data->SrcAddrMode); 00662 cmd_printf("SrcAddr: %s\n", trace_array(comm_status_ind_data->SrcAddr, 8)); 00663 cmd_printf("DstAddrMode: %u\n", comm_status_ind_data->DstAddrMode); 00664 cmd_printf("DstAddr: %s\n", trace_array(comm_status_ind_data->DstAddr, 8)); 00665 cmd_printf("status: %hhu (%s)\n", comm_status_ind_data->status, mlme_status_string(comm_status_ind_data->status)); 00666 print_security(&comm_status_ind_data->Key); 00667 } 00668 break; 00669 } 00670 case MLME_SYNC_LOSS: { 00671 break; 00672 } 00673 default: 00674 break; 00675 } 00676 } 00677 00678 int mac_start_command(int argc, char *argv[]) 00679 { 00680 char *str; 00681 int32_t val; 00682 bool boolean; 00683 00684 cmd_printf("MLME-START.request\n"); 00685 if (cmd_parameter_val(argc, argv, "--pan_id", &str)) { 00686 uint32_t pan_id = strtoul(str, NULL, 16); 00687 if (pan_id <= 0xFFFF) { 00688 start_req.PANId = pan_id; 00689 } else { 00690 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00691 } 00692 } 00693 if (cmd_parameter_int(argc, argv, "--logical_channel", &val)) { 00694 if (val >= 0 && val <= 26) { 00695 start_req.LogicalChannel = val; 00696 } else { 00697 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00698 } 00699 } 00700 if (cmd_parameter_int(argc, argv, "--channel_page", &val)) { 00701 if (val >= 0 && val <= 2) { 00702 start_req.ChannelPage = val; 00703 } else { 00704 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00705 } 00706 } 00707 if (cmd_parameter_int(argc, argv, "--start_time", &val)) { 00708 start_req.StartTime = val; 00709 } 00710 if (cmd_parameter_int(argc, argv, "--beacon_order", &val)) { 00711 if (val >= 0 && val <= 15) { 00712 start_req.BeaconOrder = val; 00713 } else { 00714 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00715 } 00716 } 00717 if (cmd_parameter_int(argc, argv, "--super_frame_order", &val)) { 00718 if (val >= 0 && val <= 15) { 00719 start_req.SuperframeOrder = val; 00720 } else { 00721 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00722 } 00723 } 00724 if (cmd_parameter_bool(argc, argv, "--pan_coordinator", &boolean)) { 00725 start_req.PANCoordinator = boolean; 00726 } 00727 if (cmd_parameter_bool(argc, argv, "--battery_life_extension", &boolean)) { 00728 start_req.BatteryLifeExtension = boolean; 00729 } 00730 if (cmd_parameter_bool(argc, argv, "--coord_realignment", &boolean)) { 00731 start_req.CoordRealignment = boolean; 00732 } 00733 mac_interface->mlme_req(mac_interface, MLME_START, &start_req); 00734 return CMDLINE_RETCODE_SUCCESS; 00735 } 00736 00737 int mac_scan_command(int argc, char *argv[]) 00738 { 00739 char *str; 00740 int32_t val; 00741 00742 cmd_printf("MLME-SCAN.request\n"); 00743 if (cmd_parameter_int(argc, argv, "--scan_type", &val)) { 00744 if (val >= 0 && val <= 3) { 00745 scan_req.ScanType = (mac_scan_type_t)val; 00746 } else { 00747 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00748 } 00749 } 00750 if (cmd_parameter_int(argc, argv, "--channel_page_enum", &val)) { 00751 if (val >= 0 && val <= 10) { 00752 scan_req.ScanChannels.channel_page = (channel_page_e)val; 00753 } else { 00754 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00755 } 00756 } 00757 if (cmd_parameter_val(argc, argv, "--channel_mask", &str)) { 00758 scan_req.ScanChannels.channel_mask[0] = strtoul(str, NULL, 16); 00759 } 00760 if (cmd_parameter_int(argc, argv, "--scan_duration", &val)) { 00761 if (val >= 0 && val <= 14) { 00762 scan_req.ScanDuration = val; 00763 } else { 00764 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00765 } 00766 } 00767 if (cmd_parameter_int(argc, argv, "--channel_page", &val)) { 00768 if (val >= 0 && val <= 2) { 00769 scan_req.ChannelPage = val; 00770 } else { 00771 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00772 } 00773 } 00774 if (handle_security_args(argc, argv, &scan_req.Key) != CMDLINE_RETCODE_SUCCESS) { 00775 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00776 } 00777 clear_beacons(); 00778 mac_interface->mlme_req(mac_interface, MLME_SCAN, &scan_req); 00779 return CMDLINE_RETCODE_EXCUTING_CONTINUE; 00780 } 00781 00782 int mac_data_command(int argc, char *argv[]) 00783 { 00784 char *str; 00785 int32_t val; 00786 bool boolean; 00787 00788 cmd_printf("MCPS-DATA.request\n"); 00789 if (cmd_parameter_int(argc, argv, "--src_addr_mode", &val)) { 00790 if (val == 0 || val == 2 || val == 3) { 00791 data_req.SrcAddrMode = val; 00792 } else { 00793 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00794 } 00795 } 00796 if (cmd_parameter_int(argc, argv, "--dst_addr_mode", &val)) { 00797 if (val == 0 || val == 2 || val == 3) { 00798 data_req.DstAddrMode = val; 00799 } else { 00800 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00801 } 00802 } 00803 if (cmd_parameter_val(argc, argv, "--dst_pan_id", &str)) { 00804 uint32_t pan_id = strtoul(str, NULL, 16); 00805 if (pan_id <= 0xFFFF) { 00806 data_req.DstPANId = pan_id; 00807 } else { 00808 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00809 } 00810 } 00811 if (cmd_parameter_val(argc, argv, "--dst_addr", &str)) { 00812 int len = (data_req.DstAddrMode == 2 ? 2 : 8); 00813 if (string_to_bytes(str, data_req.DstAddr, len) != 0) { 00814 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00815 } 00816 } 00817 if (cmd_parameter_int(argc, argv, "--msdu_length", &val)) { 00818 data_req.msduLength = val; 00819 } 00820 if (cmd_parameter_val(argc, argv, "--msdu", &str)) { 00821 ns_dyn_mem_free(data_req.msdu); 00822 if (strlen(str) != data_req.msduLength) { 00823 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00824 } 00825 data_req.msdu = (uint8_t*)ns_dyn_mem_temporary_alloc(data_req.msduLength); 00826 if (data_req.msdu == NULL) { 00827 tr_error("Failed to allocate memory for the msdu"); 00828 return CMDLINE_RETCODE_FAIL; 00829 } 00830 std::memcpy(data_req.msdu, str, data_req.msduLength); 00831 } 00832 if (cmd_parameter_int(argc, argv, "--msdu_handle", &val)) { 00833 if (val >= 0 && val <= 255) { 00834 data_req.msduHandle = val; 00835 } 00836 } 00837 if (cmd_parameter_bool(argc, argv, "--tx_ack_req", &boolean)) { 00838 data_req.TxAckReq = boolean; 00839 } 00840 if (cmd_parameter_bool(argc, argv, "--indirect_tx", &boolean)) { 00841 data_req.InDirectTx = boolean; 00842 } 00843 if (cmd_parameter_bool(argc, argv, "--pending_bit", &boolean)) { 00844 data_req.PendingBit = boolean; 00845 } 00846 if (cmd_parameter_bool(argc, argv, "--wait_for_confirm", &boolean)) { 00847 wait_for_confirm = boolean; 00848 } 00849 if (handle_security_args(argc, argv, &data_req.Key) != CMDLINE_RETCODE_SUCCESS) { 00850 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00851 } 00852 mac_interface->mcps_data_req(mac_interface, &data_req); 00853 if (wait_for_confirm) { 00854 return CMDLINE_RETCODE_EXCUTING_CONTINUE; 00855 } 00856 return CMDLINE_RETCODE_SUCCESS; 00857 } 00858 00859 int mac_poll_command(int argc, char *argv[]) 00860 { 00861 char *str; 00862 int32_t val; 00863 00864 cmd_printf("MLME-POLL.request\n"); 00865 data_count = 0; 00866 if (cmd_parameter_int(argc, argv, "--coord_addr_mode", &val)) { 00867 if (val == 2 || val == 3) { 00868 poll_req.CoordAddrMode = val; 00869 } else { 00870 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00871 } 00872 } 00873 if (cmd_parameter_val(argc, argv, "--coord_pan_id", &str)) { 00874 unsigned long pan_id = strtoul(str, NULL, 16); 00875 if (pan_id <= 0xFFFF) { 00876 poll_req.CoordPANId = pan_id; 00877 } else { 00878 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00879 } 00880 } 00881 if (cmd_parameter_val(argc, argv, "--coord_address", &str)) { 00882 int len = (poll_req.CoordAddrMode == 2 ? 2: 8); 00883 if (string_to_bytes(str, poll_req.CoordAddress, len) != 0) { 00884 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00885 } 00886 } 00887 if (handle_security_args(argc, argv, &poll_req.Key) != CMDLINE_RETCODE_SUCCESS) { 00888 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00889 } 00890 mac_interface->mlme_req(mac_interface, MLME_POLL, &poll_req); 00891 return CMDLINE_RETCODE_EXCUTING_CONTINUE; 00892 } 00893 00894 int mac_purge_command(int argc, char *argv[]) 00895 { 00896 int32_t val; 00897 00898 cmd_printf("MCPS-PURGE.request\n"); 00899 if (cmd_parameter_int(argc, argv, "--msdu_handle", &val)) { 00900 if (val >= 0 && val <= 255) { 00901 purge_req.msduHandle = val; 00902 } else { 00903 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00904 } 00905 } 00906 mac_interface->mcps_purge_req(mac_interface, &purge_req); 00907 return CMDLINE_RETCODE_EXCUTING_CONTINUE; 00908 } 00909 00910 int mac_set_command(int argc, char *argv[]) 00911 { 00912 char *str; 00913 int32_t val; 00914 uint8_t val_uint8 = 0; 00915 uint16_t val_uint16 = 0; 00916 uint32_t val_uint32 = 0; 00917 uint8_t *val_ptr_array = NULL; 00918 00919 cmd_printf("MLME-SET.request\n"); 00920 if (cmd_parameter_val(argc, argv, "--attr", &str)) { 00921 uint32_t attribute = strtoul(str, NULL, 16); 00922 if (attribute <= 255) { 00923 set_req.attr = (mlme_attr_t)attribute; 00924 } else { 00925 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00926 } 00927 } 00928 if (cmd_parameter_int(argc, argv, "--attr_index", &val)) { 00929 if (val >= 0 && val <= 255) { 00930 set_req.attr_index = val; 00931 } else { 00932 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00933 } 00934 } 00935 if (cmd_parameter_val(argc, argv, "--value_ascii", &str)) { 00936 val_ptr_array = (uint8_t*)ns_dyn_mem_temporary_alloc(strlen(str)); 00937 if (val_ptr_array == NULL) { 00938 tr_error("Failed to allocate memory for MLME-SET.request"); 00939 return CMDLINE_RETCODE_FAIL; 00940 } 00941 std::memcpy(val_ptr_array, str, strlen(str)); 00942 set_req.value_pointer = val_ptr_array; 00943 } else if (cmd_parameter_val(argc, argv, "--value_bytes", &str)) { 00944 size_t bytes = (strlen(str) + 1) / 3; 00945 val_ptr_array = (uint8_t*)ns_dyn_mem_temporary_alloc(bytes); 00946 if (val_ptr_array == NULL) { 00947 tr_error("Failed to allocate memory for MLME-SET.request"); 00948 return CMDLINE_RETCODE_FAIL; 00949 } 00950 if (string_to_bytes(str, val_ptr_array, bytes) != 0) { 00951 ns_dyn_mem_free(val_ptr_array); 00952 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00953 } 00954 set_req.value_pointer = val_ptr_array; 00955 } else if (cmd_parameter_int(argc, argv, "--value_uint8", &val)) { 00956 if (val >= 0 && val <= 0xFF) { 00957 val_uint8 = val; 00958 set_req.value_pointer = &val_uint8; 00959 } else { 00960 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00961 } 00962 } else if (cmd_parameter_int(argc, argv, "--value_uint16", &val)) { 00963 if (val >= 0 && val <= 0xFFFF) { 00964 val_uint16 = val; 00965 set_req.value_pointer = &val_uint16; 00966 } else { 00967 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00968 } 00969 } else if (cmd_parameter_int(argc, argv, "--value_uint32", &val)) { 00970 if (val >= 0 && val <= 0x7FFFFFFF) { 00971 val_uint32 = val; 00972 set_req.value_pointer = &val_uint32; 00973 } else { 00974 return CMDLINE_RETCODE_INVALID_PARAMETERS; 00975 } 00976 } 00977 if (cmd_parameter_int(argc, argv, "--value_size", &val)) { 00978 if (val >= 0 && val <= 255) { 00979 set_req.value_size = val; 00980 } 00981 } 00982 00983 mac_interface->mlme_req(mac_interface, MLME_SET, &set_req); 00984 ns_dyn_mem_free(val_ptr_array); 00985 set_req.value_pointer = NULL; 00986 return CMDLINE_RETCODE_SUCCESS; 00987 } 00988 00989 int mac_get_command(int argc, char *argv[]) 00990 { 00991 char *str; 00992 int32_t val; 00993 00994 cmd_printf("MLME-GET.request\n"); 00995 if (cmd_parameter_val(argc, argv, "--attr", &str)) { 00996 uint32_t attribute = strtoul(str, NULL, 16); 00997 if (attribute <= 255) { 00998 get_req.attr = (mlme_attr_t)attribute; 00999 } else { 01000 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01001 } 01002 } 01003 if (cmd_parameter_int(argc, argv, "--attr_index", &val)) { 01004 if (val >= 0 && val <= 255) { 01005 get_req.attr_index = val; 01006 } else { 01007 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01008 } 01009 } 01010 mac_interface->mlme_req(mac_interface, MLME_GET, &get_req); 01011 return CMDLINE_RETCODE_SUCCESS; 01012 } 01013 01014 int mac_reset_command(int argc, char *argv[]) 01015 { 01016 bool boolean; 01017 01018 cmd_printf("MLME-RESET.request\n"); 01019 if (cmd_parameter_bool(argc, argv, "--set_default_pib", &boolean)) { 01020 reset_req.SetDefaultPIB = boolean; 01021 } 01022 mac_interface->mlme_req(mac_interface, MLME_RESET, &reset_req); 01023 return CMDLINE_RETCODE_SUCCESS; 01024 } 01025 01026 int mac_address_command(int argc, char *argv[]) 01027 { 01028 char *str; 01029 uint8_t ext_addr[8]; 01030 01031 if (cmd_parameter_val(argc, argv, "--64-bit", &str)) { 01032 if (string_to_bytes(str, ext_addr, 8) != 0) { 01033 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01034 } 01035 mac_interface->mac64_set(mac_interface, ext_addr); 01036 cmd_printf("64-bit MAC address set to: %s\n", trace_array(ext_addr, 8)); 01037 } else if (cmd_parameter_val(argc, argv, "--16-bit", &str)) { 01038 uint32_t short_addr_32 = strtoul(str, NULL, 16); 01039 if (short_addr_32 <= 0xFFFF) { 01040 uint16_t short_addr = short_addr_32; 01041 mlme_set_t set_req; 01042 set_req.attr = macShortAddress; 01043 set_req.value_pointer = &short_addr; 01044 set_req.value_size = 2; 01045 mac_interface->mlme_req(mac_interface, MLME_SET, &set_req); 01046 cmd_printf("16-bit MAC address set to: 0x%04X\n", short_addr); 01047 } else { 01048 tr_warn("Invalid 16-bit MAC address given: %lu", short_addr_32); 01049 } 01050 } else if (argc == 1) { 01051 if (mac_interface->mac64_get(mac_interface, MAC_EXTENDED_READ_ONLY, ext_addr) == 0) { 01052 cmd_printf("EUI64: %s\n", trace_array(ext_addr, 8)); 01053 } else { 01054 tr_warn("Failed to read EUI64"); 01055 return CMDLINE_RETCODE_FAIL; 01056 } 01057 if (mac_interface->mac64_get(mac_interface, MAC_EXTENDED_DYNAMIC, ext_addr) == 0) { 01058 cmd_printf("MAC64: %s\n", trace_array(ext_addr, 8)); 01059 } else { 01060 tr_warn("Failed to read MAC64"); 01061 return CMDLINE_RETCODE_FAIL; 01062 } 01063 } else { 01064 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01065 } 01066 return CMDLINE_RETCODE_SUCCESS; 01067 } 01068 01069 static int key_config_command(int argc, char *argv[]) 01070 { 01071 char *str; 01072 int32_t val; 01073 bool boolean; 01074 int lookup_index = 0, device_index = 0, usage_index = 0; 01075 01076 if (cmd_parameter_val(argc, argv, "--key", &str)) { 01077 if (strlen(str) == 2*16+15) { 01078 if (string_to_bytes(str, key_descriptor.Key, 16) != 0) { 01079 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01080 } 01081 } else { 01082 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01083 } 01084 } 01085 if (cmd_parameter_int(argc, argv, "--key_id_lookup_list_entries", &val)) { 01086 if (val >= 0 && val < LOOKUP_DESCRIPTOR_TABLE_SIZE) { 01087 key_descriptor.KeyIdLookupListEntries = val; 01088 } else { 01089 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01090 } 01091 } 01092 if (cmd_parameter_int(argc, argv, "--key_device_list_entries", &val)) { 01093 if (val >= 0 && val < DEVICE_DESCRIPTOR_TABLE_SIZE) { 01094 key_descriptor.KeyDeviceListEntries = val; 01095 } else { 01096 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01097 } 01098 } 01099 if (cmd_parameter_int(argc, argv, "--key_usage_list_entries", &val)) { 01100 if (val >= 0 && val < USAGE_DESCRIPTOR_TABLE_SIZE) { 01101 key_descriptor.KeyUsageListEntries = val; 01102 } else { 01103 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01104 } 01105 } 01106 if (cmd_parameter_int(argc, argv, "--lookup_index", &val)) { 01107 if (val >= 0 && val < LOOKUP_DESCRIPTOR_TABLE_SIZE) { 01108 lookup_index = val; 01109 } else { 01110 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01111 } 01112 } 01113 if (cmd_parameter_val(argc, argv, "--lookup_data", &str)) { 01114 if (strlen(str) == 2*9+8) { 01115 if (string_to_bytes(str, key_descriptor.KeyIdLookupList[lookup_index].LookupData, 9) != 0) { 01116 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01117 } 01118 } else { 01119 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01120 } 01121 } 01122 if (cmd_parameter_int(argc, argv, "--lookup_data_size", &val)) { 01123 if (val == 0 || val == 1) { 01124 key_descriptor.KeyIdLookupList[lookup_index].LookupDataSize = val; 01125 } else { 01126 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01127 } 01128 } 01129 if (cmd_parameter_int(argc, argv, "--device_list_index", &val)) { 01130 if (val >= 0 && val < DEVICE_DESCRIPTOR_TABLE_SIZE) { 01131 device_index = val; 01132 } else { 01133 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01134 } 01135 } 01136 if (cmd_parameter_int(argc, argv, "--device_descriptor_handle", &val)) { 01137 if (val >= 0 && val <= 255) { 01138 key_descriptor.KeyDeviceList[device_index].DeviceDescriptorHandle = val; 01139 } else { 01140 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01141 } 01142 } 01143 if (cmd_parameter_bool(argc, argv, "--unique_device", &boolean)) { 01144 key_descriptor.KeyDeviceList[device_index].UniqueDevice = boolean; 01145 } 01146 if (cmd_parameter_bool(argc, argv, "--blacklisted", &boolean)) { 01147 key_descriptor.KeyDeviceList[device_index].Blacklisted = boolean; 01148 } 01149 if (cmd_parameter_int(argc, argv, "--usage_index", &val)) { 01150 if (val >= 0 && val <= USAGE_DESCRIPTOR_TABLE_SIZE) { 01151 usage_index = val; 01152 } else { 01153 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01154 } 01155 } 01156 if (cmd_parameter_int(argc, argv, "--frame_type", &val)) { 01157 if (val >= 0 && val <= 3) { 01158 key_descriptor.KeyUsageList[usage_index].FrameType = val; 01159 } else { 01160 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01161 } 01162 } 01163 if (key_descriptor.KeyUsageList[usage_index].FrameType == 3) { 01164 if (cmd_parameter_int(argc, argv, "--command_frame_identifier", &val)) { 01165 if (val >= 1 && val <= 9) { 01166 key_descriptor.KeyUsageList[usage_index].CommandFrameIdentifier = val; 01167 } else { 01168 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01169 } 01170 } 01171 } 01172 return CMDLINE_RETCODE_SUCCESS; 01173 } 01174 01175 static int key_add_command(int argc, char *argv[]) 01176 { 01177 mlme_set_t set_req; 01178 int32_t val; 01179 int key_index = 0; 01180 01181 if (cmd_parameter_int(argc, argv, "--index", &val)) { 01182 if (val >= 0 && val <= 255) { 01183 key_index = val; 01184 } else { 01185 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01186 } 01187 } 01188 01189 set_req.attr = macKeyTable; 01190 set_req.attr_index = key_index; 01191 set_req.value_pointer = &key_descriptor; 01192 set_req.value_size = sizeof(mlme_key_descriptor_entry_t); 01193 mac_interface->mlme_req(mac_interface, MLME_SET, &set_req); 01194 return CMDLINE_RETCODE_SUCCESS; 01195 } 01196 01197 int mac_key_command(int argc, char *argv[]) 01198 { 01199 char *cmd = argv[1]; 01200 01201 if (strcmp(cmd, "config") == 0) { 01202 return key_config_command(argc, argv); 01203 } else if (strcmp(cmd, "add") == 0) { 01204 return key_add_command(argc, argv); 01205 } 01206 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01207 } 01208 01209 int mac_add_neighbour_command(int argc, char *argv[]) 01210 { 01211 char *str; 01212 int32_t val; 01213 mlme_device_descriptor_t neighbour; 01214 mlme_set_t set_req; 01215 01216 neighbour.Exempt = false; 01217 if (cmd_parameter_int(argc, argv, "--frame_ctr", &val)) { 01218 neighbour.FrameCounter = val; 01219 } 01220 if (cmd_parameter_val(argc, argv, "--mac16", &str)) { 01221 uint32_t short_addr = strtoul(str, NULL, 16); 01222 if (short_addr <= 0xFFFF) { 01223 neighbour.ShortAddress = short_addr; 01224 } else { 01225 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01226 } 01227 } 01228 if (cmd_parameter_val(argc, argv, "--mac64", &str)) { 01229 if (strlen(str) == 2*8+7) { 01230 if (string_to_bytes(str, neighbour.ExtAddress, 8) != 0) { 01231 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01232 } 01233 } else { 01234 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01235 } 01236 } 01237 if (cmd_parameter_val(argc, argv, "--pan_id", &str)) { 01238 uint32_t pan_id = strtoul(str, NULL, 16); 01239 if (pan_id <= 0xFFFF) { 01240 neighbour.PANId = val; 01241 } else { 01242 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01243 } 01244 } 01245 if (cmd_parameter_int(argc, argv, "--index", &val)) { 01246 if (val >= 0 && val <= 255) { 01247 set_req.attr_index = val; 01248 } else { 01249 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01250 } 01251 } 01252 01253 set_req.attr = macDeviceTable; 01254 set_req.value_pointer = &neighbour; 01255 set_req.value_size = sizeof(mlme_device_descriptor_t); 01256 mac_interface->mlme_req(mac_interface, MLME_SET, &set_req); 01257 return CMDLINE_RETCODE_SUCCESS; 01258 } 01259 01260 #ifndef DISABLE_FILTERING 01261 static int filter_start(int argc, char *argv[]) 01262 { 01263 char *str; 01264 01265 if (cmd_parameter_val(argc, argv, "--mode", &str)) { 01266 if (strcmp(str, "allow") == 0) { 01267 return mac_filter_start(mac_interface->parent_id, MAC_FILTER_ALLOWED) < 0 ? CMDLINE_RETCODE_FAIL : CMDLINE_RETCODE_SUCCESS; 01268 } else if (strcmp(str, "block") == 0) { 01269 return mac_filter_start(mac_interface->parent_id, MAC_FILTER_BLOCKED) < 0 ? CMDLINE_RETCODE_FAIL : CMDLINE_RETCODE_SUCCESS;; 01270 } else if (strcmp(str, "fixed") == 0) { 01271 int32_t lqi, dbm; 01272 if (cmd_parameter_int(argc, argv, "--lqi_m", &lqi) && 01273 cmd_parameter_int(argc, argv, "--dbm_m", &dbm)) { 01274 return mac_filter_start(mac_interface->parent_id, MAC_FILTER_FIXED(lqi, dbm)) < 0 ? CMDLINE_RETCODE_FAIL : CMDLINE_RETCODE_SUCCESS; 01275 } 01276 } 01277 } 01278 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01279 } 01280 01281 static int filter_add(int argc, char *argv[]) 01282 { 01283 char *str; 01284 uint32_t short_addr; 01285 uint8_t long_addr[8]; 01286 int32_t lqi_m, lqi_add, dbm_m, dbm_add; 01287 01288 if (cmd_parameter_int(argc, argv, "--lqi_m", &lqi_m) && 01289 cmd_parameter_int(argc, argv, "--lqi_add", &lqi_add) && 01290 cmd_parameter_int(argc, argv, "--dbm_m", &dbm_m) && 01291 cmd_parameter_int(argc, argv, "--dbm_add", &dbm_add)) { 01292 } else if (cmd_parameter_val(argc, argv, "--mode", &str)) { 01293 if (strcmp(str, "allow")) { 01294 lqi_m = dbm_m = 256; 01295 lqi_add = dbm_add = 0; 01296 } else if (strcmp(str, "block")) { 01297 lqi_m = lqi_add = dbm_m = dbm_add = 0; 01298 } else if (strcmp(str, "fixed")) { 01299 lqi_add = dbm_add = 0; 01300 if (cmd_parameter_int(argc, argv, "--lqi_m", &lqi_m) && 01301 cmd_parameter_int(argc, argv, "--dbm_m", &dbm_m)) { 01302 } else { 01303 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01304 } 01305 } else { 01306 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01307 } 01308 } else { 01309 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01310 } 01311 01312 if (cmd_parameter_val(argc, argv, "--short", &str)) { 01313 short_addr = strtoul(str, NULL, 16); 01314 if (short_addr <= 0xFFFF) { 01315 return mac_filter_add_short(mac_interface->parent_id, short_addr, lqi_m, lqi_add, dbm_m, dbm_add) < 0 ? CMDLINE_RETCODE_FAIL : CMDLINE_RETCODE_SUCCESS; 01316 } else { 01317 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01318 } 01319 } else if (cmd_parameter_val(argc, argv, "--long", &str)) { 01320 if (string_to_bytes(str, long_addr, 8) != 0) { 01321 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01322 } 01323 return mac_filter_add_long(mac_interface->parent_id, long_addr, lqi_m, lqi_add, dbm_m, dbm_add) < 0 ? CMDLINE_RETCODE_FAIL : CMDLINE_RETCODE_SUCCESS; 01324 } else { 01325 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01326 } 01327 } 01328 01329 static int filter_remove(int argc, char *argv[]) 01330 { 01331 char *str; 01332 uint32_t short_addr; 01333 uint8_t long_addr[8]; 01334 01335 if (cmd_parameter_val(argc, argv, "--short", &str)) { 01336 short_addr = strtoul(str, NULL, 16); 01337 if (short_addr <= 0xFFFF) { 01338 return mac_filter_delete_short(mac_interface->parent_id, short_addr) < 0 ? CMDLINE_RETCODE_FAIL : CMDLINE_RETCODE_SUCCESS; 01339 } else { 01340 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01341 } 01342 } else if (cmd_parameter_val(argc, argv, "--long", &str)) { 01343 if (string_to_bytes(str, long_addr, 8) != 0) { 01344 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01345 } 01346 return mac_filter_delete_long(mac_interface->parent_id, long_addr) < 0 ? CMDLINE_RETCODE_FAIL : CMDLINE_RETCODE_SUCCESS; 01347 } else { 01348 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01349 } 01350 } 01351 01352 static int filter_clear(int argc, char *argv[]) 01353 { 01354 return mac_filter_clear(mac_interface->parent_id) < 0 ? CMDLINE_RETCODE_FAIL : CMDLINE_RETCODE_SUCCESS; 01355 } 01356 01357 static int filter_stop(int argc, char *argv[]) 01358 { 01359 mac_filter_stop(mac_interface->parent_id); 01360 return CMDLINE_RETCODE_SUCCESS; 01361 } 01362 #else 01363 static int filter_start(int argc, char *argv[]) 01364 { 01365 (void)argc; 01366 (void)argv; 01367 return 0; 01368 } 01369 01370 static int filter_add(int argc, char *argv[]) 01371 { 01372 (void)argc; 01373 (void)argv; 01374 return 0; 01375 } 01376 static int filter_remove(int argc, char *argv[]) 01377 { 01378 (void)argc; 01379 (void)argv; 01380 return 0; 01381 } 01382 static int filter_clear(int argc, char *argv[]) 01383 { 01384 (void)argc; 01385 (void)argv; 01386 return 0; 01387 } 01388 static int filter_stop(int argc, char *argv[]) 01389 { 01390 (void)argc; 01391 (void)argv; 01392 return 0; 01393 } 01394 #endif 01395 int mac_filter_command(int argc, char *argv[]) 01396 { 01397 char *cmd = argv[1]; 01398 01399 if (strcmp(cmd, "start") == 0) { 01400 return filter_start(argc, argv); 01401 } else if (strcmp(cmd, "add") == 0) { 01402 return filter_add(argc, argv); 01403 } else if (strcmp(cmd, "remove") == 0) { 01404 return filter_remove(argc, argv); 01405 } else if (strcmp(cmd, "clear") == 0) { 01406 return filter_clear(argc, argv); 01407 } else if (strcmp(cmd, "stop") == 0) { 01408 return filter_stop(argc, argv); 01409 } 01410 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01411 } 01412 01413 int mac_config_status_command(int argc, char *argv[]) 01414 { 01415 int32_t val; 01416 char *str; 01417 01418 if (cmd_parameter_int(argc, argv, "--data_conf", &val)) { 01419 if (val >= 0 && val <= 255) { 01420 expected_statuses.data_conf = val; 01421 } else { 01422 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01423 } 01424 } else if (cmd_parameter_val(argc, argv, "--data_ind", &str)) { 01425 size_t len = strlen(str); 01426 ns_dyn_mem_free(expected_statuses.data_ind); 01427 expected_statuses.data_ind = (uint8_t*)ns_dyn_mem_temporary_alloc(len); 01428 expected_statuses.data_ind_len = len; 01429 std::memcpy(expected_statuses.data_ind, str, len); 01430 } else if (cmd_parameter_int(argc, argv, "--get", &val)) { 01431 if (val >= 0 && val <= 255) { 01432 expected_statuses.get_conf = val; 01433 } else { 01434 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01435 } 01436 } else if (cmd_parameter_int(argc, argv, "--scan", &val)) { 01437 if (val >= 0 && val <= 255) { 01438 expected_statuses.scan_conf = val; 01439 } else { 01440 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01441 } 01442 } else if (cmd_parameter_int(argc, argv, "--poll", &val)) { 01443 if (val >= 0 && val <= 255) { 01444 expected_statuses.poll_conf = val; 01445 } else { 01446 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01447 } 01448 } else if (cmd_parameter_int(argc, argv, "--purge", &val)) { 01449 if (val >= 0 && val <= 255) { 01450 expected_statuses.purge_conf = val; 01451 } else { 01452 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01453 } 01454 } else if (cmd_parameter_int(argc, argv, "--comm_status", &val)) { 01455 if (val >= 0 && val <= 255) { 01456 expected_statuses.comm_status_ind = val; 01457 } else { 01458 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01459 } 01460 } else if (cmd_parameter_index(argc, argv, "--list") != -1) { 01461 for (unsigned int i = 0; i < 256; ++i) { 01462 const char *status = mlme_status_string(i); 01463 if (status) { 01464 cmd_printf("%hhu\t%s\n", i, status); 01465 } 01466 } 01467 } else if (cmd_parameter_index(argc, argv, "--reset") != -1) { 01468 expected_statuses.data_conf = MLME_SUCCESS; 01469 expected_statuses.get_conf = MLME_SUCCESS; 01470 expected_statuses.scan_conf = MLME_SUCCESS; 01471 expected_statuses.poll_conf = MLME_SUCCESS; 01472 expected_statuses.purge_conf = MLME_SUCCESS; 01473 expected_statuses.comm_status_ind = MLME_SUCCESS; 01474 expected_statuses.data_ind_len = 0; 01475 expected_statuses.data_ind = NULL; 01476 } else if (argc == 1) { 01477 cmd_printf("MCPS-DATA.confirm: %d (%s)\n", expected_statuses.data_conf, mlme_status_string(expected_statuses.data_conf)); 01478 cmd_printf("MLME-GET.confirm: %d (%s)\n", expected_statuses.get_conf, mlme_status_string(expected_statuses.get_conf)); 01479 cmd_printf("MLME-SCAN.confirm: %d (%s)\n", expected_statuses.scan_conf, mlme_status_string(expected_statuses.scan_conf)); 01480 cmd_printf("MLME-POLL.confirm: %d (%s)\n", expected_statuses.poll_conf, mlme_status_string(expected_statuses.poll_conf)); 01481 cmd_printf("MCPS.PURGE.confirm. %d (%s)\n", expected_statuses.purge_conf, mlme_status_string(expected_statuses.purge_conf)); 01482 cmd_printf("MLME-COMM-STATUS.indication: %d (%s)\n", expected_statuses.comm_status_ind, mlme_status_string(expected_statuses.comm_status_ind)); 01483 cmd_printf("MCPS-DATA.indication: %s <%.*s>\n", trace_array(expected_statuses.data_ind, expected_statuses.data_ind_len), expected_statuses.data_ind_len, expected_statuses.data_ind); 01484 } else { 01485 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01486 } 01487 return CMDLINE_RETCODE_SUCCESS; 01488 } 01489 01490 int mac_find_beacon_command(int argc, char *argv[]) 01491 { 01492 char *str; 01493 01494 if (cmd_parameter_val(argc, argv, "--data", &str)) { 01495 for (int i = 0; i < MLME_MAC_RES_SIZE_MAX; ++i) { 01496 if (received_beacons.beacons[i] == NULL) { 01497 continue; 01498 } 01499 if (strncmp(received_beacons.beacons[i], str, received_beacons.beacon_lengths[i]) == 0) { 01500 return CMDLINE_RETCODE_SUCCESS; 01501 } 01502 } 01503 return CMDLINE_RETCODE_FAIL; 01504 } else { 01505 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01506 } 01507 } 01508 01509 int mac_wait_command(int argc, char *argv[]) 01510 { 01511 int32_t val; 01512 static uint32_t timeout_ms = 1000; 01513 int remaining_ms = timeout_ms; 01514 if (cmd_parameter_int(argc, argv, "--timeout", &val)) { 01515 if (val >= 0) { 01516 timeout_ms = val; 01517 } else { 01518 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01519 } 01520 } 01521 while (data_count < 1) { 01522 ThisThread::sleep_for(10); 01523 remaining_ms -= 10; 01524 if (remaining_ms <= 0) { 01525 return CMDLINE_RETCODE_FAIL; 01526 } 01527 } 01528 data_count = 0; 01529 return CMDLINE_RETCODE_SUCCESS; 01530 } 01531 01532 int mac_analyze_ed_command(int argc, char *argv[]) 01533 { 01534 int32_t val; 01535 int channel; 01536 01537 if (cmd_parameter_int(argc, argv, "--channel", &val)) { 01538 if (val >= 0 && val <= 26) { 01539 channel = val; 01540 } else { 01541 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01542 } 01543 } else { 01544 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01545 } 01546 01547 if (cmd_parameter_int(argc, argv, "--above", &val)) { 01548 for (int i = 0; i < last_ed_results.count; ++i) { 01549 if (last_ed_results.channel[i] == channel) { 01550 return last_ed_results.ED_values[i] >= val ? CMDLINE_RETCODE_SUCCESS : CMDLINE_RETCODE_FAIL; 01551 } 01552 } 01553 } else if (cmd_parameter_int(argc, argv, "--below", &val)) { 01554 for (int i = 0; i < last_ed_results.count; ++i) { 01555 if (last_ed_results.channel[i] == channel) { 01556 return last_ed_results.ED_values[i] <= val ? CMDLINE_RETCODE_SUCCESS : CMDLINE_RETCODE_FAIL; 01557 } 01558 } 01559 } else { 01560 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01561 } 01562 return CMDLINE_RETCODE_FAIL; 01563 } 01564 01565 static void reset_security(mlme_security_t *sec) 01566 { 01567 sec->SecurityLevel = 0; 01568 sec->KeyIdMode = 0; 01569 sec->KeyIndex = 0; 01570 memset(sec->Keysource, 0, 8); 01571 } 01572 01573 int reset_command(int argc, char *argv[]) 01574 { 01575 wait_for_confirm = true; 01576 silent_mode = false; 01577 data_count = 0; 01578 01579 start_req.PANId = 0x1234; 01580 start_req.LogicalChannel = 11; 01581 start_req.ChannelPage = 0; 01582 start_req.StartTime = 0; 01583 start_req.BeaconOrder = 15; 01584 start_req.SuperframeOrder = 15; 01585 start_req.PANCoordinator = true; 01586 start_req.BatteryLifeExtension = false; 01587 start_req.CoordRealignment = false; 01588 reset_security(&start_req.CoordRealignKey); 01589 reset_security(&start_req.BeaconRealignKey); 01590 01591 scan_req.ScanType = MAC_ACTIVE_SCAN; 01592 scan_req.ScanChannels.channel_page = CHANNEL_PAGE_0; 01593 scan_req.ScanChannels.channel_mask[0] = 0x07FFF800; 01594 reset_security(&scan_req.Key); 01595 01596 data_req.SrcAddrMode = 3; 01597 data_req.DstAddrMode = 3; 01598 data_req.DstPANId = 0x1234; 01599 memset(data_req.DstAddr, 0, 8); 01600 data_req.msduLength = 0; 01601 data_req.msdu = NULL; 01602 data_req.msduHandle = 0; 01603 data_req.TxAckReq = true; 01604 data_req.InDirectTx = false; 01605 data_req.PendingBit = false; 01606 reset_security(&data_req.Key); 01607 01608 poll_req.CoordAddrMode = 3; 01609 poll_req.CoordPANId = 0x1234; 01610 memset(poll_req.CoordAddress, 0, 8); 01611 reset_security(&poll_req.Key); 01612 01613 purge_req.msduHandle = 0; 01614 01615 set_req.attr = (mlme_attr_t)0x39; 01616 set_req.attr_index = 0; 01617 set_req.value_pointer = NULL; 01618 set_req.value_size = 0; 01619 01620 get_req.attr = (mlme_attr_t)0x39; 01621 get_req.attr_index = 0; 01622 01623 reset_req.SetDefaultPIB = true; 01624 01625 return CMDLINE_RETCODE_SUCCESS; 01626 } 01627 01628 int silent_mode_command(int argc, char *argv[]) 01629 { 01630 char *cmd; 01631 if (argc < 2) { 01632 return CMDLINE_RETCODE_FAIL; 01633 } 01634 cmd = argv[1]; 01635 if (strcmp(cmd, "on") == 0) { 01636 silent_mode = true; 01637 return CMDLINE_RETCODE_SUCCESS; 01638 } else if (strcmp(cmd, "off") == 0) { 01639 silent_mode = false; 01640 return CMDLINE_RETCODE_SUCCESS; 01641 } else { 01642 return CMDLINE_RETCODE_INVALID_PARAMETERS; 01643 } 01644 }
Generated on Tue Aug 9 2022 00:37:12 by
1.7.2