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.
uwb_link.h
00001 // 00002 // Simple message protocol for UWB. 00003 // 00004 // Created by Benjamin Hepp on 02.04.16. 00005 // Copyright (c) 2016 Benjamin Hepp. All rights reserved. 00006 // 00007 00008 #pragma once 00009 00010 #include <string.h> 00011 #include <vector> 00012 00013 #include <ait_link/ait_link.h> 00014 00015 namespace ait { 00016 00017 class UWBMessageBody { 00018 public: 00019 virtual int getSize() const = 0; 00020 virtual void buildMessage(uint8_t* buffer) const = 0; 00021 virtual bool decodeMessage(const uint8_t* buffer, size_t buffer_size) = 0; 00022 }; 00023 00024 class UWBMessageString : public UWBMessageBody { 00025 public: 00026 UWBMessageString() 00027 : str_length_(-1), str_(NULL) { 00028 } 00029 00030 UWBMessageString(const char* str) 00031 : str_(str) { 00032 str_length_ = strlen(str); 00033 } 00034 00035 virtual int getSize() const { 00036 return str_length_ + 1; 00037 } 00038 00039 virtual void buildMessage(uint8_t* buffer) const { 00040 memcpy(buffer, str_, getSize()); 00041 } 00042 00043 virtual bool decodeMessage(const uint8_t* buffer, size_t buffer_size) { 00044 #ifdef __MBED__ 00045 // TODO: This can lead to a buffer overrun (something like strnlen should be used) 00046 str_length_ = strlen(reinterpret_cast<const char*>(buffer)); 00047 #else 00048 str_length_ = strnlen(reinterpret_cast<const char*>(buffer), buffer_size); 00049 if (str_length_ >= buffer_size) { 00050 return false; 00051 } 00052 #endif 00053 str_ = reinterpret_cast<const char*>(buffer); 00054 return true; 00055 } 00056 00057 int getStringLength() const { 00058 return str_length_; 00059 } 00060 00061 const char* getString() const { 00062 return str_; 00063 } 00064 00065 private: 00066 int str_length_; 00067 const char* str_; 00068 }; 00069 00070 struct UWBMessageMultiRange : public UWBMessageBody { 00071 UWBMessageMultiRange() 00072 : address(0), remote_address(0) { 00073 } 00074 00075 UWBMessageMultiRange(uint8_t address, uint8_t remote_address) 00076 : address(address), remote_address(remote_address) { 00077 } 00078 00079 void clearMeasurements() { 00080 timestamp_master_request_1.clear(); 00081 timestamp_slave_reply.clear(); 00082 timestamp_master_request_2.clear(); 00083 } 00084 00085 void addModuleMeasurement(uint64_t timestamp_master_request_1, uint64_t timestamp_slave_reply, uint64_t timestamp_master_request_2) { 00086 this->timestamp_master_request_1.push_back(timestamp_master_request_1); 00087 this->timestamp_slave_reply.push_back(timestamp_slave_reply); 00088 this->timestamp_master_request_2.push_back(timestamp_master_request_2); 00089 } 00090 00091 void setSlaveMeasurement(uint64_t timestamp_master_request_1_recv, uint64_t timestamp_slave_reply_send, uint64_t timestamp_master_request_2_recv) { 00092 this->timestamp_master_request_1_recv = timestamp_master_request_1_recv; 00093 this->timestamp_slave_reply_send = timestamp_slave_reply_send; 00094 this->timestamp_master_request_2_recv = timestamp_master_request_2_recv; 00095 } 00096 00097 int getNumOfModules() const { 00098 return timestamp_master_request_1.size(); 00099 } 00100 00101 virtual int getSize() const { 00102 return sizeof(uint8_t) + sizeof(address) + sizeof(remote_address) + (getNumOfModules() + 1) * 3 * sizeof(uint64_t); 00103 } 00104 00105 virtual void buildMessage(uint8_t* buffer) const { 00106 // Number of modules and addresses 00107 uint8_t num_of_modules = static_cast<uint8_t>(getNumOfModules()); 00108 *buffer = num_of_modules; 00109 ++buffer; 00110 *buffer = address; 00111 ++buffer; 00112 *buffer = remote_address; 00113 ++buffer; 00114 // Slave timestamps 00115 uint64_t* buffer_64 = reinterpret_cast<uint64_t*>(buffer); 00116 *buffer_64 = timestamp_master_request_1_recv; 00117 ++buffer_64; 00118 *buffer_64 = timestamp_slave_reply_send; 00119 ++buffer_64; 00120 *buffer_64 = timestamp_master_request_2_recv; 00121 ++buffer_64; 00122 // Master and listener timestamps 00123 for (int i = 0; i < num_of_modules; ++i) { 00124 *buffer_64 = timestamp_master_request_1[i]; 00125 ++buffer_64; 00126 *buffer_64 = timestamp_slave_reply[i]; 00127 ++buffer_64; 00128 *buffer_64 = timestamp_master_request_2[i]; 00129 ++buffer_64; 00130 } 00131 } 00132 00133 virtual bool decodeMessage(const uint8_t* buffer, size_t buffer_size) { 00134 if (buffer_size < sizeof(uint8_t) + sizeof(address) + sizeof(remote_address)) { 00135 return false; 00136 } 00137 00138 clearMeasurements(); 00139 00140 // Number of modules and addresses 00141 int num_of_modules = *buffer; 00142 ++buffer; 00143 address = *buffer; 00144 ++buffer; 00145 remote_address = *buffer; 00146 ++buffer; 00147 if (buffer_size < getSize()) { 00148 return false; 00149 } 00150 // Slave timestamps 00151 const uint64_t* buffer_64 = reinterpret_cast<const uint64_t*>(buffer); 00152 timestamp_master_request_1_recv = *buffer_64; 00153 ++buffer_64; 00154 timestamp_slave_reply_send = *buffer_64; 00155 ++buffer_64; 00156 timestamp_master_request_2_recv = *buffer_64; 00157 ++buffer_64; 00158 // Master and listener timestamps 00159 for (int i = 0; i < num_of_modules; ++i) { 00160 timestamp_master_request_1.push_back(*buffer_64); 00161 ++buffer_64; 00162 timestamp_slave_reply.push_back(*buffer_64); 00163 ++buffer_64; 00164 timestamp_master_request_2.push_back(*buffer_64); 00165 ++buffer_64; 00166 } 00167 return true; 00168 } 00169 00170 uint8_t address; 00171 uint8_t remote_address; 00172 00173 uint64_t timestamp_master_request_1_recv; 00174 uint64_t timestamp_slave_reply_send; 00175 uint64_t timestamp_master_request_2_recv; 00176 std::vector<uint64_t> timestamp_master_request_1; 00177 std::vector<uint64_t> timestamp_slave_reply; 00178 std::vector<uint64_t> timestamp_master_request_2; 00179 }; 00180 00181 class UWBMessage { 00182 public: 00183 const static uint8_t UWB_MESSAGE_TYPE_NOP = 0x00; 00184 const static uint8_t UWB_MESSAGE_TYPE_STATUS = 0x01; 00185 const static uint8_t UWB_MESSAGE_TYPE_MULTI_RANGE = 0x02; 00186 00187 UWBMessage() 00188 : type_(UWB_MESSAGE_TYPE_NOP), body_(NULL), part_allocated_(false) { 00189 } 00190 00191 UWBMessage(uint8_t type) 00192 : type_(type), body_(NULL), part_allocated_(false) { 00193 } 00194 00195 UWBMessage(uint8_t type, const UWBMessageBody* body) 00196 : type_(type), body_(body), part_allocated_(false) { 00197 } 00198 00199 ~UWBMessage() { 00200 clearMessageBody(); 00201 } 00202 00203 uint8_t getType() const { 00204 return type_; 00205 } 00206 00207 const UWBMessageBody* getMessageBody() const { 00208 return body_; 00209 } 00210 00211 void setMessageBody(const UWBMessageBody* body) { 00212 clearMessageBody(); 00213 body_ = body; 00214 } 00215 00216 int getSize() const { 00217 int size = sizeof(type_); 00218 if (body_ != NULL) { 00219 size += body_->getSize(); 00220 } 00221 return size; 00222 } 00223 00224 void buildMessage(uint8_t* buffer) const { 00225 buffer[0] = type_; 00226 if (body_ != NULL) { 00227 buffer += sizeof(type_); 00228 body_->buildMessage(buffer); 00229 } 00230 } 00231 00232 bool decodeMessage(const uint8_t* buffer, size_t buffer_size) { 00233 clearMessageBody(); 00234 part_allocated_ = true; 00235 if (buffer_size < sizeof(type_)) { 00236 return false; 00237 } 00238 type_ = buffer[0]; 00239 buffer += sizeof(type_); 00240 buffer_size -= sizeof(type_); 00241 switch (type_) { 00242 case UWB_MESSAGE_TYPE_NOP: { 00243 break; 00244 } 00245 case UWB_MESSAGE_TYPE_STATUS: { 00246 UWBMessageString *msg_string = new UWBMessageString(); 00247 if (msg_string->decodeMessage(buffer, buffer_size)) { 00248 body_ = msg_string; 00249 } else { 00250 delete msg_string; 00251 return false; 00252 } 00253 break; 00254 } 00255 case UWB_MESSAGE_TYPE_MULTI_RANGE: { 00256 UWBMessageMultiRange *msg_multi_range = new UWBMessageMultiRange(); 00257 if (msg_multi_range->decodeMessage(buffer, buffer_size)) { 00258 body_ = msg_multi_range; 00259 } else { 00260 delete msg_multi_range; 00261 return false; 00262 } 00263 break; 00264 } 00265 default: 00266 return false; 00267 } 00268 return true; 00269 } 00270 00271 private: 00272 void clearMessageBody() { 00273 if (part_allocated_) { 00274 delete body_; 00275 part_allocated_ = false; 00276 } 00277 body_ = NULL; 00278 } 00279 00280 uint8_t type_; 00281 const UWBMessageBody* body_; 00282 bool part_allocated_; 00283 }; 00284 00285 class UWBLink { 00286 public: 00287 UWBLink(AITLink* ait_link, int buffer_size = 1024) 00288 : handle_message_callback_(NULL), callback_user_data_(NULL), 00289 ait_link_(ait_link), buffer_size_(buffer_size) { 00290 buffer_ = new uint8_t[buffer_size]; 00291 ait_link_->registerFrameHandler(&UWBLink::handleFrameWrapper, this); 00292 } 00293 00294 virtual ~UWBLink() { 00295 delete[] buffer_; 00296 } 00297 00298 bool sendMessage(const UWBMessage& msg) { 00299 int size = msg.getSize(); 00300 if (size > buffer_size_) { 00301 return false; 00302 } 00303 msg.buildMessage(buffer_); 00304 ait_link_->sendFrame(buffer_, size); 00305 return true; 00306 } 00307 00308 void registerMessageHandler(void (*callback)(void* user_data, const UWBMessage& msg), void* user_data) { 00309 handle_message_callback_ = callback; 00310 callback_user_data_ = user_data; 00311 } 00312 00313 void inputReceivedChar(uint8_t data) { 00314 ait_link_->inputReceivedChar(data); 00315 } 00316 00317 protected: 00318 virtual void handleMessage(const UWBMessage& msg) { 00319 if (handle_message_callback_ != NULL) { 00320 (*handle_message_callback_)(callback_user_data_, msg); 00321 } 00322 } 00323 00324 void (*handle_message_callback_)(void* user_data, const UWBMessage& msg); 00325 void* callback_user_data_; 00326 00327 private: 00328 void handleFrame(const uint8_t* frame_buffer, size_t frame_length) { 00329 UWBMessage msg; 00330 if (msg.decodeMessage(frame_buffer, frame_length)) { 00331 handleMessage(msg); 00332 } else { 00333 fprintf(stderr, "Failed to decode UWB message"); 00334 } 00335 } 00336 00337 static void handleFrameWrapper(void* user_data, const uint8_t* frame_buffer, size_t frame_length) { 00338 UWBLink* uwb_link = reinterpret_cast<UWBLink*>(user_data); 00339 uwb_link->handleFrame(frame_buffer, frame_length); 00340 } 00341 00342 AITLink* ait_link_; 00343 uint8_t* buffer_; 00344 int buffer_size_; 00345 }; 00346 00347 }
Generated on Wed Jul 13 2022 13:24:57 by
1.7.2