Stefan Schuermans commited on 2012-05-06 15:16:58
              Showing 8 changed files, with 471 additions and 111 deletions.
            
| ... | ... | @@ -60,7 +60,7 @@ SRC = $(TARGET).c | 
| 60 | 60 |  | 
| 61 | 61 | # If there is more than one source file, append them above, or modify and | 
| 62 | 62 | # uncomment the following: | 
| 63 | -SRC += app_cfg.c apps.c \ | |
| 63 | +SRC += app_bbm.c app_cfg.c apps.c apps_tools.c \ | |
| 64 | 64 | arp.c bus.c cf.c checksum.c config.c dhcp.c dosfs.c dosfs_user.c \ | 
| 65 | 65 | eeprom.c ethernet.c http.c icmp.c ip.c random.c rtl8019.c \ | 
| 66 | 66 | ser62500.c status.c tasks.c tcp.c timing.c uart.c udp.c \ | 
| ... | ... | @@ -0,0 +1,237 @@ | 
| 1 | +/* flaneth - flash and ethernet | |
| 2 | + Copyright (C) 2007-2012 Stefan Schuermans <stefan@schuermans.info> | |
| 3 | + Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html | |
| 4 | + a BlinkenArea project - http://www.blinkenarea.org/ */ | |
| 5 | + | |
| 6 | +#include <stdio.h> | |
| 7 | +#include <string.h> | |
| 8 | + | |
| 9 | +#include "apps_tools.h" | |
| 10 | +#include "app_bbm.h" | |
| 11 | +#include "debug.h" | |
| 12 | +#include "dosfs.h" | |
| 13 | +#include "nethelp.h" | |
| 14 | +#include "timing.h" | |
| 15 | + | |
| 16 | +///< BBM file header | |
| 17 | +typedef struct app_bbm_header { | |
| 18 | + uint32_t magic; | |
| 19 | + uint16_t height; | |
| 20 | + uint16_t width; | |
| 21 | + uint16_t channels; | |
| 22 | + uint16_t maxval; | |
| 23 | + uint32_t framecnt; | |
| 24 | + uint32_t duration; | |
| 25 | + uint32_t frameptr; | |
| 26 | +} AppBbmHeader; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * @brief get name of next file from playlist directory | |
| 30 | + * @param[in,out] state internal state of application | |
| 31 | + * @param[out] filename name of file | |
| 32 | + * @param[in] filename_sz length of filename buffer | |
| 33 | + * @return 0 if success ful, -1 if not | |
| 34 | + */ | |
| 35 | +static char AppBbmNextName(AppBbmState *state, char *filename, | |
| 36 | + unsigned char filename_sz) | |
| 37 | +{ | |
| 38 | + // assemble filename of playlist directory | |
| 39 | + char dirname[10]; | |
| 40 | + sprintf(dirname, "bbm%hhu/pl", state->no); | |
| 41 | + | |
| 42 | + // open playlist directory | |
| 43 | + DIRINFO di; | |
| 44 | + di.scratch = *state->sectorBuf; | |
| 45 | +  if (DFS_OpenDir(state->vi, (uint8_t *)dirname, &di) != DFS_OK) { | |
| 46 | + // no playlist dir -> deactivate application | |
| 47 | + state->isInit = 0; | |
| 48 | +    debug_app_bbm_printf("%hhu: cannot open directory %s", | |
| 49 | + state->no, filename); | |
| 50 | + return -1; | |
| 51 | + } | |
| 52 | + | |
| 53 | + // get file with index idxFile | |
| 54 | + DIRENT de; | |
| 55 | + unsigned short idx; | |
| 56 | + char firstName[11], haveFirst; | |
| 57 | + haveFirst = 0; | |
| 58 | +  for (idx = 0; idx <= /* file 0 -> loop once */ state->idxFile; ++idx) { | |
| 59 | + | |
| 60 | + // get next file | |
| 61 | +    do { | |
| 62 | +      if (DFS_GetNext(state->vi, &di, &de) != 0) { | |
| 63 | + // no files at all -> deactivate application | |
| 64 | +        if (!haveFirst) { | |
| 65 | + state->isInit = 0; | |
| 66 | +          debug_app_bbm_printf("%hhu: no files in playlist directory", | |
| 67 | + state->no); | |
| 68 | + return -1; | |
| 69 | + } | |
| 70 | + // end of (non-empty) playlist reached -> restart playlist | |
| 71 | + // -> return first file name, next file index 1 | |
| 72 | + snprintf(filename, filename_sz, | |
| 73 | + "bbm%hhu/pl/%-11.11s", state->no, firstName); | |
| 74 | + filename[filename_sz - 1] = 0; | |
| 75 | + state->idxFile = 1; | |
| 76 | + return 0; | |
| 77 | + } | |
| 78 | + } while (de.name[0] == 0 || // ignore deleted | |
| 79 | + de.attr & (ATTR_VOLUME_ID | ATTR_DIRECTORY)); // ignore volumeIDs, | |
| 80 | + // dirs, long names | |
| 81 | + | |
| 82 | + // first file found -> save name (for restarting playlist when end reached) | |
| 83 | +    if (!haveFirst) { | |
| 84 | + memcpy(firstName, de.name, sizeof(firstName)); | |
| 85 | + haveFirst = 1; | |
| 86 | + } | |
| 87 | + | |
| 88 | + } // for idx | |
| 89 | + | |
| 90 | + // found name of file with index idxFile | |
| 91 | + // -> return file name, increment file index for next file | |
| 92 | + snprintf(filename, filename_sz, | |
| 93 | + "bbm%hhu/pl/%-11.11s", state->no, de.name); | |
| 94 | + filename[filename_sz - 1] = 0; | |
| 95 | + state->idxFile++; | |
| 96 | + return 0; | |
| 97 | +} | |
| 98 | + | |
| 99 | +/** | |
| 100 | + * @brief parse header of BBM file | |
| 101 | + * @param[in,out] state internal state of application | |
| 102 | + */ | |
| 103 | +static void AppBbmParseHeader(AppBbmState *state) | |
| 104 | +{ | |
| 105 | + // read BBM header | |
| 106 | + AppBbmHeader hdr; | |
| 107 | + uint32_t len; | |
| 108 | + if (DFS_ReadFile(&state->fi, *state->sectorBuf, | |
| 109 | + (uint8_t *)&hdr, &len, sizeof(hdr)) != DFS_OK) | |
| 110 | + len = 0; | |
| 111 | +  if (len < sizeof(hdr)) { | |
| 112 | +    debug_app_bbm_printf("%hhu: truncated BBM file", state->no); | |
| 113 | + return; // retry with next file in next iteration | |
| 114 | + } | |
| 115 | + | |
| 116 | + // check header | |
| 117 | +  if (ntohl(hdr.magic) != 0x23542666) { | |
| 118 | +    debug_app_bbm_printf("%hhu: invalid magic %lX in BBM file", | |
| 119 | + state->no, hdr.magic); | |
| 120 | + return; // retry with next file in next iteration | |
| 121 | + } | |
| 122 | + state->height = ntohs(hdr.height); | |
| 123 | + state->width = ntohs(hdr.width); | |
| 124 | + state->channels = ntohs(hdr.channels); | |
| 125 | + state->maxval = ntohs(hdr.maxval); | |
| 126 | + if (state->height < 1 || state->height > 1000 || | |
| 127 | + state->width < 1 || state->width > 1000 || | |
| 128 | + state->channels < 1 || state->channels > 3 || | |
| 129 | +      state->maxval < 1 || state->maxval > 255) { | |
| 130 | +    debug_app_bbm_printf("%hhu: invalid dimensions in BBM file", state->no); | |
| 131 | + return; // retry with next file in next iteration | |
| 132 | + } | |
| 133 | +  if (state->height * state->width * state->channels > 1000) { | |
| 134 | +    debug_app_bbm_printf("%hhu: BBM frame size too large", state->no); | |
| 135 | + return; // retry with next file in next iteration | |
| 136 | + } | |
| 137 | + uint32_t frameptr = ntohl(hdr.frameptr); | |
| 138 | +  if (frameptr < sizeof(hdr)) { | |
| 139 | +    debug_app_bbm_printf("%hhu: invalid framepointer in BBM", state->no); | |
| 140 | + return; // retry with next file in next iteration | |
| 141 | + } | |
| 142 | + | |
| 143 | + // seek to start of first frame | |
| 144 | + DFS_Seek(&state->fi, frameptr, *state->sectorBuf); | |
| 145 | +  if (state->fi.pointer != frameptr) { | |
| 146 | +    debug_app_bbm_printf("%hhu: seek to first frame failed", state->no); | |
| 147 | + return; // retry with next file in next iteration | |
| 148 | + } | |
| 149 | + | |
| 150 | + // a file has been found and opened, header is parsed | |
| 151 | +  debug_app_bbm_printf("%hhu: header parsed: %hux%hu-%hu/%hu", state->no, | |
| 152 | + state->width, state->height, state->channels, | |
| 153 | + state->maxval + 1); | |
| 154 | +} | |
| 155 | + | |
| 156 | +/** | |
| 157 | + * @brief open next file from playlist directory | |
| 158 | + * @param[in,out] state internal state of application | |
| 159 | + */ | |
| 160 | +static void AppBbmNextFile(AppBbmState *state) | |
| 161 | +{ | |
| 162 | + // get name of next file to open | |
| 163 | + char filename[22]; | |
| 164 | + if (AppBbmNextName(state, filename, sizeof(filename)) != 0) | |
| 165 | + return; | |
| 166 | + | |
| 167 | + // open file | |
| 168 | + if (DFS_OpenFile(state->vi, (uint8_t *)filename, DFS_READ, | |
| 169 | +                   *state->sectorBuf, &state->fi) != 0) { | |
| 170 | +    debug_app_bbm_printf("%hhu: cannot open file %s", state->no, filename); | |
| 171 | + return; // retry with next file in next iteration | |
| 172 | + } | |
| 173 | +  debug_app_bbm_printf("%hhu: file %s", state->no, filename); | |
| 174 | + | |
| 175 | + // parse header | |
| 176 | + AppBbmParseHeader(state); | |
| 177 | +} | |
| 178 | + | |
| 179 | +/** | |
| 180 | + * @brief initialize BBM play application | |
| 181 | + * @param[in,out] state internal state of application | |
| 182 | + * | |
| 183 | + * state.sectorBuf, state.vi, state.no have to be initialized before calling | |
| 184 | + */ | |
| 185 | +void AppBbmInit(AppBbmState *state) // (extern) | |
| 186 | +{ | |
| 187 | + // default: not initialized | |
| 188 | + state->isInit = 0; | |
| 189 | + | |
| 190 | + // get destination address for MCUF frames | |
| 191 | + char filename[12]; | |
| 192 | + sprintf(filename, "bbm%hhu/addr", state->no); | |
| 193 | + if (AppsToolsReadIp(*state->sectorBuf, state->vi, | |
| 194 | +                      filename, state->addr) == 0) { | |
| 195 | + state->haveAddr = 1; | |
| 196 | +    debug_app_bbm_printf("%hhu: address %hhu.%hhu.%hhu.%hhu", state->no, | |
| 197 | + state->addr[0], state->addr[1], | |
| 198 | + state->addr[2], state->addr[3]); | |
| 199 | +  } else { | |
| 200 | + state->haveAddr = 0; | |
| 201 | +    debug_app_bbm_printf("%hhu: no address", state->no); | |
| 202 | + } | |
| 203 | + | |
| 204 | + // initialize internal state | |
| 205 | + state->idxFile = 0; | |
| 206 | + state->haveFile = 0; | |
| 207 | + | |
| 208 | + // initialized, start with first action now | |
| 209 | + state->isInit = 1; | |
| 210 | + TimingGetMs(&state->nextActMs); | |
| 211 | +} | |
| 212 | + | |
| 213 | +/** | |
| 214 | + * @brief run BBM play application | |
| 215 | + * @param[in,out] state internal state of application | |
| 216 | + */ | |
| 217 | +void AppBbmRun(AppBbmState *state) // (extern) | |
| 218 | +{ | |
| 219 | + // not initialized -> leave | |
| 220 | + if (!state->isInit) | |
| 221 | + return; | |
| 222 | + | |
| 223 | + // time for next action not yet reached -> leave | |
| 224 | + unsigned long ms; | |
| 225 | + TimingGetMs(&ms); | |
| 226 | + if ((long)(state->nextActMs - ms) > 0) | |
| 227 | + return; | |
| 228 | + | |
| 229 | + // no file -> open next one | |
| 230 | +  if (!state->haveFile) { | |
| 231 | + AppBbmNextFile(state); | |
| 232 | + return; // do not work too much in one step / app might be deactivated now | |
| 233 | + } | |
| 234 | + | |
| 235 | + // TODO | |
| 236 | +} | |
| 237 | + | 
| ... | ... | @@ -0,0 +1,46 @@ | 
| 1 | +/* flaneth - flash and ethernet | |
| 2 | + Copyright (C) 2007-2012 Stefan Schuermans <stefan@schuermans.info> | |
| 3 | + Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html | |
| 4 | + a BlinkenArea project - http://www.blinkenarea.org/ */ | |
| 5 | + | |
| 6 | +#ifndef INC_app_bbm | |
| 7 | +#define INC_app_bbm | |
| 8 | + | |
| 9 | +#include "dosfs.h" | |
| 10 | + | |
| 11 | +/// internal state of BBM play application | |
| 12 | +typedef struct app_bbm_state { | |
| 13 | + // initialize before calling init | |
| 14 | + uint8_t (*sectorBuf)[SECTOR_SIZE]; ///< scratch buffer to store a sector | |
| 15 | + VOLINFO *vi; ///< volume information structure | |
| 16 | + uint8_t no; ///< number of BBM play application | |
| 17 | + // internal stuff | |
| 18 | + char isInit; ///< if successfully initialized | |
| 19 | + unsigned long nextActMs; ///< when to do next action | |
| 20 | + char haveAddr; ///< if destination address for MCUF is known | |
| 21 | + unsigned char addr[4]; ///< destination address for MCUF packets | |
| 22 | + unsigned int idxFile; ///< index of file to open next | |
| 23 | + char haveFile; ///< if a file is open | |
| 24 | + FILEINFO fi; ///< information about open file | |
| 25 | + uint16_t height; ///< height of current movie | |
| 26 | + uint16_t width; ///< width of current movie | |
| 27 | + uint16_t channels; ///< channels in current movie | |
| 28 | + uint16_t maxval; ///< maxval of current movie | |
| 29 | +} AppBbmState; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * @brief initialize BBM play application | |
| 33 | + * @param[in,out] state internal state of application | |
| 34 | + * | |
| 35 | + * state.sectorBuf, state.vi, state.no have to be initialized before calling | |
| 36 | + */ | |
| 37 | +extern void AppBbmInit(AppBbmState *state); | |
| 38 | + | |
| 39 | +/** | |
| 40 | + * @brief run BBM play application | |
| 41 | + * @param[in,out] state internal state of application | |
| 42 | + */ | |
| 43 | +extern void AppBbmRun(AppBbmState *state); | |
| 44 | + | |
| 45 | +#endif // #ifndef INC_app_bbm | |
| 46 | + | 
| ... | ... | @@ -3,112 +3,13 @@ | 
| 3 | 3 | Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html | 
| 4 | 4 | a BlinkenArea project - http://www.blinkenarea.org/ */ | 
| 5 | 5 |  | 
| 6 | -#include <stdio.h> | |
| 7 | -#include <string.h> | |
| 8 | - | |
| 6 | +#include "apps_tools.h" | |
| 9 | 7 | #include "app_cfg.h" | 
| 10 | 8 | #include "config.h" | 
| 11 | 9 | #include "debug.h" | 
| 12 | 10 | #include "dosfs.h" | 
| 13 | 11 | #include "rtl8019.h" | 
| 14 | 12 |  | 
| 15 | -/** | |
| 16 | - * @brief read string from file | |
| 17 | - * @param[in] sectorBuf scratch buffer to store a sector | |
| 18 | - * @param[in] vi volume information structure | |
| 19 | - * @param[in] filename name of file to read | |
| 20 | - * @param[out] buf buffer to put string to | |
| 21 | - * @param[in] sz size of buffer | |
| 22 | - * @return 0 on success, -1 on error | |
| 23 | - */ | |
| 24 | -static char AppCfgReadStr(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi, | |
| 25 | - const char *filename, char *buf, unsigned int sz) | |
| 26 | -{ | |
| 27 | - FILEINFO fi; | |
| 28 | - uint32_t len; | |
| 29 | - | |
| 30 | - // open file | |
| 31 | -  if (DFS_OpenFile(vi, (uint8_t *)filename, DFS_READ, sectorBuf, &fi) != 0) { | |
| 32 | -    debug_app_cfg_printf("cannot open file %s", filename); | |
| 33 | - return -1; | |
| 34 | - } | |
| 35 | - | |
| 36 | - // read string from file | |
| 37 | - len = 0; | |
| 38 | - DFS_ReadFile(&fi, sectorBuf, (uint8_t *)buf, &len, sz - 1); | |
| 39 | - if (len > sz - 1) | |
| 40 | - len = sz - 1; | |
| 41 | - buf[len] = 0; // terminate string | |
| 42 | -  debug_apps_printf("string read from file %s: %s", filename, buf); | |
| 43 | - return 0; | |
| 44 | -} | |
| 45 | - | |
| 46 | -/** | |
| 47 | - * @brief read MAC address from file | |
| 48 | - * @param[in] sectorBuf scratch buffer to store a sector | |
| 49 | - * @param[in] vi volume information structure | |
| 50 | - * @param[in] filename name of file to read | |
| 51 | - * @param[out] mac MAC address read | |
| 52 | - * @return 0 on success, -1 on error | |
| 53 | - */ | |
| 54 | -static char AppCfgReadMac(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi, | |
| 55 | - const char *filename, unsigned char mac[6]) | |
| 56 | -{ | |
| 57 | - char bufStr[18]; | |
| 58 | - unsigned char bufMac[6]; | |
| 59 | - | |
| 60 | - // get string from file | |
| 61 | - if (AppCfgReadStr(sectorBuf, vi, filename, bufStr, sizeof(bufStr)) != 0) | |
| 62 | - return -1; | |
| 63 | - | |
| 64 | - // parse string | |
| 65 | - if (sscanf(bufStr, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", | |
| 66 | - &bufMac[0], &bufMac[1], &bufMac[2], | |
| 67 | -             &bufMac[3], &bufMac[4], &bufMac[5]) != 6) { | |
| 68 | -    debug_apps_printf("MAC parse error"); | |
| 69 | - return -1; | |
| 70 | - } | |
| 71 | - | |
| 72 | - // copy MAC to output | |
| 73 | -  debug_apps_printf("MAC read: %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX", | |
| 74 | - bufMac[0], bufMac[1], bufMac[2], | |
| 75 | - bufMac[3], bufMac[4], bufMac[5]); | |
| 76 | - memcpy(mac, bufMac, 6); | |
| 77 | - return 0; | |
| 78 | -} | |
| 79 | - | |
| 80 | -/** | |
| 81 | - * @brief read IP address from file | |
| 82 | - * @param[in] sectorBuf scratch buffer to store a sector | |
| 83 | - * @param[in] vi volume information structure | |
| 84 | - * @param[in] filename name of file to read | |
| 85 | - * @param[out] ip IP address read | |
| 86 | - * @return 0 on success, -1 on error | |
| 87 | - */ | |
| 88 | -static char AppCfgReadIp(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi, | |
| 89 | - const char *filename, unsigned char ip[4]) | |
| 90 | -{ | |
| 91 | - char bufStr[16]; | |
| 92 | - unsigned char bufIp[4]; | |
| 93 | - | |
| 94 | - // get string from file | |
| 95 | - if (AppCfgReadStr(sectorBuf, vi, filename, bufStr, sizeof(bufStr)) != 0) | |
| 96 | - return -1; | |
| 97 | - | |
| 98 | - // parse string | |
| 99 | - if (sscanf(bufStr, "%hhu.%hhu.%hhu.%hhu", | |
| 100 | -             &bufIp[0], &bufIp[1], &bufIp[2], &bufIp[3]) != 4) { | |
| 101 | -    debug_apps_printf("IP parse error"); | |
| 102 | - return -1; | |
| 103 | - } | |
| 104 | - | |
| 105 | - // copy IP to output | |
| 106 | -  debug_apps_printf("IP read: %hhu.%hhu.%hhu.%hhu", | |
| 107 | - bufIp[0], bufIp[1], bufIp[2], bufIp[3]); | |
| 108 | - memcpy(ip, bufIp, 4); | |
| 109 | - return 0; | |
| 110 | -} | |
| 111 | - | |
| 112 | 13 | /** | 
| 113 | 14 | * @brief update configuration | 
| 114 | 15 | * @param[in] sectorBuf scratch buffer to store a sector | 
| ... | ... | @@ -117,10 +18,11 @@ static char AppCfgReadIp(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi, | 
| 117 | 18 | void AppCfgRun(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi) // (extern) | 
| 118 | 19 |  { | 
| 119 | 20 | // load config | 
| 120 | - if (AppCfgReadMac(sectorBuf, vi, "cfg/mac", ConfigMac) == 0) | |
| 21 | +  debug_app_cfg_printf("reading config"); | |
| 22 | + if (AppsToolsReadMac(sectorBuf, vi, "cfg/mac", ConfigMac) == 0) | |
| 121 | 23 | RtlInit(); | 
| 122 | - AppCfgReadIp(sectorBuf, vi, "cfg/ip", ConfigIp); | |
| 123 | - AppCfgReadIp(sectorBuf, vi, "cfg/mask", ConfigMask); | |
| 124 | - AppCfgReadIp(sectorBuf, vi, "cfg/gw", ConfigGw); | |
| 24 | + AppsToolsReadIp(sectorBuf, vi, "cfg/ip", ConfigIp); | |
| 25 | + AppsToolsReadIp(sectorBuf, vi, "cfg/mask", ConfigMask); | |
| 26 | + AppsToolsReadIp(sectorBuf, vi, "cfg/gw", ConfigGw); | |
| 125 | 27 | } | 
| 126 | 28 |  | 
| ... | ... | @@ -5,10 +5,13 @@ | 
| 5 | 5 |  | 
| 6 | 6 | #include <string.h> | 
| 7 | 7 |  | 
| 8 | +#include "app_bbm.h" | |
| 8 | 9 | #include "app_cfg.h" | 
| 9 | 10 | #include "apps.h" | 
| 11 | +#include "cf.h" | |
| 10 | 12 | #include "debug.h" | 
| 11 | 13 | #include "dosfs.h" | 
| 14 | +#include "tasks.h" | |
| 12 | 15 |  | 
| 13 | 16 | /** | 
| 14 | 17 | * @brief list directory and dump file | 
| ... | ... | @@ -26,13 +29,15 @@ static void AppsListDump(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi) | 
| 26 | 29 |  | 
| 27 | 30 | // list files in root directory | 
| 28 | 31 | di.scratch = sectorBuf; | 
| 29 | -  if (DFS_OpenDir(vi, (uint8_t *)"", &di) != 0) { | |
| 32 | +  if (DFS_OpenDir(vi, (uint8_t *)"", &di) != DFS_OK) { | |
| 30 | 33 |      debug_apps_printf("cannot open root directory"); | 
| 31 | 34 | return; | 
| 32 | 35 | } | 
| 33 | 36 |    debug_apps_printf("files in root directory:"); | 
| 34 | -  while (DFS_GetNext(vi, &di, &de) == 0) { | |
| 35 | -    if (de.attr == ATTR_LONG_NAME) { | |
| 37 | +  while (DFS_GetNext(vi, &di, &de) == DFS_OK) { | |
| 38 | +    if (de.name[0] == 0) { | |
| 39 | + // ignore deleted files | |
| 40 | +    } else if (de.attr == ATTR_LONG_NAME) { | |
| 36 | 41 | // ignore long names | 
| 37 | 42 |      } else if (de.attr & ATTR_VOLUME_ID) { | 
| 38 | 43 |        debug_apps_printf("volume ID: %-11.11s", de.name); | 
| ... | ... | @@ -46,13 +51,13 @@ static void AppsListDump(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi) | 
| 46 | 51 | } | 
| 47 | 52 |  | 
| 48 | 53 | // dump last file | 
| 49 | -  if (DFS_OpenFile(vi, filename, DFS_READ, sectorBuf, &fi) != 0) { | |
| 54 | +  if (DFS_OpenFile(vi, filename, DFS_READ, sectorBuf, &fi) != DFS_OK) { | |
| 50 | 55 |      debug_apps_printf("cannot open file %s", filename); | 
| 51 | 56 | return; | 
| 52 | 57 | } | 
| 53 | 58 |    debug_apps_printf("dumping file %s (max. %u bytes):", filename, sizeof(buf)); | 
| 59 | + if (DFS_ReadFile(&fi, sectorBuf, buf, &len, sizeof(buf)) != DFS_OK) | |
| 54 | 60 | len = 0; | 
| 55 | - DFS_ReadFile(&fi, sectorBuf, buf, &len, sizeof(buf)); | |
| 56 | 61 | for (i = 0; i < len; ++i) | 
| 57 | 62 |      debug_apps_printf("%3lu: %02hX", i, buf[i]); | 
| 58 | 63 |    debug_apps_printf("done", filename); | 
| ... | ... | @@ -76,7 +81,7 @@ void AppsRun(void) // (extern) | 
| 76 | 81 |    debug_apps_printf("partition: start %lu size %lu", partStart, partSize); | 
| 77 | 82 |  | 
| 78 | 83 | // get volume info | 
| 79 | -  if (DFS_GetVolInfo(0, sectorBuf, partStart, &vi) != 0) { | |
| 84 | +  if (DFS_GetVolInfo(0, sectorBuf, partStart, &vi) != DFS_OK) { | |
| 80 | 85 |      debug_apps_printf("cannot get volume info"); | 
| 81 | 86 | return; | 
| 82 | 87 | } | 
| ... | ... | @@ -104,5 +109,15 @@ void AppsRun(void) // (extern) | 
| 104 | 109 |  | 
| 105 | 110 | // run one-short applications | 
| 106 | 111 | AppCfgRun(sectorBuf, &vi); | 
| 112 | + | |
| 113 | + // initialize applications | |
| 114 | +  AppBbmState bbm0 = { .sectorBuf = §orBuf, .vi = &vi, .no = 0 }; | |
| 115 | + AppBbmInit(&bbm0); | |
| 116 | + | |
| 117 | + // run applications | |
| 118 | +  while (CfIsPresent()) { | |
| 119 | + AppBbmRun(&bbm0); | |
| 120 | + Tasks(); | |
| 121 | + } | |
| 107 | 122 | } | 
| 108 | 123 |  | 
| ... | ... | @@ -0,0 +1,110 @@ | 
| 1 | +/* flaneth - flash and ethernet | |
| 2 | + Copyright (C) 2007-2012 Stefan Schuermans <stefan@schuermans.info> | |
| 3 | + Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html | |
| 4 | + a BlinkenArea project - http://www.blinkenarea.org/ */ | |
| 5 | + | |
| 6 | +#include <stdio.h> | |
| 7 | +#include <string.h> | |
| 8 | + | |
| 9 | +#include "apps_tools.h" | |
| 10 | +#include "debug.h" | |
| 11 | +#include "dosfs.h" | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * @brief read string from file | |
| 15 | + * @param[in] sectorBuf scratch buffer to store a sector | |
| 16 | + * @param[in] vi volume information structure | |
| 17 | + * @param[in] filename name of file to read | |
| 18 | + * @param[out] buf buffer to put string to | |
| 19 | + * @param[in] sz size of buffer | |
| 20 | + * @return 0 on success, -1 on error | |
| 21 | + */ | |
| 22 | +char AppsToolsReadStr(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi, | |
| 23 | + const char *filename, char *buf, unsigned int sz) // (extern) | |
| 24 | +{ | |
| 25 | + FILEINFO fi; | |
| 26 | + uint32_t len; | |
| 27 | + | |
| 28 | + // open file | |
| 29 | + if (DFS_OpenFile(vi, (uint8_t *)filename, DFS_READ, | |
| 30 | +                   sectorBuf, &fi) != DFS_OK) { | |
| 31 | +    debug_app_cfg_printf("cannot open file %s", filename); | |
| 32 | + return -1; | |
| 33 | + } | |
| 34 | + | |
| 35 | + // read string from file | |
| 36 | + if (DFS_ReadFile(&fi, sectorBuf, (uint8_t *)buf, &len, sz - 1) != DFS_OK) | |
| 37 | + len = 0; | |
| 38 | + if (len > sz - 1) | |
| 39 | + len = sz - 1; | |
| 40 | + buf[len] = 0; // terminate string | |
| 41 | +  debug_apps_tools_printf("string read from file %s: %s", filename, buf); | |
| 42 | + return 0; | |
| 43 | +} | |
| 44 | + | |
| 45 | +/** | |
| 46 | + * @brief read MAC address from file | |
| 47 | + * @param[in] sectorBuf scratch buffer to store a sector | |
| 48 | + * @param[in] vi volume information structure | |
| 49 | + * @param[in] filename name of file to read | |
| 50 | + * @param[out] mac MAC address read | |
| 51 | + * @return 0 on success, -1 on error | |
| 52 | + */ | |
| 53 | +char AppsToolsReadMac(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi, | |
| 54 | + const char *filename, unsigned char mac[6]) // (extern) | |
| 55 | +{ | |
| 56 | + char bufStr[18]; | |
| 57 | + unsigned char bufMac[6]; | |
| 58 | + | |
| 59 | + // get string from file | |
| 60 | + if (AppsToolsReadStr(sectorBuf, vi, filename, bufStr, sizeof(bufStr)) != 0) | |
| 61 | + return -1; | |
| 62 | + | |
| 63 | + // parse string | |
| 64 | + if (sscanf(bufStr, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", | |
| 65 | + &bufMac[0], &bufMac[1], &bufMac[2], | |
| 66 | +             &bufMac[3], &bufMac[4], &bufMac[5]) != 6) { | |
| 67 | +    debug_apps_tools_printf("MAC parse error"); | |
| 68 | + return -1; | |
| 69 | + } | |
| 70 | + | |
| 71 | + // copy MAC to output | |
| 72 | +  debug_apps_tools_printf("MAC read: %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX", | |
| 73 | + bufMac[0], bufMac[1], bufMac[2], | |
| 74 | + bufMac[3], bufMac[4], bufMac[5]); | |
| 75 | + memcpy(mac, bufMac, 6); | |
| 76 | + return 0; | |
| 77 | +} | |
| 78 | + | |
| 79 | +/** | |
| 80 | + * @brief read IP address from file | |
| 81 | + * @param[in] sectorBuf scratch buffer to store a sector | |
| 82 | + * @param[in] vi volume information structure | |
| 83 | + * @param[in] filename name of file to read | |
| 84 | + * @param[out] ip IP address read | |
| 85 | + * @return 0 on success, -1 on error | |
| 86 | + */ | |
| 87 | +char AppsToolsReadIp(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi, | |
| 88 | + const char *filename, unsigned char ip[4]) // (extern) | |
| 89 | +{ | |
| 90 | + char bufStr[16]; | |
| 91 | + unsigned char bufIp[4]; | |
| 92 | + | |
| 93 | + // get string from file | |
| 94 | + if (AppsToolsReadStr(sectorBuf, vi, filename, bufStr, sizeof(bufStr)) != 0) | |
| 95 | + return -1; | |
| 96 | + | |
| 97 | + // parse string | |
| 98 | + if (sscanf(bufStr, "%hhu.%hhu.%hhu.%hhu", | |
| 99 | +             &bufIp[0], &bufIp[1], &bufIp[2], &bufIp[3]) != 4) { | |
| 100 | +    debug_apps_tools_printf("IP parse error"); | |
| 101 | + return -1; | |
| 102 | + } | |
| 103 | + | |
| 104 | + // copy IP to output | |
| 105 | +  debug_apps_tools_printf("IP read: %hhu.%hhu.%hhu.%hhu", | |
| 106 | + bufIp[0], bufIp[1], bufIp[2], bufIp[3]); | |
| 107 | + memcpy(ip, bufIp, 4); | |
| 108 | + return 0; | |
| 109 | +} | |
| 110 | + | 
| ... | ... | @@ -0,0 +1,46 @@ | 
| 1 | +/* flaneth - flash and ethernet | |
| 2 | + Copyright (C) 2007-2012 Stefan Schuermans <stefan@schuermans.info> | |
| 3 | + Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html | |
| 4 | + a BlinkenArea project - http://www.blinkenarea.org/ */ | |
| 5 | + | |
| 6 | +#ifndef INC_apps_tools | |
| 7 | +#define INC_spps_tools | |
| 8 | + | |
| 9 | +#include "dosfs.h" | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * @brief read string from file | |
| 13 | + * @param[in] sectorBuf scratch buffer to store a sector | |
| 14 | + * @param[in] vi volume information structure | |
| 15 | + * @param[in] filename name of file to read | |
| 16 | + * @param[out] buf buffer to put string to | |
| 17 | + * @param[in] sz size of buffer | |
| 18 | + * @return 0 on success, -1 on error | |
| 19 | + */ | |
| 20 | +extern char AppsToolsReadStr(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi, | |
| 21 | + const char *filename, char *buf, unsigned int sz); | |
| 22 | + | |
| 23 | +/** | |
| 24 | + * @brief read MAC address from file | |
| 25 | + * @param[in] sectorBuf scratch buffer to store a sector | |
| 26 | + * @param[in] vi volume information structure | |
| 27 | + * @param[in] filename name of file to read | |
| 28 | + * @param[out] mac MAC address read | |
| 29 | + * @return 0 on success, -1 on error | |
| 30 | + */ | |
| 31 | +extern char AppsToolsReadMac(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi, | |
| 32 | + const char *filename, unsigned char mac[6]); | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * @brief read IP address from file | |
| 36 | + * @param[in] sectorBuf scratch buffer to store a sector | |
| 37 | + * @param[in] vi volume information structure | |
| 38 | + * @param[in] filename name of file to read | |
| 39 | + * @param[out] ip IP address read | |
| 40 | + * @return 0 on success, -1 on error | |
| 41 | + */ | |
| 42 | +extern char AppsToolsReadIp(uint8_t sectorBuf[SECTOR_SIZE], VOLINFO *vi, | |
| 43 | + const char *filename, unsigned char ip[4]); | |
| 44 | + | |
| 45 | +#endif // #ifndef INC_apps_tools | |
| 46 | + | 
| ... | ... | @@ -23,6 +23,8 @@ | 
| 23 | 23 | #define DEBUG_TCP 1 | 
| 24 | 24 | #define DEBUG_HTTP 1 | 
| 25 | 25 | #define DEBUG_APPS 1 | 
| 26 | +#define DEBUG_APPS_TOOLS 1 | |
| 27 | +#define DEBUG_APP_BBM 1 | |
| 26 | 28 | #define DEBUG_APP_CFG 1 | 
| 27 | 29 |  | 
| 28 | 30 | // debug version of printf | 
| ... | ... | @@ -54,6 +56,8 @@ | 
| 54 | 56 | #define debug_tcp_printf(fmt, arg...) debug_specialized_printf(DEBUG_TCP, "tcp: "fmt, ##arg) | 
| 55 | 57 | #define debug_http_printf(fmt, arg...) debug_specialized_printf(DEBUG_HTTP, "http: "fmt, ##arg) | 
| 56 | 58 | #define debug_apps_printf(fmt, arg...) debug_specialized_printf(DEBUG_APPS, "apps: "fmt, ##arg) | 
| 59 | +#define debug_apps_tools_printf(fmt, arg...) debug_specialized_printf(DEBUG_APPS_TOOLS, "apps_tools: "fmt, ##arg) | |
| 60 | +#define debug_app_bbm_printf(fmt, arg...) debug_specialized_printf(DEBUG_APP_BBM, "app_bbm: "fmt, ##arg) | |
| 57 | 61 | #define debug_app_cfg_printf(fmt, arg...) debug_specialized_printf(DEBUG_APP_CFG, "app_cfg: "fmt, ##arg) | 
| 58 | 62 |  | 
| 59 | 63 | #endif // #ifndef INC_debug | 
| 60 | 64 |