modded version CNMAT/OSC https://github.com/CNMAT/OSC

Dependents:   CVtoOSCConverter

Fork of osc-cnmat by Asperius van Hansen

Committer:
casiotone401
Date:
Sat Feb 13 11:29:14 2016 +0000
Revision:
4:107c23eb31b6
Parent:
2:61caa2495215
OSCMessage::send & OSCBundle::send supports return OSC buffer

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aspeteRakete 1:18009e3041ea 1 /*
aspeteRakete 1:18009e3041ea 2 Written by Yotam Mann, The Center for New Music and Audio Technologies,
aspeteRakete 1:18009e3041ea 3 University of California, Berkeley. Copyright (c) 2012, The Regents of
aspeteRakete 1:18009e3041ea 4 the University of California (Regents).
aspeteRakete 1:18009e3041ea 5
aspeteRakete 1:18009e3041ea 6 Permission to use, copy, modify, distribute, and distribute modified versions
aspeteRakete 1:18009e3041ea 7 of this software and its documentation without fee and without a signed
aspeteRakete 1:18009e3041ea 8 licensing agreement, is hereby granted, provided that the above copyright
aspeteRakete 1:18009e3041ea 9 notice, this paragraph and the following two paragraphs appear in all copies,
aspeteRakete 1:18009e3041ea 10 modifications, and distributions.
aspeteRakete 1:18009e3041ea 11
aspeteRakete 1:18009e3041ea 12 IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
aspeteRakete 1:18009e3041ea 13 SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
aspeteRakete 1:18009e3041ea 14 OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
aspeteRakete 1:18009e3041ea 15 BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
aspeteRakete 1:18009e3041ea 16
aspeteRakete 1:18009e3041ea 17 REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
aspeteRakete 1:18009e3041ea 18 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
aspeteRakete 1:18009e3041ea 19 PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
aspeteRakete 1:18009e3041ea 20 HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
aspeteRakete 1:18009e3041ea 21 MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
aspeteRakete 1:18009e3041ea 22
aspeteRakete 1:18009e3041ea 23 For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu
aspeteRakete 1:18009e3041ea 24 */
aspeteRakete 1:18009e3041ea 25
aspeteRakete 1:18009e3041ea 26 #include "OSCMessage.h"
aspeteRakete 1:18009e3041ea 27 #include "OSCMatch.h"
aspeteRakete 1:18009e3041ea 28
casiotone401 4:107c23eb31b6 29 // Fast strlen function http://www.strchr.com/optimized_strlen_function
casiotone401 4:107c23eb31b6 30 inline size_t strlengthgth(const char *s)
casiotone401 4:107c23eb31b6 31 {
casiotone401 4:107c23eb31b6 32 size_t len = 0;
casiotone401 4:107c23eb31b6 33
casiotone401 4:107c23eb31b6 34 for (;;)
casiotone401 4:107c23eb31b6 35 {
casiotone401 4:107c23eb31b6 36 unsigned x = *(unsigned*)s;
casiotone401 4:107c23eb31b6 37 if ((x & 0xFF) == 0) return len;
casiotone401 4:107c23eb31b6 38 if ((x & 0xFF00) == 0) return len + 1;
casiotone401 4:107c23eb31b6 39 if ((x & 0xFF0000) == 0) return len + 2;
casiotone401 4:107c23eb31b6 40 if ((x & 0xFF000000) == 0) return len + 3;
casiotone401 4:107c23eb31b6 41 s += 4, len += 4;
casiotone401 4:107c23eb31b6 42 }
casiotone401 4:107c23eb31b6 43 }
casiotone401 4:107c23eb31b6 44
aspeteRakete 1:18009e3041ea 45 /*=============================================================================
aspeteRakete 1:18009e3041ea 46 CONSTRUCTORS / DESTRUCTOR
aspeteRakete 1:18009e3041ea 47 =============================================================================*/
aspeteRakete 1:18009e3041ea 48
aspeteRakete 1:18009e3041ea 49 //constructor with address
aspeteRakete 1:18009e3041ea 50 OSCMessage::OSCMessage(const char * _address){
aspeteRakete 1:18009e3041ea 51 setupMessage();
aspeteRakete 1:18009e3041ea 52 setAddress(_address);
aspeteRakete 1:18009e3041ea 53 }
aspeteRakete 1:18009e3041ea 54
aspeteRakete 1:18009e3041ea 55 //constructor with nothing
aspeteRakete 1:18009e3041ea 56 //just a placeholder since the message is invalid
aspeteRakete 1:18009e3041ea 57 OSCMessage::OSCMessage(){
aspeteRakete 1:18009e3041ea 58 setupMessage();
aspeteRakete 1:18009e3041ea 59 error = INVALID_OSC;
aspeteRakete 1:18009e3041ea 60 }
aspeteRakete 1:18009e3041ea 61
aspeteRakete 1:18009e3041ea 62 //variable length constructor
aspeteRakete 1:18009e3041ea 63 //for example OSCMessage msg("/address", "isf", 1, "two", 3.0);
aspeteRakete 1:18009e3041ea 64 /*
aspeteRakete 1:18009e3041ea 65 OSCMessage::OSCMessage(const char * _address, char * types, ... ){
aspeteRakete 1:18009e3041ea 66 setupMessage(_address);
aspeteRakete 1:18009e3041ea 67 }
aspeteRakete 1:18009e3041ea 68 */
aspeteRakete 1:18009e3041ea 69
aspeteRakete 1:18009e3041ea 70 //sets up a new message
aspeteRakete 1:18009e3041ea 71 void OSCMessage::setupMessage(){
aspeteRakete 1:18009e3041ea 72 address = NULL;
aspeteRakete 1:18009e3041ea 73 //setup the attributes
aspeteRakete 1:18009e3041ea 74 dataCount = 0;
aspeteRakete 1:18009e3041ea 75 error = OSC_OK;
aspeteRakete 1:18009e3041ea 76 //setup the space for data
aspeteRakete 1:18009e3041ea 77 data = NULL;
aspeteRakete 1:18009e3041ea 78 //setup for filling the message
aspeteRakete 1:18009e3041ea 79 incomingBuffer = NULL;
aspeteRakete 1:18009e3041ea 80 incomingBufferSize = 0;
aspeteRakete 1:18009e3041ea 81 incomingBufferFree = 0;
aspeteRakete 1:18009e3041ea 82 clearIncomingBuffer();
aspeteRakete 1:18009e3041ea 83 //set the decode state
aspeteRakete 1:18009e3041ea 84 decodeState = STANDBY;
aspeteRakete 1:18009e3041ea 85 }
aspeteRakete 1:18009e3041ea 86
aspeteRakete 1:18009e3041ea 87 //DESTRUCTOR
aspeteRakete 1:18009e3041ea 88 OSCMessage::~OSCMessage(){
aspeteRakete 1:18009e3041ea 89 //free everything that needs to be freed
aspeteRakete 1:18009e3041ea 90 //free the address
aspeteRakete 1:18009e3041ea 91 free(address);
aspeteRakete 1:18009e3041ea 92 //free the data
aspeteRakete 1:18009e3041ea 93 empty();
aspeteRakete 1:18009e3041ea 94 //free the filling buffer
aspeteRakete 1:18009e3041ea 95 free(incomingBuffer);
aspeteRakete 1:18009e3041ea 96 }
aspeteRakete 1:18009e3041ea 97
aspeteRakete 1:18009e3041ea 98 void OSCMessage::empty(){
aspeteRakete 1:18009e3041ea 99 error = OSC_OK;
aspeteRakete 1:18009e3041ea 100 //free each of hte data in the array
aspeteRakete 1:18009e3041ea 101 for (int i = 0; i < dataCount; i++){
aspeteRakete 1:18009e3041ea 102 OSCData * datum = getOSCData(i);
aspeteRakete 1:18009e3041ea 103 //explicitly destruct the data
aspeteRakete 1:18009e3041ea 104 //datum->~OSCData();
aspeteRakete 1:18009e3041ea 105 delete datum;
aspeteRakete 1:18009e3041ea 106 }
aspeteRakete 1:18009e3041ea 107 //and free the array
aspeteRakete 1:18009e3041ea 108 free(data);
aspeteRakete 1:18009e3041ea 109 data = NULL;
aspeteRakete 1:18009e3041ea 110 dataCount = 0;
aspeteRakete 1:18009e3041ea 111 clearIncomingBuffer();
aspeteRakete 1:18009e3041ea 112 }
aspeteRakete 1:18009e3041ea 113
aspeteRakete 1:18009e3041ea 114 //COPY
aspeteRakete 1:18009e3041ea 115 OSCMessage::OSCMessage(OSCMessage * msg){
aspeteRakete 1:18009e3041ea 116 //start with a message with the same address
aspeteRakete 1:18009e3041ea 117 setupMessage();
aspeteRakete 1:18009e3041ea 118 setAddress(msg->address);
aspeteRakete 1:18009e3041ea 119 //add each of the data to the other message
aspeteRakete 1:18009e3041ea 120 for (int i = 0; i < msg->dataCount; i++){
aspeteRakete 1:18009e3041ea 121 add(msg->data[i]);
aspeteRakete 1:18009e3041ea 122 }
aspeteRakete 1:18009e3041ea 123 }
aspeteRakete 1:18009e3041ea 124
aspeteRakete 1:18009e3041ea 125 /*=============================================================================
aspeteRakete 1:18009e3041ea 126 GETTING DATA
aspeteRakete 1:18009e3041ea 127 =============================================================================*/
aspeteRakete 1:18009e3041ea 128
aspeteRakete 1:18009e3041ea 129 OSCData * OSCMessage::getOSCData(int position){
aspeteRakete 1:18009e3041ea 130 if (position < dataCount){
aspeteRakete 1:18009e3041ea 131 OSCData * datum = data[position];
aspeteRakete 1:18009e3041ea 132 return datum;
aspeteRakete 1:18009e3041ea 133 } else {
aspeteRakete 1:18009e3041ea 134 error = INDEX_OUT_OF_BOUNDS;
aspeteRakete 1:18009e3041ea 135 return NULL;
aspeteRakete 1:18009e3041ea 136 }
aspeteRakete 1:18009e3041ea 137 }
aspeteRakete 1:18009e3041ea 138
aspeteRakete 1:18009e3041ea 139 int32_t OSCMessage::getInt(int position){
aspeteRakete 1:18009e3041ea 140 OSCData * datum = getOSCData(position);
aspeteRakete 1:18009e3041ea 141 if (!hasError()){
aspeteRakete 1:18009e3041ea 142 return datum->getInt();
aspeteRakete 1:18009e3041ea 143 } else {
aspeteRakete 1:18009e3041ea 144 return NULL;
aspeteRakete 1:18009e3041ea 145 }
aspeteRakete 1:18009e3041ea 146 }
aspeteRakete 1:18009e3041ea 147 uint64_t OSCMessage::getTime(int position){
aspeteRakete 1:18009e3041ea 148 OSCData * datum = getOSCData(position);
aspeteRakete 1:18009e3041ea 149 if (!hasError()){
aspeteRakete 1:18009e3041ea 150 return datum->getTime();
aspeteRakete 1:18009e3041ea 151 } else {
aspeteRakete 1:18009e3041ea 152 return NULL;
aspeteRakete 1:18009e3041ea 153 }
aspeteRakete 1:18009e3041ea 154 }
aspeteRakete 1:18009e3041ea 155 float OSCMessage::getFloat(int position){
aspeteRakete 1:18009e3041ea 156 OSCData * datum = getOSCData(position);
aspeteRakete 1:18009e3041ea 157 if (!hasError()){
aspeteRakete 1:18009e3041ea 158 return datum->getFloat();
aspeteRakete 1:18009e3041ea 159 } else {
aspeteRakete 1:18009e3041ea 160 return NULL;
aspeteRakete 1:18009e3041ea 161 }
aspeteRakete 1:18009e3041ea 162 }
aspeteRakete 1:18009e3041ea 163
aspeteRakete 1:18009e3041ea 164 double OSCMessage::getDouble(int position){
aspeteRakete 1:18009e3041ea 165 OSCData * datum = getOSCData(position);
aspeteRakete 1:18009e3041ea 166 if (!hasError()){
aspeteRakete 1:18009e3041ea 167 return datum->getDouble();
aspeteRakete 1:18009e3041ea 168 } else {
aspeteRakete 1:18009e3041ea 169 return NULL;
aspeteRakete 1:18009e3041ea 170 }
aspeteRakete 1:18009e3041ea 171 }
aspeteRakete 1:18009e3041ea 172
aspeteRakete 1:18009e3041ea 173 int OSCMessage::getString(int position, char * buffer, int bufferSize){
aspeteRakete 1:18009e3041ea 174 OSCData * datum = getOSCData(position);
aspeteRakete 1:18009e3041ea 175 if (!hasError()){
aspeteRakete 1:18009e3041ea 176 //the number of bytes to copy is the smaller between the buffer size and the datum's byte length
aspeteRakete 1:18009e3041ea 177 int copyBytes = bufferSize < datum->bytes? bufferSize : datum->bytes;
aspeteRakete 1:18009e3041ea 178 return datum->getString(buffer, copyBytes);
aspeteRakete 1:18009e3041ea 179 } else {
aspeteRakete 1:18009e3041ea 180 return NULL;
aspeteRakete 1:18009e3041ea 181 }
aspeteRakete 1:18009e3041ea 182 }
aspeteRakete 1:18009e3041ea 183
aspeteRakete 1:18009e3041ea 184 int OSCMessage::getBlob(int position, uint8_t * buffer, int bufferSize){
aspeteRakete 1:18009e3041ea 185 OSCData * datum = getOSCData(position);
aspeteRakete 1:18009e3041ea 186 if (!hasError()){
aspeteRakete 1:18009e3041ea 187 //the number of bytes to copy is the smaller between the buffer size and the datum's byte length
aspeteRakete 1:18009e3041ea 188 int copyBytes = bufferSize < datum->bytes? bufferSize : datum->bytes;
aspeteRakete 1:18009e3041ea 189 return datum->getBlob(buffer, copyBytes);
aspeteRakete 1:18009e3041ea 190 } else {
aspeteRakete 1:18009e3041ea 191 return NULL;
aspeteRakete 1:18009e3041ea 192 }
aspeteRakete 1:18009e3041ea 193 }
aspeteRakete 1:18009e3041ea 194
aspeteRakete 1:18009e3041ea 195 char OSCMessage::getType(int position){
aspeteRakete 1:18009e3041ea 196 OSCData * datum = getOSCData(position);
aspeteRakete 1:18009e3041ea 197 if (!hasError()){
aspeteRakete 1:18009e3041ea 198 return datum->type;
aspeteRakete 1:18009e3041ea 199 } else {
aspeteRakete 1:18009e3041ea 200 return NULL;
aspeteRakete 1:18009e3041ea 201 }
aspeteRakete 1:18009e3041ea 202 }
aspeteRakete 1:18009e3041ea 203
aspeteRakete 1:18009e3041ea 204 int OSCMessage::getDataLength(int position){
aspeteRakete 1:18009e3041ea 205 OSCData * datum = getOSCData(position);
aspeteRakete 1:18009e3041ea 206 if (!hasError()){
aspeteRakete 1:18009e3041ea 207 return datum->bytes;
aspeteRakete 1:18009e3041ea 208 } else {
aspeteRakete 1:18009e3041ea 209 return 0;
aspeteRakete 1:18009e3041ea 210 }
aspeteRakete 1:18009e3041ea 211 }
aspeteRakete 1:18009e3041ea 212
aspeteRakete 1:18009e3041ea 213 /*=============================================================================
aspeteRakete 1:18009e3041ea 214 TESTING DATA
aspeteRakete 1:18009e3041ea 215 =============================================================================*/
aspeteRakete 1:18009e3041ea 216
aspeteRakete 1:18009e3041ea 217 bool OSCMessage::testType(int position, char type){
aspeteRakete 1:18009e3041ea 218 OSCData * datum = getOSCData(position);
aspeteRakete 1:18009e3041ea 219 if (!hasError()){
aspeteRakete 1:18009e3041ea 220 return datum->type == type;
aspeteRakete 1:18009e3041ea 221 } else {
aspeteRakete 1:18009e3041ea 222 return false;
aspeteRakete 1:18009e3041ea 223 }
aspeteRakete 1:18009e3041ea 224 }
aspeteRakete 1:18009e3041ea 225
aspeteRakete 1:18009e3041ea 226 bool OSCMessage::isInt(int position){
aspeteRakete 1:18009e3041ea 227 return testType(position, 'i');
aspeteRakete 1:18009e3041ea 228 }
aspeteRakete 1:18009e3041ea 229
aspeteRakete 1:18009e3041ea 230 bool OSCMessage::isTime(int position){
aspeteRakete 1:18009e3041ea 231 return testType(position, 't');
aspeteRakete 1:18009e3041ea 232 }
aspeteRakete 1:18009e3041ea 233
aspeteRakete 1:18009e3041ea 234 bool OSCMessage::isFloat(int position){
aspeteRakete 1:18009e3041ea 235 return testType(position, 'f');
aspeteRakete 1:18009e3041ea 236 }
aspeteRakete 1:18009e3041ea 237
aspeteRakete 1:18009e3041ea 238 bool OSCMessage::isBlob(int position){
aspeteRakete 1:18009e3041ea 239 return testType(position, 'b');
aspeteRakete 1:18009e3041ea 240 }
aspeteRakete 1:18009e3041ea 241
aspeteRakete 1:18009e3041ea 242 bool OSCMessage::isChar(int position){
aspeteRakete 1:18009e3041ea 243 return testType(position, 'c');
aspeteRakete 1:18009e3041ea 244 }
aspeteRakete 1:18009e3041ea 245
aspeteRakete 1:18009e3041ea 246 bool OSCMessage::isString(int position){
aspeteRakete 1:18009e3041ea 247 return testType(position, 's');
aspeteRakete 1:18009e3041ea 248 }
aspeteRakete 1:18009e3041ea 249
aspeteRakete 1:18009e3041ea 250 bool OSCMessage::isDouble(int position){
aspeteRakete 1:18009e3041ea 251 return testType(position, 'd');
aspeteRakete 1:18009e3041ea 252 }
aspeteRakete 1:18009e3041ea 253 bool OSCMessage::isBoolean(int position){
aspeteRakete 1:18009e3041ea 254 return testType(position, 'T') || testType(position, 'F');
aspeteRakete 1:18009e3041ea 255 }
aspeteRakete 1:18009e3041ea 256
aspeteRakete 1:18009e3041ea 257
aspeteRakete 1:18009e3041ea 258 /*=============================================================================
aspeteRakete 1:18009e3041ea 259 PATTERN MATCHING
aspeteRakete 1:18009e3041ea 260 =============================================================================*/
aspeteRakete 1:18009e3041ea 261
aspeteRakete 1:18009e3041ea 262 int OSCMessage::match(const char * pattern, int addr_offset){
aspeteRakete 1:18009e3041ea 263 int pattern_offset;
aspeteRakete 1:18009e3041ea 264 int address_offset;
aspeteRakete 1:18009e3041ea 265 int ret = osc_match(address + addr_offset, pattern, &pattern_offset, &address_offset);
aspeteRakete 1:18009e3041ea 266 char * next = (char *) (address + addr_offset + pattern_offset);
aspeteRakete 1:18009e3041ea 267 if (ret==3){
aspeteRakete 1:18009e3041ea 268 return pattern_offset;
aspeteRakete 1:18009e3041ea 269 } else if (pattern_offset > 0 && *next == '/'){
aspeteRakete 1:18009e3041ea 270 return pattern_offset;
aspeteRakete 1:18009e3041ea 271 } else {
aspeteRakete 1:18009e3041ea 272 return 0;
aspeteRakete 1:18009e3041ea 273 }
aspeteRakete 1:18009e3041ea 274 }
aspeteRakete 1:18009e3041ea 275
aspeteRakete 1:18009e3041ea 276 bool OSCMessage::fullMatch( const char * pattern, int addr_offset){
aspeteRakete 1:18009e3041ea 277 int pattern_offset;
aspeteRakete 1:18009e3041ea 278 int address_offset;
aspeteRakete 1:18009e3041ea 279 int ret = osc_match(address + addr_offset, pattern, &address_offset, &pattern_offset);
aspeteRakete 1:18009e3041ea 280 return (ret==3);
aspeteRakete 1:18009e3041ea 281 }
aspeteRakete 1:18009e3041ea 282
aspeteRakete 1:18009e3041ea 283 bool OSCMessage::dispatch(const char * pattern, void (*callback)(OSCMessage &), int addr_offset){
aspeteRakete 1:18009e3041ea 284 if (fullMatch(pattern, addr_offset)){
aspeteRakete 1:18009e3041ea 285 callback(*this);
aspeteRakete 1:18009e3041ea 286 return true;
aspeteRakete 1:18009e3041ea 287 } else {
aspeteRakete 1:18009e3041ea 288 return false;
aspeteRakete 1:18009e3041ea 289 }
aspeteRakete 1:18009e3041ea 290 }
aspeteRakete 1:18009e3041ea 291
aspeteRakete 1:18009e3041ea 292 bool OSCMessage::route(const char * pattern, void (*callback)(OSCMessage &, int), int initial_offset){
aspeteRakete 1:18009e3041ea 293 int match_offset = match(pattern, initial_offset);
aspeteRakete 1:18009e3041ea 294 if (match_offset>0){
aspeteRakete 1:18009e3041ea 295 callback(*this, match_offset + initial_offset);
aspeteRakete 1:18009e3041ea 296 return true;
aspeteRakete 1:18009e3041ea 297 } else {
aspeteRakete 1:18009e3041ea 298 return false;
aspeteRakete 1:18009e3041ea 299 }
aspeteRakete 1:18009e3041ea 300 }
aspeteRakete 1:18009e3041ea 301
aspeteRakete 1:18009e3041ea 302 /*=============================================================================
aspeteRakete 1:18009e3041ea 303 ADDRESS
aspeteRakete 1:18009e3041ea 304 =============================================================================*/
aspeteRakete 1:18009e3041ea 305
aspeteRakete 1:18009e3041ea 306 int OSCMessage::getAddress(char * buffer, int offset){
aspeteRakete 1:18009e3041ea 307 strcpy(buffer, address+offset);
aspeteRakete 1:18009e3041ea 308 return strlen(buffer);
aspeteRakete 1:18009e3041ea 309 }
aspeteRakete 1:18009e3041ea 310
aspeteRakete 1:18009e3041ea 311 int OSCMessage::getAddress(char * buffer, int offset, int len){
aspeteRakete 1:18009e3041ea 312 strncpy(buffer, address+offset, len);
aspeteRakete 1:18009e3041ea 313 return strlen(buffer);
aspeteRakete 1:18009e3041ea 314 }
aspeteRakete 1:18009e3041ea 315
aspeteRakete 1:18009e3041ea 316 void OSCMessage::setAddress(const char * _address){
aspeteRakete 1:18009e3041ea 317 //free the previous address
aspeteRakete 1:18009e3041ea 318 free(address); // are we sure address was allocated?
aspeteRakete 1:18009e3041ea 319 //copy the address
aspeteRakete 1:18009e3041ea 320 char * addressMemory = (char *) malloc( (strlen(_address) + 1) * sizeof(char) );
aspeteRakete 1:18009e3041ea 321 if (addressMemory == NULL){
aspeteRakete 1:18009e3041ea 322 error = ALLOCFAILED;
aspeteRakete 1:18009e3041ea 323 address = NULL;
aspeteRakete 1:18009e3041ea 324 } else {
aspeteRakete 1:18009e3041ea 325 strcpy(addressMemory, _address);
aspeteRakete 1:18009e3041ea 326 address = addressMemory;
aspeteRakete 1:18009e3041ea 327 }
aspeteRakete 1:18009e3041ea 328 }
aspeteRakete 1:18009e3041ea 329
aspeteRakete 1:18009e3041ea 330 /*=============================================================================
aspeteRakete 1:18009e3041ea 331 SIZE
aspeteRakete 1:18009e3041ea 332 =============================================================================*/
aspeteRakete 1:18009e3041ea 333
aspeteRakete 1:18009e3041ea 334 #ifdef SLOWpadcalculation
aspeteRakete 1:18009e3041ea 335 int OSCMessage::padSize(int _bytes){
aspeteRakete 1:18009e3041ea 336 int space = (_bytes + 3) / 4;
aspeteRakete 1:18009e3041ea 337 space *= 4;
aspeteRakete 1:18009e3041ea 338 return space - _bytes;
aspeteRakete 1:18009e3041ea 339 }
aspeteRakete 1:18009e3041ea 340 #else
aspeteRakete 1:18009e3041ea 341 static inline int padSize(int bytes) { return (4- (bytes&03))&3; }
aspeteRakete 1:18009e3041ea 342 #endif
aspeteRakete 1:18009e3041ea 343 //returns the number of OSCData in the OSCMessage
aspeteRakete 1:18009e3041ea 344 int OSCMessage::size(){
aspeteRakete 1:18009e3041ea 345 return dataCount;
aspeteRakete 1:18009e3041ea 346 }
aspeteRakete 1:18009e3041ea 347
aspeteRakete 1:18009e3041ea 348 int OSCMessage::bytes(){
aspeteRakete 1:18009e3041ea 349 int messageSize = 0;
aspeteRakete 1:18009e3041ea 350 //send the address
aspeteRakete 1:18009e3041ea 351 int addrLen = strlen(address) + 1;
aspeteRakete 1:18009e3041ea 352 messageSize += addrLen;
aspeteRakete 1:18009e3041ea 353 //padding amount
aspeteRakete 1:18009e3041ea 354 int addrPad = padSize(addrLen);
aspeteRakete 1:18009e3041ea 355 messageSize += addrPad;
aspeteRakete 1:18009e3041ea 356 //add the comma seperator
aspeteRakete 1:18009e3041ea 357 messageSize += 1;
aspeteRakete 1:18009e3041ea 358 //add the types
aspeteRakete 1:18009e3041ea 359 messageSize += dataCount;
aspeteRakete 1:18009e3041ea 360 //pad the types
aspeteRakete 1:18009e3041ea 361 int typePad = padSize(dataCount + 1); //for the comma
aspeteRakete 1:18009e3041ea 362 if (typePad == 0){
aspeteRakete 1:18009e3041ea 363 typePad = 4; // to make sure the type string is null terminated
aspeteRakete 1:18009e3041ea 364 }
casiotone401 4:107c23eb31b6 365 messageSize += typePad;
aspeteRakete 1:18009e3041ea 366 //then the data
aspeteRakete 1:18009e3041ea 367 for (int i = 0; i < dataCount; i++){
aspeteRakete 1:18009e3041ea 368 OSCData * datum = getOSCData(i);
casiotone401 4:107c23eb31b6 369 messageSize += datum->bytes;
aspeteRakete 1:18009e3041ea 370 messageSize += padSize(datum->bytes);
aspeteRakete 1:18009e3041ea 371 }
aspeteRakete 1:18009e3041ea 372 return messageSize;
aspeteRakete 1:18009e3041ea 373 }
aspeteRakete 1:18009e3041ea 374
aspeteRakete 1:18009e3041ea 375 /*=============================================================================
aspeteRakete 1:18009e3041ea 376 ERROR HANDLING
aspeteRakete 1:18009e3041ea 377 =============================================================================*/
aspeteRakete 1:18009e3041ea 378
aspeteRakete 1:18009e3041ea 379 bool OSCMessage::hasError(){
aspeteRakete 1:18009e3041ea 380 bool retError = error != OSC_OK;
aspeteRakete 1:18009e3041ea 381 //test each of the data
aspeteRakete 1:18009e3041ea 382 for (int i = 0; i < dataCount; i++){
aspeteRakete 1:18009e3041ea 383 OSCData * datum = getOSCData(i);
aspeteRakete 1:18009e3041ea 384 retError |= datum->error != OSC_OK;
aspeteRakete 1:18009e3041ea 385 }
aspeteRakete 1:18009e3041ea 386 return retError;
aspeteRakete 1:18009e3041ea 387 }
aspeteRakete 1:18009e3041ea 388
aspeteRakete 1:18009e3041ea 389 OSCErrorCode OSCMessage::getError(){
aspeteRakete 1:18009e3041ea 390 return error;
aspeteRakete 1:18009e3041ea 391 }
aspeteRakete 1:18009e3041ea 392
aspeteRakete 1:18009e3041ea 393 /*=============================================================================
aspeteRakete 1:18009e3041ea 394 SENDING
aspeteRakete 1:18009e3041ea 395 =============================================================================*/
aspeteRakete 1:18009e3041ea 396
aspeteRakete 2:61caa2495215 397
aspeteRakete 2:61caa2495215 398 /*void OSCMessage::send(Stream &p){
aspeteRakete 1:18009e3041ea 399 //don't send a message with errors
aspeteRakete 1:18009e3041ea 400 if (hasError()){
aspeteRakete 1:18009e3041ea 401 return;
aspeteRakete 1:18009e3041ea 402 }
aspeteRakete 1:18009e3041ea 403 uint8_t nullChar = '\0';
aspeteRakete 1:18009e3041ea 404 //send the address
aspeteRakete 1:18009e3041ea 405 int addrLen = strlen(address) + 1;
aspeteRakete 1:18009e3041ea 406 //padding amount
aspeteRakete 1:18009e3041ea 407 int addrPad = padSize(addrLen);
aspeteRakete 1:18009e3041ea 408 //write it to the stream
aspeteRakete 1:18009e3041ea 409 p.write((uint8_t *) address, addrLen);
aspeteRakete 1:18009e3041ea 410 //add the padding
aspeteRakete 1:18009e3041ea 411 while(addrPad--){
aspeteRakete 1:18009e3041ea 412 p.write(nullChar);
aspeteRakete 1:18009e3041ea 413 }
aspeteRakete 1:18009e3041ea 414 //add the comma seperator
aspeteRakete 1:18009e3041ea 415 p.write((uint8_t) ',');
aspeteRakete 1:18009e3041ea 416 //add the types
aspeteRakete 1:18009e3041ea 417 #ifdef PAULSSUGGESTION
aspeteRakete 1:18009e3041ea 418 // Paul suggested buffering on the stack
aspeteRakete 1:18009e3041ea 419 // to improve performance. The problem is this could exhaust the stack
aspeteRakete 1:18009e3041ea 420 // for long complex messages
aspeteRakete 1:18009e3041ea 421 {
aspeteRakete 1:18009e3041ea 422 uint8_t typstr[dataCount];
aspeteRakete 1:18009e3041ea 423
aspeteRakete 1:18009e3041ea 424 for (int i = 0; i < dataCount; i++){
aspeteRakete 1:18009e3041ea 425 typstr[i] = getType(i);
aspeteRakete 1:18009e3041ea 426 }
aspeteRakete 1:18009e3041ea 427 p.write(typstr,dataCount);
aspeteRakete 1:18009e3041ea 428 }
aspeteRakete 1:18009e3041ea 429 #else
aspeteRakete 1:18009e3041ea 430 for (int i = 0; i < dataCount; i++){
aspeteRakete 1:18009e3041ea 431 p.write((uint8_t) getType(i));
aspeteRakete 1:18009e3041ea 432 }
aspeteRakete 1:18009e3041ea 433 #endif
aspeteRakete 1:18009e3041ea 434 //pad the types
aspeteRakete 1:18009e3041ea 435 int typePad = padSize(dataCount + 1); // 1 is for the comma
aspeteRakete 1:18009e3041ea 436 if (typePad == 0){
aspeteRakete 1:18009e3041ea 437 typePad = 4; // This is because the type string has to be null terminated
aspeteRakete 1:18009e3041ea 438 }
aspeteRakete 1:18009e3041ea 439 while(typePad--){
aspeteRakete 1:18009e3041ea 440 p.write(nullChar);
aspeteRakete 1:18009e3041ea 441 }
aspeteRakete 1:18009e3041ea 442 //write the data
aspeteRakete 1:18009e3041ea 443 for (int i = 0; i < dataCount; i++){
aspeteRakete 1:18009e3041ea 444 OSCData * datum = getOSCData(i);
aspeteRakete 1:18009e3041ea 445 if ((datum->type == 's') || (datum->type == 'b')){
aspeteRakete 1:18009e3041ea 446 p.write(datum->data.b, datum->bytes);
aspeteRakete 1:18009e3041ea 447 int dataPad = padSize(datum->bytes);
aspeteRakete 1:18009e3041ea 448 while(dataPad--){
aspeteRakete 1:18009e3041ea 449 p.write(nullChar);
aspeteRakete 1:18009e3041ea 450 }
aspeteRakete 1:18009e3041ea 451 } else if(datum->type == 'b'){
aspeteRakete 1:18009e3041ea 452 p.write(datum->data.b, datum->bytes);
aspeteRakete 1:18009e3041ea 453 int dataPad = padSize(datum->bytes);
aspeteRakete 1:18009e3041ea 454 while(dataPad--){
aspeteRakete 1:18009e3041ea 455 p.write(nullChar);
aspeteRakete 1:18009e3041ea 456 }
aspeteRakete 1:18009e3041ea 457 } else if (datum->type == 'd'){
aspeteRakete 1:18009e3041ea 458 double d = BigEndian(datum->data.d);
aspeteRakete 1:18009e3041ea 459 uint8_t * ptr = (uint8_t *) &d;
aspeteRakete 1:18009e3041ea 460 p.write(ptr, 8);
aspeteRakete 1:18009e3041ea 461 } else if (datum->type == 't'){
aspeteRakete 1:18009e3041ea 462 uint64_t d = BigEndian(datum->data.l);
aspeteRakete 1:18009e3041ea 463 uint8_t * ptr = (uint8_t *) &d;
aspeteRakete 1:18009e3041ea 464 p.write(ptr, 8);
aspeteRakete 1:18009e3041ea 465
aspeteRakete 1:18009e3041ea 466 } else if (datum->type == 'T' || datum->type == 'F')
aspeteRakete 1:18009e3041ea 467 { }
aspeteRakete 1:18009e3041ea 468 else { // float or int
aspeteRakete 1:18009e3041ea 469 uint32_t i = BigEndian(datum->data.i);
aspeteRakete 1:18009e3041ea 470 uint8_t * ptr = (uint8_t *) &i;
aspeteRakete 1:18009e3041ea 471 p.write(ptr, datum->bytes);
aspeteRakete 1:18009e3041ea 472 }
aspeteRakete 1:18009e3041ea 473 }
aspeteRakete 1:18009e3041ea 474 }*/
aspeteRakete 1:18009e3041ea 475
casiotone401 4:107c23eb31b6 476
casiotone401 4:107c23eb31b6 477 int OSCMessage::send(uint8_t * messageBuffer){
casiotone401 4:107c23eb31b6 478 int i, j;
casiotone401 4:107c23eb31b6 479 //don't send a message with errors
casiotone401 4:107c23eb31b6 480 if (hasError()){
casiotone401 4:107c23eb31b6 481 return -1;
casiotone401 4:107c23eb31b6 482 }
casiotone401 4:107c23eb31b6 483 uint8_t nullChar = '\0';
casiotone401 4:107c23eb31b6 484 //send the address
casiotone401 4:107c23eb31b6 485 int addrLen = strlen(address) + 1;
casiotone401 4:107c23eb31b6 486 //padding amount
casiotone401 4:107c23eb31b6 487 int addrPad = padSize(addrLen);
casiotone401 4:107c23eb31b6 488 //write it to the stream
casiotone401 4:107c23eb31b6 489 //p.write((uint8_t *) address, addrLen);
casiotone401 4:107c23eb31b6 490 int addrIdx = 0;
casiotone401 4:107c23eb31b6 491 int idx = 0 + bundleOffset;
casiotone401 4:107c23eb31b6 492
casiotone401 4:107c23eb31b6 493 while(addrLen--) {
casiotone401 4:107c23eb31b6 494 messageBuffer[idx++] = address[addrIdx++];
casiotone401 4:107c23eb31b6 495 }
casiotone401 4:107c23eb31b6 496 //add the padding
casiotone401 4:107c23eb31b6 497 while(addrPad--){
casiotone401 4:107c23eb31b6 498 //p.write(nullChar);
casiotone401 4:107c23eb31b6 499 messageBuffer[idx++] = nullChar;
casiotone401 4:107c23eb31b6 500 }
casiotone401 4:107c23eb31b6 501 //add the comma seperator
casiotone401 4:107c23eb31b6 502 //p.write((uint8_t) ',');
casiotone401 4:107c23eb31b6 503 messageBuffer[idx++] = ',';
casiotone401 4:107c23eb31b6 504 //add the types
casiotone401 4:107c23eb31b6 505 #ifdef PAULSSUGGESTION
casiotone401 4:107c23eb31b6 506 // Paul suggested buffering on the stack
casiotone401 4:107c23eb31b6 507 // to improve performance. The problem is this could exhaust the stack
casiotone401 4:107c23eb31b6 508 // for long complex messages
casiotone401 4:107c23eb31b6 509 {
casiotone401 4:107c23eb31b6 510 //uint8_t typstr[dataCount];
casiotone401 4:107c23eb31b6 511
casiotone401 4:107c23eb31b6 512 for (i = 0; i < dataCount; i++){
casiotone401 4:107c23eb31b6 513 //typstr[i] = getType(i);
casiotone401 4:107c23eb31b6 514 messageBuffer[idx++] = getType(i);
casiotone401 4:107c23eb31b6 515 }
casiotone401 4:107c23eb31b6 516 //p.write(typstr,dataCount);
casiotone401 4:107c23eb31b6 517 }
casiotone401 4:107c23eb31b6 518 #else
casiotone401 4:107c23eb31b6 519 for (i = 0; i < dataCount; i++){
casiotone401 4:107c23eb31b6 520 //p.write((uint8_t) getType(i));
casiotone401 4:107c23eb31b6 521 messageBuffer[idx++] = getType(i);
casiotone401 4:107c23eb31b6 522 }
casiotone401 4:107c23eb31b6 523 #endif
casiotone401 4:107c23eb31b6 524 //pad the types
casiotone401 4:107c23eb31b6 525 int typePad = padSize(dataCount + 1); // 1 is for the comma
casiotone401 4:107c23eb31b6 526
casiotone401 4:107c23eb31b6 527 if (typePad == 0) {
casiotone401 4:107c23eb31b6 528 typePad = 4; // This is because the type string has to be null terminated
casiotone401 4:107c23eb31b6 529 }
casiotone401 4:107c23eb31b6 530
casiotone401 4:107c23eb31b6 531 while(typePad--){
casiotone401 4:107c23eb31b6 532 //p.write(nullChar);
casiotone401 4:107c23eb31b6 533 messageBuffer[idx++] = nullChar;
casiotone401 4:107c23eb31b6 534 }
casiotone401 4:107c23eb31b6 535 //write the data
casiotone401 4:107c23eb31b6 536 for (i = 0; i < dataCount; i++) {
casiotone401 4:107c23eb31b6 537
casiotone401 4:107c23eb31b6 538 OSCData * datum = getOSCData(i);
casiotone401 4:107c23eb31b6 539
casiotone401 4:107c23eb31b6 540 if ((datum->type == 's') || (datum->type == 'b')){
casiotone401 4:107c23eb31b6 541 //p.write(datum->data.b, datum->bytes);
casiotone401 4:107c23eb31b6 542 for (j = 0; j < datum->bytes; j++) {
casiotone401 4:107c23eb31b6 543 messageBuffer[idx++] = datum->data.b[j];
casiotone401 4:107c23eb31b6 544 }
casiotone401 4:107c23eb31b6 545
casiotone401 4:107c23eb31b6 546 int dataPad = padSize(datum->bytes);
casiotone401 4:107c23eb31b6 547 while(dataPad--){
casiotone401 4:107c23eb31b6 548 //p.write(nullChar);
casiotone401 4:107c23eb31b6 549 messageBuffer[idx++] = nullChar;
casiotone401 4:107c23eb31b6 550 }
casiotone401 4:107c23eb31b6 551 } else if (datum->type == 'd'){
casiotone401 4:107c23eb31b6 552 double d = BigEndian(datum->data.d);
casiotone401 4:107c23eb31b6 553 //uint8_t * ptr = (uint8_t *) &d;
casiotone401 4:107c23eb31b6 554 uint8_t * ptr = (uint8_t *) &d;
casiotone401 4:107c23eb31b6 555 //p.write(ptr, 8);
casiotone401 4:107c23eb31b6 556 for (j = 0; j < 8; j++) {
casiotone401 4:107c23eb31b6 557 messageBuffer[idx++] = ptr[j];
casiotone401 4:107c23eb31b6 558 }
casiotone401 4:107c23eb31b6 559 } else if (datum->type == 't'){
casiotone401 4:107c23eb31b6 560 uint64_t d = BigEndian(datum->data.l);
casiotone401 4:107c23eb31b6 561 //uint8_t * ptr = (uint8_t *) &d;
casiotone401 4:107c23eb31b6 562 uint8_t * ptr = (uint8_t *) &d;
casiotone401 4:107c23eb31b6 563 //p.write(ptr, 8);
casiotone401 4:107c23eb31b6 564 for (j = 0; j < 8; j++) {
casiotone401 4:107c23eb31b6 565 messageBuffer[idx++] = ptr[j];
casiotone401 4:107c23eb31b6 566 }
casiotone401 4:107c23eb31b6 567 } else if (datum->type == 'T' || datum->type == 'F') {
casiotone401 4:107c23eb31b6 568
casiotone401 4:107c23eb31b6 569 } else { // float or int
casiotone401 4:107c23eb31b6 570 //uint32_t i = BigEndian(datum->data.i);
casiotone401 4:107c23eb31b6 571 uint32_t ui = BigEndian(datum->data.i);
casiotone401 4:107c23eb31b6 572 //uint8_t * ptr = (uint8_t *) &i;
casiotone401 4:107c23eb31b6 573 uint8_t * ptr = (uint8_t *) &ui;
casiotone401 4:107c23eb31b6 574 //p.write(ptr, datum->bytes);
casiotone401 4:107c23eb31b6 575 for (j = 0; j < datum->bytes; j++) {
casiotone401 4:107c23eb31b6 576 messageBuffer[idx++] = ptr[j];
casiotone401 4:107c23eb31b6 577 }
casiotone401 4:107c23eb31b6 578 }
casiotone401 4:107c23eb31b6 579 }
casiotone401 4:107c23eb31b6 580
casiotone401 4:107c23eb31b6 581 bundleOffset = 0;
casiotone401 4:107c23eb31b6 582 return idx;
casiotone401 4:107c23eb31b6 583 }
casiotone401 4:107c23eb31b6 584
aspeteRakete 1:18009e3041ea 585 /*=============================================================================
aspeteRakete 1:18009e3041ea 586 FILLING
aspeteRakete 1:18009e3041ea 587 =============================================================================*/
aspeteRakete 1:18009e3041ea 588
aspeteRakete 1:18009e3041ea 589 void OSCMessage::fill(uint8_t incomingByte){
aspeteRakete 1:18009e3041ea 590 decode(incomingByte);
aspeteRakete 1:18009e3041ea 591 }
casiotone401 4:107c23eb31b6 592 /*
aspeteRakete 1:18009e3041ea 593 void OSCMessage::fill(uint8_t * incomingBytes, int length){
aspeteRakete 1:18009e3041ea 594 while (length--){
aspeteRakete 1:18009e3041ea 595 decode(*incomingBytes++);
aspeteRakete 1:18009e3041ea 596 }
aspeteRakete 1:18009e3041ea 597 }
casiotone401 4:107c23eb31b6 598 */
aspeteRakete 1:18009e3041ea 599 /*=============================================================================
aspeteRakete 1:18009e3041ea 600 DECODING
aspeteRakete 1:18009e3041ea 601 =============================================================================*/
aspeteRakete 1:18009e3041ea 602
aspeteRakete 1:18009e3041ea 603 void OSCMessage::decodeAddress(){
aspeteRakete 1:18009e3041ea 604 setAddress((char *) incomingBuffer);
aspeteRakete 1:18009e3041ea 605 //change the error from invalide message
aspeteRakete 1:18009e3041ea 606 error = OSC_OK;
aspeteRakete 1:18009e3041ea 607 clearIncomingBuffer();
aspeteRakete 1:18009e3041ea 608 }
aspeteRakete 1:18009e3041ea 609
aspeteRakete 1:18009e3041ea 610 void OSCMessage::decodeType(uint8_t incomingByte){
aspeteRakete 1:18009e3041ea 611 char type = incomingByte;
aspeteRakete 1:18009e3041ea 612 add(type);
aspeteRakete 1:18009e3041ea 613 }
aspeteRakete 1:18009e3041ea 614
aspeteRakete 1:18009e3041ea 615 void OSCMessage::decodeData(uint8_t incomingByte){
aspeteRakete 1:18009e3041ea 616 //get the first OSCData to re-set
aspeteRakete 1:18009e3041ea 617 for (int i = 0; i < dataCount; i++){
aspeteRakete 1:18009e3041ea 618 OSCData * datum = getOSCData(i);
aspeteRakete 1:18009e3041ea 619 if (datum->error == INVALID_OSC){
aspeteRakete 1:18009e3041ea 620 //set the contents of datum with the data received
aspeteRakete 1:18009e3041ea 621 switch (datum->type){
aspeteRakete 1:18009e3041ea 622 case 'i':
aspeteRakete 1:18009e3041ea 623 if (incomingBufferSize == 4){
aspeteRakete 1:18009e3041ea 624 //parse the buffer as an int
aspeteRakete 1:18009e3041ea 625 union {
aspeteRakete 1:18009e3041ea 626 int32_t i;
aspeteRakete 1:18009e3041ea 627 uint8_t b[4];
aspeteRakete 1:18009e3041ea 628 } u;
aspeteRakete 1:18009e3041ea 629 memcpy(u.b, incomingBuffer, 4);
aspeteRakete 1:18009e3041ea 630 int32_t dataVal = BigEndian(u.i);
aspeteRakete 1:18009e3041ea 631 set(i, dataVal);
aspeteRakete 1:18009e3041ea 632 clearIncomingBuffer();
aspeteRakete 1:18009e3041ea 633 }
aspeteRakete 1:18009e3041ea 634 break;
aspeteRakete 1:18009e3041ea 635 case 'f':
aspeteRakete 1:18009e3041ea 636 if (incomingBufferSize == 4){
aspeteRakete 1:18009e3041ea 637 //parse the buffer as an int
aspeteRakete 1:18009e3041ea 638 union {
aspeteRakete 1:18009e3041ea 639 float f;
aspeteRakete 1:18009e3041ea 640 uint8_t b[4];
aspeteRakete 1:18009e3041ea 641 } u;
aspeteRakete 1:18009e3041ea 642 memcpy(u.b, incomingBuffer, 4);
aspeteRakete 1:18009e3041ea 643 float dataVal = BigEndian(u.f);
aspeteRakete 1:18009e3041ea 644 set(i, dataVal);
aspeteRakete 1:18009e3041ea 645 clearIncomingBuffer();
aspeteRakete 1:18009e3041ea 646 }
aspeteRakete 1:18009e3041ea 647 break;
aspeteRakete 1:18009e3041ea 648 case 'd':
aspeteRakete 1:18009e3041ea 649 if (incomingBufferSize == 8){
aspeteRakete 1:18009e3041ea 650 //parse the buffer as an int
aspeteRakete 1:18009e3041ea 651 union {
aspeteRakete 1:18009e3041ea 652 double d;
aspeteRakete 1:18009e3041ea 653 uint8_t b[8];
aspeteRakete 1:18009e3041ea 654 } u;
aspeteRakete 1:18009e3041ea 655 memcpy(u.b, incomingBuffer, 8);
aspeteRakete 1:18009e3041ea 656 double dataVal = BigEndian(u.d);
aspeteRakete 1:18009e3041ea 657 set(i, dataVal);
aspeteRakete 1:18009e3041ea 658 clearIncomingBuffer();
aspeteRakete 1:18009e3041ea 659 }
aspeteRakete 1:18009e3041ea 660 break;
aspeteRakete 1:18009e3041ea 661 case 't':
aspeteRakete 1:18009e3041ea 662 if (incomingBufferSize == 8){
aspeteRakete 1:18009e3041ea 663 //parse the buffer as an int
aspeteRakete 1:18009e3041ea 664 union {
aspeteRakete 1:18009e3041ea 665 uint64_t d;
aspeteRakete 1:18009e3041ea 666 uint8_t b[8];
aspeteRakete 1:18009e3041ea 667 } u;
aspeteRakete 1:18009e3041ea 668 memcpy(u.b, incomingBuffer, 8);
aspeteRakete 1:18009e3041ea 669 uint64_t dataVal = BigEndian(u.d);
aspeteRakete 1:18009e3041ea 670 set(i, dataVal);
aspeteRakete 1:18009e3041ea 671 clearIncomingBuffer();
aspeteRakete 1:18009e3041ea 672 }
aspeteRakete 1:18009e3041ea 673 break;
aspeteRakete 1:18009e3041ea 674
aspeteRakete 1:18009e3041ea 675 case 's':
aspeteRakete 1:18009e3041ea 676 if (incomingByte == 0){
aspeteRakete 1:18009e3041ea 677 char * str = (char *) incomingBuffer;
aspeteRakete 1:18009e3041ea 678 set(i, str);
aspeteRakete 1:18009e3041ea 679 clearIncomingBuffer();
aspeteRakete 1:18009e3041ea 680 decodeState = DATA_PADDING;
aspeteRakete 1:18009e3041ea 681 }
aspeteRakete 1:18009e3041ea 682 break;
aspeteRakete 1:18009e3041ea 683 case 'b':
aspeteRakete 1:18009e3041ea 684 if (incomingBufferSize > 4){
aspeteRakete 1:18009e3041ea 685 //compute the expected blob size
aspeteRakete 1:18009e3041ea 686 union {
aspeteRakete 1:18009e3041ea 687 uint32_t i;
aspeteRakete 1:18009e3041ea 688 uint8_t b[4];
aspeteRakete 1:18009e3041ea 689 } u;
aspeteRakete 1:18009e3041ea 690 memcpy(u.b, incomingBuffer, 4);
aspeteRakete 1:18009e3041ea 691 uint32_t blobLength = BigEndian(u.i);
aspeteRakete 1:18009e3041ea 692 if (incomingBufferSize == blobLength + 4){
aspeteRakete 1:18009e3041ea 693 set(i, incomingBuffer + 4, blobLength);
aspeteRakete 1:18009e3041ea 694 clearIncomingBuffer();
aspeteRakete 1:18009e3041ea 695 decodeState = DATA_PADDING;
aspeteRakete 1:18009e3041ea 696 }
aspeteRakete 1:18009e3041ea 697
aspeteRakete 1:18009e3041ea 698 }
aspeteRakete 1:18009e3041ea 699 break;
aspeteRakete 1:18009e3041ea 700 }
aspeteRakete 1:18009e3041ea 701 //break out of the for loop once we've selected the first invalid message
aspeteRakete 1:18009e3041ea 702 break;
aspeteRakete 1:18009e3041ea 703 }
aspeteRakete 1:18009e3041ea 704 }
casiotone401 4:107c23eb31b6 705
aspeteRakete 1:18009e3041ea 706 }
aspeteRakete 1:18009e3041ea 707
aspeteRakete 1:18009e3041ea 708 //does not validate the incoming OSC for correctness
aspeteRakete 1:18009e3041ea 709 void OSCMessage::decode(uint8_t incomingByte){
aspeteRakete 1:18009e3041ea 710 addToIncomingBuffer(incomingByte);
aspeteRakete 1:18009e3041ea 711 switch (decodeState){
aspeteRakete 1:18009e3041ea 712 case STANDBY:
aspeteRakete 1:18009e3041ea 713 if (incomingByte == '/'){
aspeteRakete 1:18009e3041ea 714 decodeState = ADDRESS;
aspeteRakete 1:18009e3041ea 715 }
aspeteRakete 1:18009e3041ea 716 break;
aspeteRakete 1:18009e3041ea 717 case ADDRESS:
aspeteRakete 1:18009e3041ea 718 if (incomingByte == 0){
aspeteRakete 1:18009e3041ea 719 //end of the address
aspeteRakete 1:18009e3041ea 720 //decode the address
aspeteRakete 1:18009e3041ea 721 decodeAddress();
aspeteRakete 1:18009e3041ea 722 //next state
aspeteRakete 1:18009e3041ea 723 decodeState = ADDRESS_PADDING;
aspeteRakete 1:18009e3041ea 724 }
aspeteRakete 1:18009e3041ea 725 break;
aspeteRakete 1:18009e3041ea 726 case ADDRESS_PADDING:
aspeteRakete 1:18009e3041ea 727 //it does not count the padding
aspeteRakete 1:18009e3041ea 728 if (incomingByte==','){
aspeteRakete 1:18009e3041ea 729 //next state
aspeteRakete 1:18009e3041ea 730 decodeState = TYPES;
aspeteRakete 1:18009e3041ea 731 clearIncomingBuffer();
aspeteRakete 1:18009e3041ea 732 }
aspeteRakete 1:18009e3041ea 733 break;
aspeteRakete 1:18009e3041ea 734 case TYPES:
aspeteRakete 1:18009e3041ea 735 if (incomingByte != 0){
aspeteRakete 1:18009e3041ea 736 //next state
aspeteRakete 1:18009e3041ea 737 decodeType(incomingByte);
aspeteRakete 1:18009e3041ea 738 } else {
aspeteRakete 1:18009e3041ea 739 decodeState = TYPES_PADDING;
aspeteRakete 1:18009e3041ea 740 }
aspeteRakete 1:18009e3041ea 741 //FALL THROUGH to test if it should go to the data state
aspeteRakete 1:18009e3041ea 742 case TYPES_PADDING: {
aspeteRakete 1:18009e3041ea 743 //compute the padding size for the types
aspeteRakete 1:18009e3041ea 744 //to determine the start of the data section
aspeteRakete 1:18009e3041ea 745 int typePad = padSize(dataCount + 1); // 1 is the comma
aspeteRakete 1:18009e3041ea 746 if (typePad == 0){
aspeteRakete 1:18009e3041ea 747 typePad = 4; // to make sure it will be null terminated
aspeteRakete 1:18009e3041ea 748 }
aspeteRakete 1:18009e3041ea 749 if (incomingBufferSize == (typePad + dataCount)){
aspeteRakete 1:18009e3041ea 750 clearIncomingBuffer();
aspeteRakete 1:18009e3041ea 751 decodeState = DATA;
aspeteRakete 1:18009e3041ea 752 }
aspeteRakete 1:18009e3041ea 753 }
aspeteRakete 1:18009e3041ea 754 break;
aspeteRakete 1:18009e3041ea 755 case DATA:
aspeteRakete 1:18009e3041ea 756 decodeData(incomingByte);
aspeteRakete 1:18009e3041ea 757 break;
aspeteRakete 1:18009e3041ea 758 case DATA_PADDING:{
aspeteRakete 1:18009e3041ea 759 //get hte last valid data
aspeteRakete 1:18009e3041ea 760 for (int i = dataCount - 1; i >= 0; i--){
aspeteRakete 1:18009e3041ea 761 OSCData * datum = getOSCData(i);
aspeteRakete 1:18009e3041ea 762 if (datum->error == OSC_OK){
aspeteRakete 1:18009e3041ea 763 //compute the padding size for the data
aspeteRakete 1:18009e3041ea 764 int dataPad = padSize(datum->bytes);
aspeteRakete 1:18009e3041ea 765 if (incomingBufferSize == dataPad){
aspeteRakete 1:18009e3041ea 766 clearIncomingBuffer();
aspeteRakete 1:18009e3041ea 767 decodeState = DATA;
aspeteRakete 1:18009e3041ea 768 }
aspeteRakete 1:18009e3041ea 769 break;
aspeteRakete 1:18009e3041ea 770 }
aspeteRakete 1:18009e3041ea 771 }
aspeteRakete 1:18009e3041ea 772 }
aspeteRakete 1:18009e3041ea 773 break;
aspeteRakete 1:18009e3041ea 774
aspeteRakete 1:18009e3041ea 775 }
aspeteRakete 1:18009e3041ea 776 }
aspeteRakete 1:18009e3041ea 777
aspeteRakete 1:18009e3041ea 778
aspeteRakete 1:18009e3041ea 779 /*=============================================================================
aspeteRakete 1:18009e3041ea 780 INCOMING BUFFER MANAGEMENT
aspeteRakete 1:18009e3041ea 781 =============================================================================*/
aspeteRakete 1:18009e3041ea 782 #define OSCPREALLOCATEIZE 16
aspeteRakete 1:18009e3041ea 783 void OSCMessage::addToIncomingBuffer(uint8_t incomingByte){
aspeteRakete 1:18009e3041ea 784 //realloc some space for the new byte and stick it on the end
aspeteRakete 1:18009e3041ea 785 if(incomingBufferFree>0)
aspeteRakete 1:18009e3041ea 786 {
aspeteRakete 1:18009e3041ea 787 incomingBuffer[incomingBufferSize++] = incomingByte;
aspeteRakete 1:18009e3041ea 788 incomingBufferFree--;
aspeteRakete 1:18009e3041ea 789 }
aspeteRakete 1:18009e3041ea 790 else
aspeteRakete 1:18009e3041ea 791 {
aspeteRakete 1:18009e3041ea 792
aspeteRakete 1:18009e3041ea 793 incomingBuffer = (uint8_t *) realloc ( incomingBuffer, incomingBufferSize + 1 + OSCPREALLOCATEIZE);
aspeteRakete 1:18009e3041ea 794 if (incomingBuffer != NULL){
aspeteRakete 1:18009e3041ea 795 incomingBuffer[incomingBufferSize++] = incomingByte;
aspeteRakete 1:18009e3041ea 796 incomingBufferFree = OSCPREALLOCATEIZE;
aspeteRakete 1:18009e3041ea 797 } else {
aspeteRakete 1:18009e3041ea 798 error = ALLOCFAILED;
aspeteRakete 1:18009e3041ea 799 }
aspeteRakete 1:18009e3041ea 800 }
aspeteRakete 1:18009e3041ea 801 }
aspeteRakete 1:18009e3041ea 802
aspeteRakete 1:18009e3041ea 803 void OSCMessage::clearIncomingBuffer(){
aspeteRakete 1:18009e3041ea 804 incomingBuffer = (uint8_t *) realloc ( incomingBuffer, OSCPREALLOCATEIZE);
aspeteRakete 1:18009e3041ea 805 if (incomingBuffer != NULL){
aspeteRakete 1:18009e3041ea 806 incomingBufferFree = OSCPREALLOCATEIZE;
aspeteRakete 1:18009e3041ea 807 } else {
aspeteRakete 1:18009e3041ea 808 error = ALLOCFAILED;
aspeteRakete 1:18009e3041ea 809 incomingBuffer = NULL;
aspeteRakete 1:18009e3041ea 810
aspeteRakete 1:18009e3041ea 811 }
aspeteRakete 1:18009e3041ea 812 incomingBufferSize = 0;
casiotone401 4:107c23eb31b6 813 }