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