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.
OSCBundle.cpp@14:2148b54dfdbf, 2018-12-10 (annotated)
- Committer:
- ibiltari
- Date:
- Mon Dec 10 16:51:59 2018 +0100
- Revision:
- 14:2148b54dfdbf
- Child:
- 16:36d28d8e5491
timing
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| ibiltari |
14:2148b54dfdbf | 1 | /* |
| ibiltari |
14:2148b54dfdbf | 2 | Written by Yotam Mann, The Center for New Music and Audio Technologies, |
| ibiltari |
14:2148b54dfdbf | 3 | University of California, Berkeley. Copyright (c) 2012, The Regents of |
| ibiltari |
14:2148b54dfdbf | 4 | the University of California (Regents). |
| ibiltari |
14:2148b54dfdbf | 5 | |
| ibiltari |
14:2148b54dfdbf | 6 | Permission to use, copy, modify, distribute, and distribute modified versions |
| ibiltari |
14:2148b54dfdbf | 7 | of this software and its documentation without fee and without a signed |
| ibiltari |
14:2148b54dfdbf | 8 | licensing agreement, is hereby granted, provided that the above copyright |
| ibiltari |
14:2148b54dfdbf | 9 | notice, this paragraph and the following two paragraphs appear in all copies, |
| ibiltari |
14:2148b54dfdbf | 10 | modifications, and distributions. |
| ibiltari |
14:2148b54dfdbf | 11 | |
| ibiltari |
14:2148b54dfdbf | 12 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, |
| ibiltari |
14:2148b54dfdbf | 13 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING |
| ibiltari |
14:2148b54dfdbf | 14 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS |
| ibiltari |
14:2148b54dfdbf | 15 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| ibiltari |
14:2148b54dfdbf | 16 | |
| ibiltari |
14:2148b54dfdbf | 17 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| ibiltari |
14:2148b54dfdbf | 18 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| ibiltari |
14:2148b54dfdbf | 19 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED |
| ibiltari |
14:2148b54dfdbf | 20 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE |
| ibiltari |
14:2148b54dfdbf | 21 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
| ibiltari |
14:2148b54dfdbf | 22 | |
| ibiltari |
14:2148b54dfdbf | 23 | For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu |
| ibiltari |
14:2148b54dfdbf | 24 | */ |
| ibiltari |
14:2148b54dfdbf | 25 | |
| ibiltari |
14:2148b54dfdbf | 26 | #include "OSCBundle.h" |
| ibiltari |
14:2148b54dfdbf | 27 | |
| ibiltari |
14:2148b54dfdbf | 28 | #include <stdlib.h> |
| ibiltari |
14:2148b54dfdbf | 29 | #include <string.h> |
| ibiltari |
14:2148b54dfdbf | 30 | |
| ibiltari |
14:2148b54dfdbf | 31 | /*============================================================================= |
| ibiltari |
14:2148b54dfdbf | 32 | CONSTRUCTORS / DESTRUCTOR |
| ibiltari |
14:2148b54dfdbf | 33 | =============================================================================*/ |
| ibiltari |
14:2148b54dfdbf | 34 | |
| ibiltari |
14:2148b54dfdbf | 35 | OSCBundle::OSCBundle(osctime_t _timetag){ |
| ibiltari |
14:2148b54dfdbf | 36 | setTimetag(_timetag); |
| ibiltari |
14:2148b54dfdbf | 37 | numMessages = 0; |
| ibiltari |
14:2148b54dfdbf | 38 | error = OSC_OK; |
| ibiltari |
14:2148b54dfdbf | 39 | messages = NULL; |
| ibiltari |
14:2148b54dfdbf | 40 | incomingBuffer = NULL; |
| ibiltari |
14:2148b54dfdbf | 41 | incomingBufferSize = 0; |
| ibiltari |
14:2148b54dfdbf | 42 | decodeState = STANDBY; |
| ibiltari |
14:2148b54dfdbf | 43 | } |
| ibiltari |
14:2148b54dfdbf | 44 | |
| ibiltari |
14:2148b54dfdbf | 45 | OSCBundle::~OSCBundle(){ |
| ibiltari |
14:2148b54dfdbf | 46 | for (int i = 0; i < numMessages; i++){ |
| ibiltari |
14:2148b54dfdbf | 47 | OSCMessage * msg = getOSCMessage(i); |
| ibiltari |
14:2148b54dfdbf | 48 | delete msg; |
| ibiltari |
14:2148b54dfdbf | 49 | } |
| ibiltari |
14:2148b54dfdbf | 50 | free(messages); |
| ibiltari |
14:2148b54dfdbf | 51 | free(incomingBuffer); |
| ibiltari |
14:2148b54dfdbf | 52 | } |
| ibiltari |
14:2148b54dfdbf | 53 | |
| ibiltari |
14:2148b54dfdbf | 54 | //clears all of the OSCMessages inside |
| ibiltari |
14:2148b54dfdbf | 55 | OSCBundle& OSCBundle::empty(){ |
| ibiltari |
14:2148b54dfdbf | 56 | error = OSC_OK; |
| ibiltari |
14:2148b54dfdbf | 57 | for (int i = 0; i < numMessages; i++){ |
| ibiltari |
14:2148b54dfdbf | 58 | OSCMessage * msg = getOSCMessage(i); |
| ibiltari |
14:2148b54dfdbf | 59 | delete msg; |
| ibiltari |
14:2148b54dfdbf | 60 | } |
| ibiltari |
14:2148b54dfdbf | 61 | free(messages); |
| ibiltari |
14:2148b54dfdbf | 62 | messages = NULL; |
| ibiltari |
14:2148b54dfdbf | 63 | clearIncomingBuffer(); |
| ibiltari |
14:2148b54dfdbf | 64 | numMessages = 0; |
| ibiltari |
14:2148b54dfdbf | 65 | return *this; |
| ibiltari |
14:2148b54dfdbf | 66 | } |
| ibiltari |
14:2148b54dfdbf | 67 | |
| ibiltari |
14:2148b54dfdbf | 68 | /*============================================================================= |
| ibiltari |
14:2148b54dfdbf | 69 | SETTERS |
| ibiltari |
14:2148b54dfdbf | 70 | =============================================================================*/ |
| ibiltari |
14:2148b54dfdbf | 71 | |
| ibiltari |
14:2148b54dfdbf | 72 | OSCMessage & OSCBundle::add(const char * _address){ |
| ibiltari |
14:2148b54dfdbf | 73 | OSCMessage * msg = new OSCMessage(_address); |
| ibiltari |
14:2148b54dfdbf | 74 | if (!msg->hasError()){ |
| ibiltari |
14:2148b54dfdbf | 75 | //realloc the array to fit the message |
| ibiltari |
14:2148b54dfdbf | 76 | OSCMessage ** messageMem = (OSCMessage **) realloc(messages, sizeof(OSCMessage *) * (numMessages + 1)); |
| ibiltari |
14:2148b54dfdbf | 77 | if (messageMem != NULL){ |
| ibiltari |
14:2148b54dfdbf | 78 | messages = messageMem; |
| ibiltari |
14:2148b54dfdbf | 79 | messages[numMessages] = msg; |
| ibiltari |
14:2148b54dfdbf | 80 | numMessages++; |
| ibiltari |
14:2148b54dfdbf | 81 | } else { |
| ibiltari |
14:2148b54dfdbf | 82 | error = ALLOCFAILED; |
| ibiltari |
14:2148b54dfdbf | 83 | } |
| ibiltari |
14:2148b54dfdbf | 84 | } |
| ibiltari |
14:2148b54dfdbf | 85 | return *msg; |
| ibiltari |
14:2148b54dfdbf | 86 | } |
| ibiltari |
14:2148b54dfdbf | 87 | |
| ibiltari |
14:2148b54dfdbf | 88 | OSCMessage & OSCBundle::add(){ |
| ibiltari |
14:2148b54dfdbf | 89 | OSCMessage * msg = new OSCMessage(); |
| ibiltari |
14:2148b54dfdbf | 90 | //realloc the array to fit the message |
| ibiltari |
14:2148b54dfdbf | 91 | OSCMessage ** messageMem = (OSCMessage **) realloc(messages, sizeof(OSCMessage *) * (numMessages + 1)); |
| ibiltari |
14:2148b54dfdbf | 92 | if (messageMem != NULL){ |
| ibiltari |
14:2148b54dfdbf | 93 | messages = messageMem; |
| ibiltari |
14:2148b54dfdbf | 94 | messages[numMessages] = msg; |
| ibiltari |
14:2148b54dfdbf | 95 | numMessages++; |
| ibiltari |
14:2148b54dfdbf | 96 | } else { |
| ibiltari |
14:2148b54dfdbf | 97 | error = ALLOCFAILED; |
| ibiltari |
14:2148b54dfdbf | 98 | } |
| ibiltari |
14:2148b54dfdbf | 99 | return *msg; |
| ibiltari |
14:2148b54dfdbf | 100 | } |
| ibiltari |
14:2148b54dfdbf | 101 | |
| ibiltari |
14:2148b54dfdbf | 102 | OSCMessage & OSCBundle::add(OSCMessage & _msg){ |
| ibiltari |
14:2148b54dfdbf | 103 | OSCMessage * msg = new OSCMessage(&_msg); |
| ibiltari |
14:2148b54dfdbf | 104 | if (!msg->hasError()){ |
| ibiltari |
14:2148b54dfdbf | 105 | //realloc the array to fit the message |
| ibiltari |
14:2148b54dfdbf | 106 | OSCMessage ** messageMem = (OSCMessage **) realloc(messages, sizeof(OSCMessage *) * (numMessages + 1)); |
| ibiltari |
14:2148b54dfdbf | 107 | if (messageMem != NULL){ |
| ibiltari |
14:2148b54dfdbf | 108 | messages = messageMem; |
| ibiltari |
14:2148b54dfdbf | 109 | messages[numMessages] = msg; |
| ibiltari |
14:2148b54dfdbf | 110 | numMessages++; |
| ibiltari |
14:2148b54dfdbf | 111 | } else { |
| ibiltari |
14:2148b54dfdbf | 112 | error = ALLOCFAILED; |
| ibiltari |
14:2148b54dfdbf | 113 | } |
| ibiltari |
14:2148b54dfdbf | 114 | } |
| ibiltari |
14:2148b54dfdbf | 115 | return *msg; |
| ibiltari |
14:2148b54dfdbf | 116 | } |
| ibiltari |
14:2148b54dfdbf | 117 | |
| ibiltari |
14:2148b54dfdbf | 118 | /*============================================================================= |
| ibiltari |
14:2148b54dfdbf | 119 | GETTERS |
| ibiltari |
14:2148b54dfdbf | 120 | =============================================================================*/ |
| ibiltari |
14:2148b54dfdbf | 121 | |
| ibiltari |
14:2148b54dfdbf | 122 | //returns the first fullMatch. |
| ibiltari |
14:2148b54dfdbf | 123 | OSCMessage * OSCBundle::getOSCMessage( char * addr){ |
| ibiltari |
14:2148b54dfdbf | 124 | for (int i = 0; i < numMessages; i++){ |
| ibiltari |
14:2148b54dfdbf | 125 | OSCMessage * msg = getOSCMessage(i); |
| ibiltari |
14:2148b54dfdbf | 126 | if (msg->fullMatch(addr)){ |
| ibiltari |
14:2148b54dfdbf | 127 | return msg; |
| ibiltari |
14:2148b54dfdbf | 128 | } |
| ibiltari |
14:2148b54dfdbf | 129 | } |
| ibiltari |
14:2148b54dfdbf | 130 | return NULL; |
| ibiltari |
14:2148b54dfdbf | 131 | } |
| ibiltari |
14:2148b54dfdbf | 132 | |
| ibiltari |
14:2148b54dfdbf | 133 | //the position is the same as the order they were declared in |
| ibiltari |
14:2148b54dfdbf | 134 | OSCMessage * OSCBundle::getOSCMessage(int pos){ |
| ibiltari |
14:2148b54dfdbf | 135 | if (pos < numMessages){ |
| ibiltari |
14:2148b54dfdbf | 136 | return messages[pos]; |
| ibiltari |
14:2148b54dfdbf | 137 | } |
| ibiltari |
14:2148b54dfdbf | 138 | return NULL; |
| ibiltari |
14:2148b54dfdbf | 139 | } |
| ibiltari |
14:2148b54dfdbf | 140 | |
| ibiltari |
14:2148b54dfdbf | 141 | /*============================================================================= |
| ibiltari |
14:2148b54dfdbf | 142 | PATTERN MATCHING |
| ibiltari |
14:2148b54dfdbf | 143 | =============================================================================*/ |
| ibiltari |
14:2148b54dfdbf | 144 | |
| ibiltari |
14:2148b54dfdbf | 145 | |
| ibiltari |
14:2148b54dfdbf | 146 | bool OSCBundle::dispatch(const char * pattern, void (*callback)(OSCMessage&), int initial_offset){ |
| ibiltari |
14:2148b54dfdbf | 147 | bool called = false; |
| ibiltari |
14:2148b54dfdbf | 148 | for (int i = 0; i < numMessages; i++){ |
| ibiltari |
14:2148b54dfdbf | 149 | OSCMessage msg = getOSCMessage(i); |
| ibiltari |
14:2148b54dfdbf | 150 | called = msg.dispatch(pattern, callback, initial_offset) || called ; |
| ibiltari |
14:2148b54dfdbf | 151 | } |
| ibiltari |
14:2148b54dfdbf | 152 | return called; |
| ibiltari |
14:2148b54dfdbf | 153 | } |
| ibiltari |
14:2148b54dfdbf | 154 | |
| ibiltari |
14:2148b54dfdbf | 155 | |
| ibiltari |
14:2148b54dfdbf | 156 | bool OSCBundle::route(const char * pattern, void (*callback)(OSCMessage&, int), int initial_offset){ |
| ibiltari |
14:2148b54dfdbf | 157 | bool called = false; |
| ibiltari |
14:2148b54dfdbf | 158 | for (int i = 0; i < numMessages; i++){ |
| ibiltari |
14:2148b54dfdbf | 159 | OSCMessage msg = getOSCMessage(i); |
| ibiltari |
14:2148b54dfdbf | 160 | called = msg.route(pattern, callback, initial_offset) || called; |
| ibiltari |
14:2148b54dfdbf | 161 | } |
| ibiltari |
14:2148b54dfdbf | 162 | return called; |
| ibiltari |
14:2148b54dfdbf | 163 | } |
| ibiltari |
14:2148b54dfdbf | 164 | |
| ibiltari |
14:2148b54dfdbf | 165 | /*============================================================================= |
| ibiltari |
14:2148b54dfdbf | 166 | SIZE |
| ibiltari |
14:2148b54dfdbf | 167 | =============================================================================*/ |
| ibiltari |
14:2148b54dfdbf | 168 | |
| ibiltari |
14:2148b54dfdbf | 169 | |
| ibiltari |
14:2148b54dfdbf | 170 | int OSCBundle::size(){ |
| ibiltari |
14:2148b54dfdbf | 171 | return numMessages; |
| ibiltari |
14:2148b54dfdbf | 172 | } |
| ibiltari |
14:2148b54dfdbf | 173 | |
| ibiltari |
14:2148b54dfdbf | 174 | /*============================================================================= |
| ibiltari |
14:2148b54dfdbf | 175 | ERROR HANDLING |
| ibiltari |
14:2148b54dfdbf | 176 | =============================================================================*/ |
| ibiltari |
14:2148b54dfdbf | 177 | |
| ibiltari |
14:2148b54dfdbf | 178 | bool OSCBundle::hasError(){ |
| ibiltari |
14:2148b54dfdbf | 179 | bool retError = error != OSC_OK; |
| ibiltari |
14:2148b54dfdbf | 180 | //test each of the data |
| ibiltari |
14:2148b54dfdbf | 181 | for (int i = 0; i < numMessages; i++){ |
| ibiltari |
14:2148b54dfdbf | 182 | OSCMessage * msg = getOSCMessage(i); |
| ibiltari |
14:2148b54dfdbf | 183 | retError |= msg->hasError(); |
| ibiltari |
14:2148b54dfdbf | 184 | } |
| ibiltari |
14:2148b54dfdbf | 185 | return retError; |
| ibiltari |
14:2148b54dfdbf | 186 | } |
| ibiltari |
14:2148b54dfdbf | 187 | |
| ibiltari |
14:2148b54dfdbf | 188 | OSCErrorCode OSCBundle::getError(){ |
| ibiltari |
14:2148b54dfdbf | 189 | return error; |
| ibiltari |
14:2148b54dfdbf | 190 | } |
| ibiltari |
14:2148b54dfdbf | 191 | |
| ibiltari |
14:2148b54dfdbf | 192 | |
| ibiltari |
14:2148b54dfdbf | 193 | /*============================================================================= |
| ibiltari |
14:2148b54dfdbf | 194 | SENDING |
| ibiltari |
14:2148b54dfdbf | 195 | =============================================================================*/ |
| ibiltari |
14:2148b54dfdbf | 196 | |
| ibiltari |
14:2148b54dfdbf | 197 | OSCBundle& OSCBundle::send(UDPSocket &p, const char *host, uint16_t port){ |
| ibiltari |
14:2148b54dfdbf | 198 | |
| ibiltari |
14:2148b54dfdbf | 199 | char buff[128]; |
| ibiltari |
14:2148b54dfdbf | 200 | uint8_t lengthEnd; |
| ibiltari |
14:2148b54dfdbf | 201 | uint8_t lengthStart; |
| ibiltari |
14:2148b54dfdbf | 202 | uint8_t nullChar = '\0'; |
| ibiltari |
14:2148b54dfdbf | 203 | buff[0]=nullChar; |
| ibiltari |
14:2148b54dfdbf | 204 | |
| ibiltari |
14:2148b54dfdbf | 205 | //don't send a bundle with errors |
| ibiltari |
14:2148b54dfdbf | 206 | if (hasError()){ |
| ibiltari |
14:2148b54dfdbf | 207 | return *this; |
| ibiltari |
14:2148b54dfdbf | 208 | } |
| ibiltari |
14:2148b54dfdbf | 209 | //write the bundle header |
| ibiltari |
14:2148b54dfdbf | 210 | static const uint8_t header[] = {'#', 'b', 'u', 'n', 'd', 'l', 'e', 0}; |
| ibiltari |
14:2148b54dfdbf | 211 | strcat(buff, (char *)header); |
| ibiltari |
14:2148b54dfdbf | 212 | // p.write(header, 8); |
| ibiltari |
14:2148b54dfdbf | 213 | //write the timetag |
| ibiltari |
14:2148b54dfdbf | 214 | { |
| ibiltari |
14:2148b54dfdbf | 215 | osctime_t time = timetag; |
| ibiltari |
14:2148b54dfdbf | 216 | uint32_t d = BigEndian(time.seconds); |
| ibiltari |
14:2148b54dfdbf | 217 | uint8_t * ptr = (uint8_t *) &d; |
| ibiltari |
14:2148b54dfdbf | 218 | // p.write(ptr, 4); |
| ibiltari |
14:2148b54dfdbf | 219 | d = BigEndian(time.fractionofseconds); |
| ibiltari |
14:2148b54dfdbf | 220 | ptr = (uint8_t *) &d; |
| ibiltari |
14:2148b54dfdbf | 221 | // p.write(ptr, 4); |
| ibiltari |
14:2148b54dfdbf | 222 | } |
| ibiltari |
14:2148b54dfdbf | 223 | |
| ibiltari |
14:2148b54dfdbf | 224 | //send the messages |
| ibiltari |
14:2148b54dfdbf | 225 | for (int i = 0; i < numMessages; i++){ |
| ibiltari |
14:2148b54dfdbf | 226 | OSCMessage * msg = getOSCMessage(i); |
| ibiltari |
14:2148b54dfdbf | 227 | int msgSize = msg->bytes(); |
| ibiltari |
14:2148b54dfdbf | 228 | //turn the message size into a pointer |
| ibiltari |
14:2148b54dfdbf | 229 | uint32_t s32 = BigEndian((uint32_t) msgSize); |
| ibiltari |
14:2148b54dfdbf | 230 | uint8_t * sptr = (uint8_t *) &s32; |
| ibiltari |
14:2148b54dfdbf | 231 | //write the messsage size |
| ibiltari |
14:2148b54dfdbf | 232 | // p.write(sptr, 4); |
| ibiltari |
14:2148b54dfdbf | 233 | // msg->send(p); TODO: change this to be compatible |
| ibiltari |
14:2148b54dfdbf | 234 | } |
| ibiltari |
14:2148b54dfdbf | 235 | return *this; |
| ibiltari |
14:2148b54dfdbf | 236 | } |
| ibiltari |
14:2148b54dfdbf | 237 | |
| ibiltari |
14:2148b54dfdbf | 238 | /*============================================================================= |
| ibiltari |
14:2148b54dfdbf | 239 | FILLING |
| ibiltari |
14:2148b54dfdbf | 240 | =============================================================================*/ |
| ibiltari |
14:2148b54dfdbf | 241 | |
| ibiltari |
14:2148b54dfdbf | 242 | OSCBundle& OSCBundle::fill(uint8_t incomingByte){ |
| ibiltari |
14:2148b54dfdbf | 243 | decode(incomingByte); |
| ibiltari |
14:2148b54dfdbf | 244 | return *this; |
| ibiltari |
14:2148b54dfdbf | 245 | } |
| ibiltari |
14:2148b54dfdbf | 246 | |
| ibiltari |
14:2148b54dfdbf | 247 | OSCBundle& OSCBundle::fill(const uint8_t * incomingBytes, int length){ |
| ibiltari |
14:2148b54dfdbf | 248 | while (length--){ |
| ibiltari |
14:2148b54dfdbf | 249 | decode(*incomingBytes++); |
| ibiltari |
14:2148b54dfdbf | 250 | } |
| ibiltari |
14:2148b54dfdbf | 251 | return *this; |
| ibiltari |
14:2148b54dfdbf | 252 | } |
| ibiltari |
14:2148b54dfdbf | 253 | |
| ibiltari |
14:2148b54dfdbf | 254 | /*============================================================================= |
| ibiltari |
14:2148b54dfdbf | 255 | DECODING |
| ibiltari |
14:2148b54dfdbf | 256 | =============================================================================*/ |
| ibiltari |
14:2148b54dfdbf | 257 | |
| ibiltari |
14:2148b54dfdbf | 258 | void OSCBundle::decodeTimetag(){ |
| ibiltari |
14:2148b54dfdbf | 259 | //parse the incoming buffer as a uint64 |
| ibiltari |
14:2148b54dfdbf | 260 | setTimetag(incomingBuffer); |
| ibiltari |
14:2148b54dfdbf | 261 | //make sure the endianness is right |
| ibiltari |
14:2148b54dfdbf | 262 | //xxx time tag timetag = BigEndian(timetag); |
| ibiltari |
14:2148b54dfdbf | 263 | decodeState = MESSAGE_SIZE; |
| ibiltari |
14:2148b54dfdbf | 264 | clearIncomingBuffer(); |
| ibiltari |
14:2148b54dfdbf | 265 | } |
| ibiltari |
14:2148b54dfdbf | 266 | |
| ibiltari |
14:2148b54dfdbf | 267 | void OSCBundle::decodeHeader(){ |
| ibiltari |
14:2148b54dfdbf | 268 | const char * header = "#bundle"; |
| ibiltari |
14:2148b54dfdbf | 269 | if (strcmp(header, (char *) incomingBuffer)!=0){ |
| ibiltari |
14:2148b54dfdbf | 270 | //otherwise go back to the top and wait for a new bundle header |
| ibiltari |
14:2148b54dfdbf | 271 | decodeState = STANDBY; |
| ibiltari |
14:2148b54dfdbf | 272 | error = INVALID_OSC; |
| ibiltari |
14:2148b54dfdbf | 273 | } else { |
| ibiltari |
14:2148b54dfdbf | 274 | decodeState = TIMETAG; |
| ibiltari |
14:2148b54dfdbf | 275 | } |
| ibiltari |
14:2148b54dfdbf | 276 | clearIncomingBuffer(); |
| ibiltari |
14:2148b54dfdbf | 277 | } |
| ibiltari |
14:2148b54dfdbf | 278 | |
| ibiltari |
14:2148b54dfdbf | 279 | void OSCBundle::decodeMessage(uint8_t incomingByte){ |
| ibiltari |
14:2148b54dfdbf | 280 | //get the current message |
| ibiltari |
14:2148b54dfdbf | 281 | if (numMessages > 0){ |
| ibiltari |
14:2148b54dfdbf | 282 | OSCMessage * lastMessage = messages[numMessages - 1]; |
| ibiltari |
14:2148b54dfdbf | 283 | //put the bytes in there |
| ibiltari |
14:2148b54dfdbf | 284 | lastMessage->fill(incomingByte); |
| ibiltari |
14:2148b54dfdbf | 285 | //if it's all done |
| ibiltari |
14:2148b54dfdbf | 286 | if (incomingBufferSize == incomingMessageSize){ |
| ibiltari |
14:2148b54dfdbf | 287 | //move onto the next message |
| ibiltari |
14:2148b54dfdbf | 288 | decodeState = MESSAGE_SIZE; |
| ibiltari |
14:2148b54dfdbf | 289 | clearIncomingBuffer(); |
| ibiltari |
14:2148b54dfdbf | 290 | } else if (incomingBufferSize > incomingMessageSize){ |
| ibiltari |
14:2148b54dfdbf | 291 | error = INVALID_OSC; |
| ibiltari |
14:2148b54dfdbf | 292 | } |
| ibiltari |
14:2148b54dfdbf | 293 | } |
| ibiltari |
14:2148b54dfdbf | 294 | } |
| ibiltari |
14:2148b54dfdbf | 295 | |
| ibiltari |
14:2148b54dfdbf | 296 | //does not validate the incoming OSC for correctness |
| ibiltari |
14:2148b54dfdbf | 297 | void OSCBundle::decode(uint8_t incomingByte){ |
| ibiltari |
14:2148b54dfdbf | 298 | addToIncomingBuffer(incomingByte); |
| ibiltari |
14:2148b54dfdbf | 299 | switch (decodeState){ |
| ibiltari |
14:2148b54dfdbf | 300 | case STANDBY: |
| ibiltari |
14:2148b54dfdbf | 301 | if (incomingByte == '#'){ |
| ibiltari |
14:2148b54dfdbf | 302 | decodeState = HEADER; |
| ibiltari |
14:2148b54dfdbf | 303 | } else if (incomingByte == '/'){ |
| ibiltari |
14:2148b54dfdbf | 304 | add();//add a simple message to the bundle |
| ibiltari |
14:2148b54dfdbf | 305 | decodeMessage(incomingByte); |
| ibiltari |
14:2148b54dfdbf | 306 | decodeState = MESSAGE; |
| ibiltari |
14:2148b54dfdbf | 307 | } |
| ibiltari |
14:2148b54dfdbf | 308 | break; |
| ibiltari |
14:2148b54dfdbf | 309 | case HEADER: |
| ibiltari |
14:2148b54dfdbf | 310 | if (incomingBufferSize == 8){ |
| ibiltari |
14:2148b54dfdbf | 311 | decodeHeader(); |
| ibiltari |
14:2148b54dfdbf | 312 | decodeState = TIMETAG; |
| ibiltari |
14:2148b54dfdbf | 313 | } |
| ibiltari |
14:2148b54dfdbf | 314 | break; |
| ibiltari |
14:2148b54dfdbf | 315 | case TIMETAG: |
| ibiltari |
14:2148b54dfdbf | 316 | if (incomingBufferSize == 8){ |
| ibiltari |
14:2148b54dfdbf | 317 | decodeTimetag(); |
| ibiltari |
14:2148b54dfdbf | 318 | decodeState = MESSAGE_SIZE; |
| ibiltari |
14:2148b54dfdbf | 319 | } |
| ibiltari |
14:2148b54dfdbf | 320 | break; |
| ibiltari |
14:2148b54dfdbf | 321 | case MESSAGE_SIZE: |
| ibiltari |
14:2148b54dfdbf | 322 | if (incomingBufferSize == 4){ |
| ibiltari |
14:2148b54dfdbf | 323 | //make sure the message size is valid |
| ibiltari |
14:2148b54dfdbf | 324 | int32_t msgSize; |
| ibiltari |
14:2148b54dfdbf | 325 | memcpy(&msgSize, incomingBuffer, 4); |
| ibiltari |
14:2148b54dfdbf | 326 | msgSize = BigEndian(msgSize); |
| ibiltari |
14:2148b54dfdbf | 327 | if (msgSize % 4 != 0 || msgSize == 0){ |
| ibiltari |
14:2148b54dfdbf | 328 | error = INVALID_OSC; |
| ibiltari |
14:2148b54dfdbf | 329 | } else { |
| ibiltari |
14:2148b54dfdbf | 330 | //add a message to the buffer |
| ibiltari |
14:2148b54dfdbf | 331 | decodeState = MESSAGE; |
| ibiltari |
14:2148b54dfdbf | 332 | incomingMessageSize = msgSize; |
| ibiltari |
14:2148b54dfdbf | 333 | clearIncomingBuffer(); |
| ibiltari |
14:2148b54dfdbf | 334 | //add a new empty message |
| ibiltari |
14:2148b54dfdbf | 335 | add(); |
| ibiltari |
14:2148b54dfdbf | 336 | } |
| ibiltari |
14:2148b54dfdbf | 337 | } |
| ibiltari |
14:2148b54dfdbf | 338 | break; |
| ibiltari |
14:2148b54dfdbf | 339 | case MESSAGE: |
| ibiltari |
14:2148b54dfdbf | 340 | decodeMessage(incomingByte); |
| ibiltari |
14:2148b54dfdbf | 341 | break; |
| ibiltari |
14:2148b54dfdbf | 342 | } |
| ibiltari |
14:2148b54dfdbf | 343 | } |
| ibiltari |
14:2148b54dfdbf | 344 | |
| ibiltari |
14:2148b54dfdbf | 345 | |
| ibiltari |
14:2148b54dfdbf | 346 | /*============================================================================= |
| ibiltari |
14:2148b54dfdbf | 347 | INCOMING BUFFER MANAGEMENT |
| ibiltari |
14:2148b54dfdbf | 348 | =============================================================================*/ |
| ibiltari |
14:2148b54dfdbf | 349 | |
| ibiltari |
14:2148b54dfdbf | 350 | void OSCBundle::addToIncomingBuffer(uint8_t incomingByte){ |
| ibiltari |
14:2148b54dfdbf | 351 | //realloc some space for the new byte and stick it on the end |
| ibiltari |
14:2148b54dfdbf | 352 | incomingBuffer = (uint8_t *) realloc ( incomingBuffer, incomingBufferSize + 1); |
| ibiltari |
14:2148b54dfdbf | 353 | if (incomingBuffer != NULL){ |
| ibiltari |
14:2148b54dfdbf | 354 | incomingBuffer[incomingBufferSize++] = incomingByte; |
| ibiltari |
14:2148b54dfdbf | 355 | } else { |
| ibiltari |
14:2148b54dfdbf | 356 | error = ALLOCFAILED; |
| ibiltari |
14:2148b54dfdbf | 357 | } |
| ibiltari |
14:2148b54dfdbf | 358 | } |
| ibiltari |
14:2148b54dfdbf | 359 | |
| ibiltari |
14:2148b54dfdbf | 360 | void OSCBundle::clearIncomingBuffer(){ |
| ibiltari |
14:2148b54dfdbf | 361 | incomingBufferSize = 0; |
| ibiltari |
14:2148b54dfdbf | 362 | free(incomingBuffer); |
| ibiltari |
14:2148b54dfdbf | 363 | incomingBuffer = NULL; |
| ibiltari |
14:2148b54dfdbf | 364 | } |
| ibiltari |
14:2148b54dfdbf | 365 | |
| ibiltari |
14:2148b54dfdbf | 366 | |
| ibiltari |
14:2148b54dfdbf | 367 |