BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
mle_tlv.c
00001 /* 00002 * Copyright (c) 2014-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 "nsconfig.h" 00018 #include "ns_trace.h" 00019 #include "string.h" 00020 #include "MLE/mle.h" 00021 #include "MLE/mle_tlv.h" 00022 #include "common_functions.h" 00023 #include "Service_Libs/mle_service/mle_service_api.h" 00024 00025 int mle_message_malformed_check(uint8_t *ptr, uint16_t data_len) 00026 { 00027 uint8_t *dptr; 00028 uint16_t length; 00029 dptr = ptr; 00030 while (data_len) { 00031 if (data_len >= 2) { 00032 dptr += 1; //Skip TLV Type 00033 length = *dptr++; 00034 if (length == 0xff) { 00035 // Long length format 00036 data_len -= 2; 00037 if (data_len < 2) { 00038 return -1; 00039 } 00040 length = common_read_16_bit(dptr); 00041 dptr += 2; 00042 } 00043 data_len -= 2; 00044 if (data_len >= length) { 00045 if (length) { 00046 data_len -= length; 00047 dptr += length; 00048 } 00049 } else { 00050 // buffer is overrun this is malformed. 00051 return -1; 00052 } 00053 } else { 00054 return -1; 00055 } 00056 } 00057 return 0; 00058 } 00059 00060 int mle_tlv_option_discover(uint8_t *ptr, uint16_t data_len, mle_tlv_type_t discovered_type, mle_tlv_info_t *option_info) 00061 { 00062 uint8_t *dptr; 00063 uint16_t length; 00064 mle_tlv_type_t type; 00065 00066 option_info->tlvLen = 0; 00067 option_info->tlvType = MLE_TYPE_UNASSIGNED; 00068 option_info->dataPtr = NULL; 00069 dptr = ptr; 00070 while (data_len) { 00071 type = (mle_tlv_type_t) * dptr++; 00072 length = *dptr++; 00073 if (length == 0xff) { 00074 // Long length format 00075 data_len -= 2; 00076 if (data_len < 2) { 00077 return -1; 00078 } 00079 length = common_read_16_bit(dptr); 00080 dptr += 2; 00081 } 00082 data_len -= 2; 00083 if (data_len >= length) { 00084 if (type == discovered_type) { 00085 option_info->tlvLen = length; 00086 option_info->tlvType = type; 00087 option_info->dataPtr = dptr; 00088 return length; 00089 } else { 00090 data_len -= length; 00091 dptr += length; 00092 } 00093 } 00094 } 00095 return -1; 00096 } 00097 00098 bool mle_tlv_type_requested(uint8_t reqType, uint8_t *ptr, uint16_t data_len) 00099 { 00100 mle_tlv_info_t tlv_info; 00101 bool retVal = false; 00102 if (mle_tlv_option_discover(ptr, data_len, MLE_TYPE_TLV_REQUEST, &tlv_info) > 0) { 00103 uint16_t i; 00104 uint8_t *t_ptr; 00105 t_ptr = tlv_info.dataPtr; 00106 for (i = 0; i < tlv_info.tlvLen; i++) { 00107 if (*t_ptr++ == reqType) { 00108 retVal = true; 00109 break; 00110 } 00111 } 00112 } 00113 return retVal; 00114 } 00115 00116 bool mle_tlv_read_8_bit_tlv(mle_tlv_type_t reqType, uint8_t *ptr, uint16_t data_len, uint8_t *buffer) 00117 { 00118 mle_tlv_info_t tlv_info; 00119 if (mle_tlv_option_discover(ptr, data_len, reqType, &tlv_info) >= 1) { 00120 uint8_t *t_ptr; 00121 t_ptr = tlv_info.dataPtr; 00122 *buffer = *t_ptr; 00123 return true; 00124 } 00125 00126 return false; 00127 } 00128 bool mle_tlv_read_16_bit_tlv(mle_tlv_type_t reqType, uint8_t *ptr, uint16_t data_len, uint16_t *buffer) 00129 { 00130 mle_tlv_info_t tlv_info; 00131 if (mle_tlv_option_discover(ptr, data_len, reqType, &tlv_info) >= 2) { 00132 *buffer = common_read_16_bit(tlv_info.dataPtr); 00133 return true; 00134 } 00135 00136 return false; 00137 } 00138 bool mle_tlv_read_32_bit_tlv(mle_tlv_type_t reqType, uint8_t *ptr, uint16_t data_len, uint32_t *buffer) 00139 { 00140 mle_tlv_info_t tlv_info; 00141 if (mle_tlv_option_discover(ptr, data_len, reqType, &tlv_info) >= 4) { 00142 *buffer = common_read_32_bit(tlv_info.dataPtr); 00143 return true; 00144 } 00145 00146 return false; 00147 } 00148 00149 bool mle_tlv_read_64_bit_tlv(mle_tlv_type_t reqType, uint8_t *ptr, uint16_t data_len, uint64_t *buffer) 00150 { 00151 mle_tlv_info_t tlv_info; 00152 if (mle_tlv_option_discover(ptr, data_len, reqType, &tlv_info) >= 8) { 00153 *buffer = common_read_64_bit(tlv_info.dataPtr); 00154 return true; 00155 } 00156 00157 return false; 00158 } 00159 00160 bool mle_registerd_address_data_check(uint8_t *ptr, uint8_t length) 00161 { 00162 uint8_t context; 00163 if (length < 9) { 00164 return false; 00165 } 00166 00167 while (length) { 00168 context = *ptr++; 00169 if (context & 0x80) { 00170 if (length < 9) { 00171 return false; 00172 } 00173 ptr += 8; 00174 length -= 9; 00175 } else { 00176 if (length < 17) { 00177 return false; 00178 } 00179 ptr += 16; 00180 length -= 17; 00181 } 00182 } 00183 return true; 00184 } 00185 00186 bool mle_tlv_read_tlv(mle_tlv_type_t reqType, uint8_t *ptr, uint16_t data_len, mle_tlv_info_t *tlv_info) 00187 { 00188 int length; 00189 length = mle_tlv_option_discover(ptr, data_len, reqType, tlv_info); 00190 if (length != -1) { 00191 if (reqType == MLE_TYPE_CHALLENGE && length > 3) { //32-bit challenge MIN which is accepted 00192 return true; 00193 } else if (reqType == MLE_TYPE_RESPONSE && length > 3) { //32-bit challenge MIN which is accepted 00194 return true; 00195 } else if (reqType == MLE_TYPE_ADDRESS_REGISTRATION && length) { 00196 return mle_registerd_address_data_check(tlv_info->dataPtr, length); 00197 } else if (reqType == MLE_TYPE_ROUTE && length >= 9) { 00198 return true; 00199 } else if (reqType == MLE_TYPE_LINK_METRICS_REPORT) { 00200 return true; 00201 }else if (reqType == MLE_TYPE_TLV_REQUEST || reqType == MLE_TYPE_NETWORK_DATA || 00202 reqType == MLE_TYPE_PENDING_OPERATIONAL_DATASET || reqType == MLE_TYPE_OPERATIONAL_DATASET) { 00203 return true; 00204 } 00205 } 00206 return false; 00207 } 00208 00209 uint8_t *mle_tlv_write_response(uint8_t *ptr, uint8_t *response_ptr, uint8_t responseLen) 00210 { 00211 *ptr++ = MLE_TYPE_RESPONSE; 00212 *ptr++ = responseLen; 00213 memcpy(ptr, response_ptr, responseLen); 00214 ptr += responseLen; 00215 return ptr; 00216 } 00217 00218 uint8_t *mle_tlv_write_source_address(uint8_t *ptr, uint16_t shortAddress) 00219 { 00220 *ptr++ = MLE_TYPE_SRC_ADDRESS; 00221 *ptr++ = 2; 00222 ptr = common_write_16_bit(shortAddress, ptr); 00223 return ptr; 00224 } 00225 00226 uint8_t *mle_tlv_write_short_address(uint8_t *ptr, uint16_t shortAddress) 00227 { 00228 *ptr++ = MLE_TYPE_ADDRESS16; 00229 *ptr++ = 2; 00230 ptr = common_write_16_bit(shortAddress, ptr); 00231 return ptr; 00232 } 00233 00234 uint8_t *mle_tlv_write_mode(uint8_t *ptr, uint8_t mode) 00235 { 00236 *ptr++ = MLE_TYPE_MODE; 00237 *ptr++ = 1; 00238 *ptr++ = mode; 00239 return ptr; 00240 } 00241 00242 uint8_t *mle_tlv_write_timeout(uint8_t *ptr, uint32_t timeOut) 00243 { 00244 *ptr++ = MLE_TYPE_TIMEOUT; 00245 *ptr++ = 4; 00246 ptr = common_write_32_bit(timeOut, ptr); 00247 return ptr; 00248 } 00249 00250 uint8_t *mle_tlv_write_challenge(uint8_t *ptr, uint8_t *challengePtr, uint8_t challenLen) 00251 { 00252 *ptr++ = MLE_TYPE_CHALLENGE; 00253 *ptr++ = challenLen; 00254 memcpy(ptr, challengePtr, challenLen); 00255 ptr += challenLen; 00256 return ptr; 00257 } 00258 00259 uint8_t *mle_tlv_write_link_layer_framecount(uint8_t *ptr, uint32_t frameCount) 00260 { 00261 *ptr++ = MLE_TYPE_LL_FRAME_COUNTER; 00262 *ptr++ = 4; 00263 ptr = common_write_32_bit(frameCount, ptr); 00264 return ptr; 00265 } 00266 00267 uint8_t *mle_tlv_write_framecounter(uint8_t *ptr, uint32_t frameCount) 00268 { 00269 *ptr++ = MLE_TYPE_MLE_FRAME_COUNTER; 00270 *ptr++ = 4; 00271 ptr = common_write_32_bit(frameCount, ptr); 00272 return ptr; 00273 } 00274 00275 uint8_t *mle_tlv_write_scan_mask(uint8_t *ptr, uint8_t scanMask) 00276 { 00277 *ptr++ = MLE_TYPE_SCAN_MASK; 00278 *ptr++ = 1; 00279 *ptr++ = scanMask; 00280 return ptr; 00281 } 00282 uint8_t *mle_tlv_req_tlv(uint8_t *ptr, uint8_t *mle_req_tlv_list, uint8_t req_list_len) 00283 { 00284 *ptr++ = MLE_TYPE_TLV_REQUEST; 00285 *ptr++ = req_list_len; 00286 memcpy(ptr, mle_req_tlv_list, req_list_len); 00287 ptr += req_list_len; 00288 return ptr; 00289 } 00290 uint8_t *mle_tlv_rssi_tlv(uint8_t *ptr, uint8_t linkMargin) 00291 { 00292 *ptr++ = MLE_TYPE_RSSI; 00293 *ptr++ = 1; 00294 *ptr++ = linkMargin; 00295 return ptr; 00296 } 00297 00298 uint8_t *mle_tlv_write_version(uint8_t *ptr, uint16_t version) 00299 { 00300 *ptr++ = MLE_TYPE_VERSION; 00301 *ptr++ = 2; 00302 ptr = common_write_16_bit(version, ptr); 00303 return ptr; 00304 } 00305 00306 uint8_t *mle_tlv_write_link_quality(uint8_t *ptr, uint8_t incoming_idr, uint8_t *mac64, uint16_t short_address, uint8_t priority_flag) 00307 { 00308 *ptr++ = MLE_TYPE_LINK_QUALITY; 00309 if (mac64) { 00310 *ptr++ = 11; 00311 *ptr++ = 0x07; /* 8 bytes long address */ 00312 } else { 00313 *ptr++ = 5; 00314 *ptr++ = 0x01; /* 2 bytes long address */ 00315 } 00316 00317 if (priority_flag) { 00318 *ptr++ = MLE_NEIGHBOR_PRIORITY_LINK | MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK; 00319 } else { 00320 *ptr++ = MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK; 00321 } 00322 00323 *ptr++ = incoming_idr; 00324 00325 if (mac64) { 00326 memcpy(ptr, mac64, 8); 00327 ptr += 8; 00328 } else { 00329 ptr = common_write_16_bit(short_address, ptr); 00330 } 00331 00332 return ptr; 00333 } 00334 00335 /** 00336 * This function will be used for validate response from ACCEPT or ACCEPT Request message 00337 */ 00338 uint16_t mle_tlv_validate_response(uint8_t *ptr, uint16_t data_len) 00339 { 00340 mle_tlv_info_t tlv_info; 00341 uint16_t msgId = 0; 00342 if (mle_tlv_option_discover(ptr, data_len, MLE_TYPE_RESPONSE, &tlv_info) > 3) { 00343 mle_service_transaction_buffer_get_for_response(tlv_info.dataPtr, tlv_info.tlvLen, &msgId); 00344 return msgId; 00345 } 00346 return msgId; 00347 } 00348 00349 bool mle_tlv_requested(uint8_t *tlv_ptr, uint16_t tlv_len, uint8_t tlv_type) 00350 { 00351 for (uint16_t i=0; i < tlv_len; i++) { 00352 if (tlv_ptr[i] == tlv_type) { 00353 return true; 00354 } 00355 } 00356 return false; 00357 } 00358 00359 void mle_tlv_ignore(uint8_t *tlv_ptr, uint16_t tlv_len, uint8_t tlv_type) 00360 { 00361 for (uint16_t i=0; i < tlv_len; i++) { 00362 if (tlv_ptr[i] == tlv_type) { 00363 tlv_ptr[i] = MLE_TYPE_UNASSIGNED; 00364 } 00365 } 00366 } 00367
Generated on Tue Jul 12 2022 12:22:12 by
