sending MCUF frames via UDP working
Stefan Schuermans

Stefan Schuermans commited on 2012-05-06 15:58:09
Showing 2 changed files, with 75 additions and 4 deletions.

... ...
@@ -11,6 +11,7 @@
11 11
 #include "debug.h"
12 12
 #include "dosfs.h"
13 13
 #include "nethelp.h"
14
+#include "udp.h"
14 15
 #include "timing.h"
15 16
 
16 17
 ///< BBM file header
... ...
@@ -46,7 +47,7 @@ static char AppBbmNextName(AppBbmState *state, char *filename,
46 47
     // no playlist dir -> deactivate application
47 48
     state->isInit = 0;
48 49
     debug_app_bbm_printf("%hhu: cannot open directory %s",
49
-                         state->no, filename);
50
+                         state->no, dirname);
50 51
     return -1;
51 52
   }
52 53
 
... ...
@@ -130,7 +131,8 @@ static void AppBbmParseHeader(AppBbmState *state)
130 131
     debug_app_bbm_printf("%hhu: invalid dimensions in BBM file", state->no);
131 132
     return; // retry with next file in next iteration
132 133
   }
133
-  if (state->height * state->width * state->channels > 1000) {
134
+  state->dataSz = state->height * state->width * state->channels;
135
+  if (state->dataSz > 1000) {
134 136
     debug_app_bbm_printf("%hhu: BBM frame size too large", state->no);
135 137
     return; // retry with next file in next iteration
136 138
   }
... ...
@@ -147,7 +149,23 @@ static void AppBbmParseHeader(AppBbmState *state)
147 149
     return; // retry with next file in next iteration
148 150
   }
149 151
 
152
+  // read frame start mrker
153
+  uint8_t framestart[4];
154
+  if (DFS_ReadFile(&state->fi, *state->sectorBuf,
155
+                   framestart, &len, sizeof(framestart)) != DFS_OK)
156
+    len = 0;
157
+  if (len < sizeof(framestart)) {
158
+    debug_app_bbm_printf("%hhu: truncated BBM file", state->no);
159
+    return; // retry with next file in next iteration
160
+  }
161
+  if (memcmp(framestart, "frms", 4) != 0) {
162
+    debug_app_bbm_printf("%hhu: invalid frame start marker in BBM file",
163
+                         state->no);
164
+    return; // retry with next file in next iteration
165
+  }
166
+
150 167
   // a file has been found and opened, header is parsed
168
+  state->haveFile = 1;
151 169
   debug_app_bbm_printf("%hhu: header parsed: %hux%hu-%hu/%hu", state->no,
152 170
                        state->width, state->height, state->channels,
153 171
                        state->maxval + 1);
... ...
@@ -176,6 +194,53 @@ static void AppBbmNextFile(AppBbmState *state)
176 194
   AppBbmParseHeader(state);
177 195
 }
178 196
 
197
+/**
198
+ * @brief process next frame
199
+ * @param[in,out] state internal state of application
200
+ */
201
+static void AppBbmProcFrame(AppBbmState *state)
202
+{
203
+  struct packet {
204
+    struct UdpPacket udp;
205
+    uint8_t mcuf[12 + state->dataSz];
206
+  } pack;
207
+
208
+  // read next frame from file
209
+  //   - read to mcuf pos 10, so data is placed at pos 12 for MCUF frame
210
+  uint32_t len;
211
+  if (DFS_ReadFile(&state->fi, *state->sectorBuf,
212
+                   pack.mcuf + 10, &len, state->dataSz + 2) != DFS_OK)
213
+    len = 0;
214
+  if (len < state->dataSz + 2) {
215
+    // end of file reached -> use next file in next iteration
216
+    state->haveFile = 0;
217
+    debug_app_bbm_printf("%hhu: end of file", state->no);
218
+    return;
219
+  }
220
+
221
+  // get frame duration
222
+  uint16_t duration = ntohs(*(uint16_t *)(pack.mcuf + 10));
223
+  debug_app_bbm_printf("%hhu: frame duration %u", state->no, duration);
224
+
225
+  // fill in MCUF header
226
+  *(uint32_t *)(pack.mcuf +  0) = htonl(0x23542666);
227
+  *(uint16_t *)(pack.mcuf +  4) = htons(state->height);
228
+  *(uint16_t *)(pack.mcuf +  6) = htons(state->width);
229
+  *(uint16_t *)(pack.mcuf +  8) = htons(state->channels);
230
+  *(uint16_t *)(pack.mcuf + 10) = htons(state->maxval);
231
+
232
+  // send MCUF frame
233
+  if (state->haveAddr) {
234
+    memcpy(pack.udp.IpHdr.Dest, state->addr, sizeof(pack.udp.IpHdr.Dest));
235
+    pack.udp.UdpHdr.SrcPort = htons(2323);
236
+    pack.udp.UdpHdr.DestPort = htons(2323);
237
+    UdpSend((unsigned char *)&pack, sizeof(pack));
238
+  }
239
+
240
+  // wait for frame duration
241
+  state->nextActMs += duration;
242
+}
243
+
179 244
 /**
180 245
  * @brief initialize BBM play application
181 246
  * @param[in,out] state internal state of application
... ...
@@ -223,8 +288,12 @@ void AppBbmRun(AppBbmState *state) // (extern)
223 288
   // time for next action not yet reached -> leave
224 289
   unsigned long ms;
225 290
   TimingGetMs(&ms);
226
-  if ((long)(state->nextActMs - ms) > 0)
291
+  long delta = state->nextActMs - ms;
292
+  if (delta > 0)
227 293
     return;
294
+  // if lagging behing more than 100ms, do not try to catch up -> advance time
295
+  if (delta < -100)
296
+    state->nextActMs = ms;
228 297
 
229 298
   // no file -> open next one
230 299
   if (!state->haveFile) {
... ...
@@ -232,6 +301,7 @@ void AppBbmRun(AppBbmState *state) // (extern)
232 301
     return; // do not work too much in one step / app might be deactivated now
233 302
   }
234 303
 
235
-  // TODO
304
+  // process next frame
305
+  AppBbmProcFrame(state);
236 306
 }
237 307
 
... ...
@@ -26,6 +26,7 @@ typedef struct app_bbm_state {
26 26
   uint16_t      width;     ///< width of current movie
27 27
   uint16_t      channels;  ///< channels in current movie
28 28
   uint16_t      maxval;    ///< maxval of current movie
29
+  uint16_t      dataSz;    ///< size of data in a frame
29 30
 } AppBbmState;
30 31
 
31 32
 /**
32 33