MMEx with SPI Slave to allow legacy devices to communicate with modern media such as USB, SD cards, the internet and all of the mbed\'s other interfaces
Dependencies: NetServices MSCUsbHost mbed TMP102 SDFileSystem
ffuncs.cpp@0:67a55a82ce06, 2011-02-27 (annotated)
- Committer:
- DeMein
- Date:
- Sun Feb 27 18:54:40 2011 +0000
- Revision:
- 0:67a55a82ce06
Version as submitted to the NXP Design Challenge
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
DeMein | 0:67a55a82ce06 | 1 | /* MMEx for MBED - File I/O Command processing |
DeMein | 0:67a55a82ce06 | 2 | * Copyright (c) 2011 MK |
DeMein | 0:67a55a82ce06 | 3 | * |
DeMein | 0:67a55a82ce06 | 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
DeMein | 0:67a55a82ce06 | 5 | * of this software and associated documentation files (the "Software"), to deal |
DeMein | 0:67a55a82ce06 | 6 | * in the Software without restriction, including without limitation the rights |
DeMein | 0:67a55a82ce06 | 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
DeMein | 0:67a55a82ce06 | 8 | * copies of the Software, and to permit persons to whom the Software is |
DeMein | 0:67a55a82ce06 | 9 | * furnished to do so, subject to the following conditions: |
DeMein | 0:67a55a82ce06 | 10 | * |
DeMein | 0:67a55a82ce06 | 11 | * The above copyright notice and this permission notice shall be included in |
DeMein | 0:67a55a82ce06 | 12 | * all copies or substantial portions of the Software. |
DeMein | 0:67a55a82ce06 | 13 | * |
DeMein | 0:67a55a82ce06 | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
DeMein | 0:67a55a82ce06 | 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
DeMein | 0:67a55a82ce06 | 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
DeMein | 0:67a55a82ce06 | 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
DeMein | 0:67a55a82ce06 | 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
DeMein | 0:67a55a82ce06 | 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
DeMein | 0:67a55a82ce06 | 20 | * THE SOFTWARE. |
DeMein | 0:67a55a82ce06 | 21 | */ |
DeMein | 0:67a55a82ce06 | 22 | |
DeMein | 0:67a55a82ce06 | 23 | /** |
DeMein | 0:67a55a82ce06 | 24 | \file ffuncs.cpp |
DeMein | 0:67a55a82ce06 | 25 | \brief Commands starting with F for File I/O |
DeMein | 0:67a55a82ce06 | 26 | */ |
DeMein | 0:67a55a82ce06 | 27 | |
DeMein | 0:67a55a82ce06 | 28 | #include "ffuncs.h" |
DeMein | 0:67a55a82ce06 | 29 | |
DeMein | 0:67a55a82ce06 | 30 | FILE *fp1; |
DeMein | 0:67a55a82ce06 | 31 | SDFileSystem sd(p5, p6, p7, p8, fs_sd); |
DeMein | 0:67a55a82ce06 | 32 | MSCFileSystem msc(fs_usb); |
DeMein | 0:67a55a82ce06 | 33 | LocalFileSystem local(fs_local); |
DeMein | 0:67a55a82ce06 | 34 | |
DeMein | 0:67a55a82ce06 | 35 | // directory handles |
DeMein | 0:67a55a82ce06 | 36 | FATFS_DIR dj; |
DeMein | 0:67a55a82ce06 | 37 | DIR *d; |
DeMein | 0:67a55a82ce06 | 38 | char odirectory = NULL; // keeps track of which directory was opened |
DeMein | 0:67a55a82ce06 | 39 | |
DeMein | 0:67a55a82ce06 | 40 | fhandle handles[10]; |
DeMein | 0:67a55a82ce06 | 41 | |
DeMein | 0:67a55a82ce06 | 42 | /** initialize file handles on startup |
DeMein | 0:67a55a82ce06 | 43 | * |
DeMein | 0:67a55a82ce06 | 44 | */ |
DeMein | 0:67a55a82ce06 | 45 | void init_handles() { |
DeMein | 0:67a55a82ce06 | 46 | // initialize the file handles |
DeMein | 0:67a55a82ce06 | 47 | for (int i = 0; i < 10; i++) { |
DeMein | 0:67a55a82ce06 | 48 | // handles[i].filename = NULL; |
DeMein | 0:67a55a82ce06 | 49 | // handles[i].medium = NULL; |
DeMein | 0:67a55a82ce06 | 50 | // handles[i].fsp = NULL; |
DeMein | 0:67a55a82ce06 | 51 | // handles[i].direct = NULL; |
DeMein | 0:67a55a82ce06 | 52 | // handles[i].filemode = NULL; |
DeMein | 0:67a55a82ce06 | 53 | // handles[i].fullpath = NULL; |
DeMein | 0:67a55a82ce06 | 54 | handles[i].fp = NULL; // we only use this to test |
DeMein | 0:67a55a82ce06 | 55 | } |
DeMein | 0:67a55a82ce06 | 56 | } |
DeMein | 0:67a55a82ce06 | 57 | |
DeMein | 0:67a55a82ce06 | 58 | /** main entry for parsing F-commands |
DeMein | 0:67a55a82ce06 | 59 | * |
DeMein | 0:67a55a82ce06 | 60 | */ |
DeMein | 0:67a55a82ce06 | 61 | void parse_F() { |
DeMein | 0:67a55a82ce06 | 62 | err_num = noerror; |
DeMein | 0:67a55a82ce06 | 63 | DBG_msg("parse_F", inbuf); |
DeMein | 0:67a55a82ce06 | 64 | |
DeMein | 0:67a55a82ce06 | 65 | wipesp(inbuf); // first remove space from string |
DeMein | 0:67a55a82ce06 | 66 | |
DeMein | 0:67a55a82ce06 | 67 | if (inbuf[1] != NULL) { |
DeMein | 0:67a55a82ce06 | 68 | switch (inbuf[1]) { |
DeMein | 0:67a55a82ce06 | 69 | case fmount : do_fmount(); // mount storage medium |
DeMein | 0:67a55a82ce06 | 70 | break; |
DeMein | 0:67a55a82ce06 | 71 | case funmount : do_funmount(); // unmount storage medium |
DeMein | 0:67a55a82ce06 | 72 | break; |
DeMein | 0:67a55a82ce06 | 73 | case ffopen : do_ffopen(); // open file |
DeMein | 0:67a55a82ce06 | 74 | break; |
DeMein | 0:67a55a82ce06 | 75 | case ffread : do_ffread(); // read from file |
DeMein | 0:67a55a82ce06 | 76 | break; |
DeMein | 0:67a55a82ce06 | 77 | case ffwrite : do_ffwrite(); // write to file |
DeMein | 0:67a55a82ce06 | 78 | break; |
DeMein | 0:67a55a82ce06 | 79 | case ffclose : do_ffclose(); // close file |
DeMein | 0:67a55a82ce06 | 80 | break; |
DeMein | 0:67a55a82ce06 | 81 | case ffseek : do_ffseek(); // seek to file position |
DeMein | 0:67a55a82ce06 | 82 | break; |
DeMein | 0:67a55a82ce06 | 83 | case fflush : do_fflush(); // flush file |
DeMein | 0:67a55a82ce06 | 84 | break; |
DeMein | 0:67a55a82ce06 | 85 | case fdir : do_fdir(); // get first directory entry |
DeMein | 0:67a55a82ce06 | 86 | break; |
DeMein | 0:67a55a82ce06 | 87 | case fndir : do_fndir(); // get next directory entry |
DeMein | 0:67a55a82ce06 | 88 | break; |
DeMein | 0:67a55a82ce06 | 89 | case fftell : do_fftell(); // get next directory entry |
DeMein | 0:67a55a82ce06 | 90 | break; |
DeMein | 0:67a55a82ce06 | 91 | case ffsize : do_ffsize(); // get next directory entry |
DeMein | 0:67a55a82ce06 | 92 | break; |
DeMein | 0:67a55a82ce06 | 93 | default : do_fdefault(); // command not recognized |
DeMein | 0:67a55a82ce06 | 94 | break; |
DeMein | 0:67a55a82ce06 | 95 | } |
DeMein | 0:67a55a82ce06 | 96 | } else { |
DeMein | 0:67a55a82ce06 | 97 | do_fdefault(); // command not recognized |
DeMein | 0:67a55a82ce06 | 98 | } |
DeMein | 0:67a55a82ce06 | 99 | } |
DeMein | 0:67a55a82ce06 | 100 | |
DeMein | 0:67a55a82ce06 | 101 | /** mount storage device |
DeMein | 0:67a55a82ce06 | 102 | * |
DeMein | 0:67a55a82ce06 | 103 | * syntax: FM[medium]<CR> |
DeMein | 0:67a55a82ce06 | 104 | * \n [medium]: U, S, L |
DeMein | 0:67a55a82ce06 | 105 | */ |
DeMein | 0:67a55a82ce06 | 106 | void do_fmount() { |
DeMein | 0:67a55a82ce06 | 107 | int rslt = 0; |
DeMein | 0:67a55a82ce06 | 108 | |
DeMein | 0:67a55a82ce06 | 109 | DBG_msg("do_fmount", inbuf); |
DeMein | 0:67a55a82ce06 | 110 | if (inbuf[2] != NULL) { |
DeMein | 0:67a55a82ce06 | 111 | switch (inbuf[2]) { |
DeMein | 0:67a55a82ce06 | 112 | case f_sdcard : DBG_msg("do_fmount", "SD, 1st init"); |
DeMein | 0:67a55a82ce06 | 113 | rslt = sd.disk_initialize(); //initialize file system |
DeMein | 0:67a55a82ce06 | 114 | DBG_msg("do_fmount", "SD, 2nd init"); |
DeMein | 0:67a55a82ce06 | 115 | rslt = sd.disk_initialize(); //initialize file system |
DeMein | 0:67a55a82ce06 | 116 | break; |
DeMein | 0:67a55a82ce06 | 117 | case f_local : // mount local flash, nothing really to do, it is always there |
DeMein | 0:67a55a82ce06 | 118 | break; |
DeMein | 0:67a55a82ce06 | 119 | case f_usb : rslt = msc.disk_initialize(); // enumerate USB device |
DeMein | 0:67a55a82ce06 | 120 | break; |
DeMein | 0:67a55a82ce06 | 121 | default : do_fdefault(); // command not recognized |
DeMein | 0:67a55a82ce06 | 122 | break; |
DeMein | 0:67a55a82ce06 | 123 | } |
DeMein | 0:67a55a82ce06 | 124 | } else { |
DeMein | 0:67a55a82ce06 | 125 | do_fdefault(); |
DeMein | 0:67a55a82ce06 | 126 | } |
DeMein | 0:67a55a82ce06 | 127 | if (rslt != noerror) { // could not mount SD or USB device |
DeMein | 0:67a55a82ce06 | 128 | DBG_int("device not mounted", rslt); |
DeMein | 0:67a55a82ce06 | 129 | send_error(err_not_mounted); |
DeMein | 0:67a55a82ce06 | 130 | } |
DeMein | 0:67a55a82ce06 | 131 | } |
DeMein | 0:67a55a82ce06 | 132 | |
DeMein | 0:67a55a82ce06 | 133 | /** unmount storage device |
DeMein | 0:67a55a82ce06 | 134 | * |
DeMein | 0:67a55a82ce06 | 135 | * syntax: FU[medium]<CR> |
DeMein | 0:67a55a82ce06 | 136 | * \n [medium]: U, S, L |
DeMein | 0:67a55a82ce06 | 137 | */ |
DeMein | 0:67a55a82ce06 | 138 | void do_funmount() { |
DeMein | 0:67a55a82ce06 | 139 | // unmount storage device |
DeMein | 0:67a55a82ce06 | 140 | int rslt = 0; |
DeMein | 0:67a55a82ce06 | 141 | DBG_msg("do_funmount", inbuf); |
DeMein | 0:67a55a82ce06 | 142 | |
DeMein | 0:67a55a82ce06 | 143 | if (inbuf[2] != NULL) { |
DeMein | 0:67a55a82ce06 | 144 | switch (inbuf[2]) { |
DeMein | 0:67a55a82ce06 | 145 | case f_sdcard : rslt = sd.disk_sync(); |
DeMein | 0:67a55a82ce06 | 146 | break; |
DeMein | 0:67a55a82ce06 | 147 | case f_local : // sync not needed, class does not have this functions |
DeMein | 0:67a55a82ce06 | 148 | break; |
DeMein | 0:67a55a82ce06 | 149 | case f_usb : rslt = msc.disk_sync(); // enumerate USB device |
DeMein | 0:67a55a82ce06 | 150 | break; |
DeMein | 0:67a55a82ce06 | 151 | default : do_fdefault(); // command not recognized |
DeMein | 0:67a55a82ce06 | 152 | break; |
DeMein | 0:67a55a82ce06 | 153 | } |
DeMein | 0:67a55a82ce06 | 154 | } else { |
DeMein | 0:67a55a82ce06 | 155 | DBG_msg("do_funmount", "argument error"); |
DeMein | 0:67a55a82ce06 | 156 | do_fdefault(); |
DeMein | 0:67a55a82ce06 | 157 | } |
DeMein | 0:67a55a82ce06 | 158 | if (rslt != noerror) { // could not mount SD or USB device |
DeMein | 0:67a55a82ce06 | 159 | // will never see this message |
DeMein | 0:67a55a82ce06 | 160 | DBG_int("device not unmounted", rslt); |
DeMein | 0:67a55a82ce06 | 161 | send_error(err_not_mounted); |
DeMein | 0:67a55a82ce06 | 162 | } |
DeMein | 0:67a55a82ce06 | 163 | } |
DeMein | 0:67a55a82ce06 | 164 | |
DeMein | 0:67a55a82ce06 | 165 | /** open file on storage device |
DeMein | 0:67a55a82ce06 | 166 | * |
DeMein | 0:67a55a82ce06 | 167 | * syntax: FO [handle] [mode] [medium] [name] |
DeMein | 0:67a55a82ce06 | 168 | * \n [handle]: 0..9 |
DeMein | 0:67a55a82ce06 | 169 | * \n [mode] : R, W, A |
DeMein | 0:67a55a82ce06 | 170 | * \n [medium]: U, S, L |
DeMein | 0:67a55a82ce06 | 171 | * \n [name] : filename in 8.3 format |
DeMein | 0:67a55a82ce06 | 172 | * \n anything after FO may be replaced by a Parameter when %n is present |
DeMein | 0:67a55a82ce06 | 173 | */ |
DeMein | 0:67a55a82ce06 | 174 | void do_ffopen() { |
DeMein | 0:67a55a82ce06 | 175 | int han = 0; // variable for handle |
DeMein | 0:67a55a82ce06 | 176 | int i = 0; |
DeMein | 0:67a55a82ce06 | 177 | int pos = 0; |
DeMein | 0:67a55a82ce06 | 178 | int pnum = 0; |
DeMein | 0:67a55a82ce06 | 179 | unsigned char c; |
DeMein | 0:67a55a82ce06 | 180 | char * cstr; |
DeMein | 0:67a55a82ce06 | 181 | |
DeMein | 0:67a55a82ce06 | 182 | wipesp(inbuf); |
DeMein | 0:67a55a82ce06 | 183 | |
DeMein | 0:67a55a82ce06 | 184 | DBG_msg("do_ffopen", inbuf); |
DeMein | 0:67a55a82ce06 | 185 | |
DeMein | 0:67a55a82ce06 | 186 | // check for a % sign in inbuf |
DeMein | 0:67a55a82ce06 | 187 | pos = 2; |
DeMein | 0:67a55a82ce06 | 188 | while ((inbuf[pos] != NULL) && (inbuf[pos] != c_percent)) pos++; |
DeMein | 0:67a55a82ce06 | 189 | |
DeMein | 0:67a55a82ce06 | 190 | if ((inbuf[pos] != NULL) && ((pnum = getpnum(inbuf[pos + 1])) >= 0)) { |
DeMein | 0:67a55a82ce06 | 191 | // found and valid parameter, now insert |
DeMein | 0:67a55a82ce06 | 192 | cstr = new char [param[pnum].size() + 1]; |
DeMein | 0:67a55a82ce06 | 193 | strcpy (cstr, param[pnum].c_str()); |
DeMein | 0:67a55a82ce06 | 194 | DBG_msg("param", cstr); |
DeMein | 0:67a55a82ce06 | 195 | DBG_int("pos", pos); |
DeMein | 0:67a55a82ce06 | 196 | remchar(inbuf, pos, 2); // remove %n, works better for insert |
DeMein | 0:67a55a82ce06 | 197 | DBG_msg("do_ffopen", inbuf); |
DeMein | 0:67a55a82ce06 | 198 | insertstr(inbuf, cstr, pos); // insert |
DeMein | 0:67a55a82ce06 | 199 | DBG_msg("do_ffopen", inbuf); |
DeMein | 0:67a55a82ce06 | 200 | delete[] cstr; |
DeMein | 0:67a55a82ce06 | 201 | } |
DeMein | 0:67a55a82ce06 | 202 | |
DeMein | 0:67a55a82ce06 | 203 | // check the arguments |
DeMein | 0:67a55a82ce06 | 204 | c = inbuf[2]; // [handle] |
DeMein | 0:67a55a82ce06 | 205 | if ((c != NULL) && (c >= '0') && (c <= '9')) { |
DeMein | 0:67a55a82ce06 | 206 | // [handle] in range |
DeMein | 0:67a55a82ce06 | 207 | han = c - '0'; |
DeMein | 0:67a55a82ce06 | 208 | } else { |
DeMein | 0:67a55a82ce06 | 209 | do_fdefault(); |
DeMein | 0:67a55a82ce06 | 210 | return; // terminate this function |
DeMein | 0:67a55a82ce06 | 211 | } |
DeMein | 0:67a55a82ce06 | 212 | |
DeMein | 0:67a55a82ce06 | 213 | if (handles[han].fp != NULL) { // file handle in use! |
DeMein | 0:67a55a82ce06 | 214 | DBG_msg("do_ffopen", "file handle in use"); |
DeMein | 0:67a55a82ce06 | 215 | send_error(err_handle_used); |
DeMein | 0:67a55a82ce06 | 216 | return; |
DeMein | 0:67a55a82ce06 | 217 | } |
DeMein | 0:67a55a82ce06 | 218 | |
DeMein | 0:67a55a82ce06 | 219 | c = inbuf[4]; // [medium] |
DeMein | 0:67a55a82ce06 | 220 | if (c != NULL) { |
DeMein | 0:67a55a82ce06 | 221 | switch (c) { |
DeMein | 0:67a55a82ce06 | 222 | case f_sdcard : handles[han].medium = f_sdcard; |
DeMein | 0:67a55a82ce06 | 223 | strcpy(handles[han].fsp, fsp_sd); |
DeMein | 0:67a55a82ce06 | 224 | break; |
DeMein | 0:67a55a82ce06 | 225 | case f_local : handles[han].medium = f_local; |
DeMein | 0:67a55a82ce06 | 226 | strcpy(handles[han].fsp, fsp_local); |
DeMein | 0:67a55a82ce06 | 227 | break; |
DeMein | 0:67a55a82ce06 | 228 | case f_usb : handles[han].medium = f_usb; |
DeMein | 0:67a55a82ce06 | 229 | strcpy(handles[han].fsp, fsp_usb); |
DeMein | 0:67a55a82ce06 | 230 | break; |
DeMein | 0:67a55a82ce06 | 231 | default : do_fdefault(); // command not recognized |
DeMein | 0:67a55a82ce06 | 232 | break; |
DeMein | 0:67a55a82ce06 | 233 | } |
DeMein | 0:67a55a82ce06 | 234 | } else { |
DeMein | 0:67a55a82ce06 | 235 | do_fdefault(); |
DeMein | 0:67a55a82ce06 | 236 | return; // terminate this function |
DeMein | 0:67a55a82ce06 | 237 | } |
DeMein | 0:67a55a82ce06 | 238 | |
DeMein | 0:67a55a82ce06 | 239 | c = inbuf[3]; // get filemode |
DeMein | 0:67a55a82ce06 | 240 | if (c != NULL) { |
DeMein | 0:67a55a82ce06 | 241 | switch (c) { |
DeMein | 0:67a55a82ce06 | 242 | case 'W' : handles[han].filemode = f_modew; |
DeMein | 0:67a55a82ce06 | 243 | break; |
DeMein | 0:67a55a82ce06 | 244 | case 'R' : handles[han].filemode = f_moder; |
DeMein | 0:67a55a82ce06 | 245 | break; |
DeMein | 0:67a55a82ce06 | 246 | case 'A' : handles[han].filemode = f_modea; |
DeMein | 0:67a55a82ce06 | 247 | break; |
DeMein | 0:67a55a82ce06 | 248 | default : do_fdefault(); // command not recognized |
DeMein | 0:67a55a82ce06 | 249 | break; |
DeMein | 0:67a55a82ce06 | 250 | } |
DeMein | 0:67a55a82ce06 | 251 | } else { |
DeMein | 0:67a55a82ce06 | 252 | do_fdefault(); |
DeMein | 0:67a55a82ce06 | 253 | return; // terminate this function |
DeMein | 0:67a55a82ce06 | 254 | } |
DeMein | 0:67a55a82ce06 | 255 | |
DeMein | 0:67a55a82ce06 | 256 | // now get filename |
DeMein | 0:67a55a82ce06 | 257 | i = 0; |
DeMein | 0:67a55a82ce06 | 258 | while ((inbuf[i + 5] != NULL) && (i <= 13)) { |
DeMein | 0:67a55a82ce06 | 259 | // will not check until end of name, take max 12 chars |
DeMein | 0:67a55a82ce06 | 260 | handles[han].filename[i] = inbuf[i + 5]; |
DeMein | 0:67a55a82ce06 | 261 | i++; |
DeMein | 0:67a55a82ce06 | 262 | handles[han].filename[i] = NULL; // guarantee null terminated string |
DeMein | 0:67a55a82ce06 | 263 | } |
DeMein | 0:67a55a82ce06 | 264 | |
DeMein | 0:67a55a82ce06 | 265 | // create full pathname |
DeMein | 0:67a55a82ce06 | 266 | strcpy(handles[han].fullpath, handles[han].fsp); |
DeMein | 0:67a55a82ce06 | 267 | strcat(handles[han].fullpath, handles[han].filename); |
DeMein | 0:67a55a82ce06 | 268 | char tmp[5]; |
DeMein | 0:67a55a82ce06 | 269 | sprintf(tmp,"%c", handles[han].filemode); |
DeMein | 0:67a55a82ce06 | 270 | |
DeMein | 0:67a55a82ce06 | 271 | DBG_msg("filename:", handles[han].filename); |
DeMein | 0:67a55a82ce06 | 272 | DBG_msg("path :", handles[han].fullpath); |
DeMein | 0:67a55a82ce06 | 273 | DBG_int("handle# :", han); |
DeMein | 0:67a55a82ce06 | 274 | DBG_chr("mode :", handles[han].filemode); |
DeMein | 0:67a55a82ce06 | 275 | DBG_chr("medium :", handles[han].medium); |
DeMein | 0:67a55a82ce06 | 276 | |
DeMein | 0:67a55a82ce06 | 277 | // now open file |
DeMein | 0:67a55a82ce06 | 278 | handles[han].fp = fopen(handles[han].fullpath,tmp); |
DeMein | 0:67a55a82ce06 | 279 | if (handles[han].fp != NULL) { |
DeMein | 0:67a55a82ce06 | 280 | DBG_msg("do_ffopen", "file opened"); |
DeMein | 0:67a55a82ce06 | 281 | } else { |
DeMein | 0:67a55a82ce06 | 282 | DBG_msg("do_ffopen", "file NOT opened"); |
DeMein | 0:67a55a82ce06 | 283 | send_error(err_filenotopen); |
DeMein | 0:67a55a82ce06 | 284 | } |
DeMein | 0:67a55a82ce06 | 285 | } |
DeMein | 0:67a55a82ce06 | 286 | |
DeMein | 0:67a55a82ce06 | 287 | /** read file contents |
DeMein | 0:67a55a82ce06 | 288 | * |
DeMein | 0:67a55a82ce06 | 289 | * syntax: FR [handle] [value] |
DeMein | 0:67a55a82ce06 | 290 | * \n [handle]: 0..9 |
DeMein | 0:67a55a82ce06 | 291 | * \n [value] : number of byte to read |
DeMein | 0:67a55a82ce06 | 292 | * \n when [value]=0 or omitted will read until <EOF>, |
DeMein | 0:67a55a82ce06 | 293 | * reading can be interrupted by sending >F or >I |
DeMein | 0:67a55a82ce06 | 294 | */ |
DeMein | 0:67a55a82ce06 | 295 | void do_ffread() { |
DeMein | 0:67a55a82ce06 | 296 | long int numbytes = 0; |
DeMein | 0:67a55a82ce06 | 297 | long int count = 0; |
DeMein | 0:67a55a82ce06 | 298 | int i, m; |
DeMein | 0:67a55a82ce06 | 299 | int han; |
DeMein | 0:67a55a82ce06 | 300 | bool go = true; |
DeMein | 0:67a55a82ce06 | 301 | bool stopread = false; |
DeMein | 0:67a55a82ce06 | 302 | |
DeMein | 0:67a55a82ce06 | 303 | DBG_msg("do_ffread", inbuf); |
DeMein | 0:67a55a82ce06 | 304 | |
DeMein | 0:67a55a82ce06 | 305 | rx_max = 0; |
DeMein | 0:67a55a82ce06 | 306 | tx_max = 0; |
DeMein | 0:67a55a82ce06 | 307 | |
DeMein | 0:67a55a82ce06 | 308 | int c = inbuf[2]; // [handle] |
DeMein | 0:67a55a82ce06 | 309 | if ((c != NULL) && (c >= '0') && (c <= '9')) { |
DeMein | 0:67a55a82ce06 | 310 | // [handle] in range |
DeMein | 0:67a55a82ce06 | 311 | han = c - '0'; |
DeMein | 0:67a55a82ce06 | 312 | } else { |
DeMein | 0:67a55a82ce06 | 313 | do_fdefault(); |
DeMein | 0:67a55a82ce06 | 314 | return; // exit with error |
DeMein | 0:67a55a82ce06 | 315 | } |
DeMein | 0:67a55a82ce06 | 316 | DBG_int("handle :", han); |
DeMein | 0:67a55a82ce06 | 317 | if (handles[han].fp == NULL) { // file handle not in use! |
DeMein | 0:67a55a82ce06 | 318 | DBG_msg("do_ffread", "no valid file handle"); |
DeMein | 0:67a55a82ce06 | 319 | send_error(err_no_handle); |
DeMein | 0:67a55a82ce06 | 320 | return; |
DeMein | 0:67a55a82ce06 | 321 | } |
DeMein | 0:67a55a82ce06 | 322 | |
DeMein | 0:67a55a82ce06 | 323 | count = 0; |
DeMein | 0:67a55a82ce06 | 324 | // next chars on the commandline is the number of bytes to read |
DeMein | 0:67a55a82ce06 | 325 | if (inbuf[3] == NULL) { |
DeMein | 0:67a55a82ce06 | 326 | // no value on the command line |
DeMein | 0:67a55a82ce06 | 327 | numbytes = 0; |
DeMein | 0:67a55a82ce06 | 328 | } else { |
DeMein | 0:67a55a82ce06 | 329 | // now process line |
DeMein | 0:67a55a82ce06 | 330 | for (i = 3; ((inbuf[i] >='0') && (inbuf[i] <= '9')); i++ ) { |
DeMein | 0:67a55a82ce06 | 331 | numbytes = 10 * numbytes + (inbuf[i] - '0'); |
DeMein | 0:67a55a82ce06 | 332 | } |
DeMein | 0:67a55a82ce06 | 333 | } |
DeMein | 0:67a55a82ce06 | 334 | DBG_int("do_ffread bytes:", numbytes); |
DeMein | 0:67a55a82ce06 | 335 | |
DeMein | 0:67a55a82ce06 | 336 | // now ready to really do the read |
DeMein | 0:67a55a82ce06 | 337 | // must monitor input buffer to check if we need to stop! |
DeMein | 0:67a55a82ce06 | 338 | while (go) { |
DeMein | 0:67a55a82ce06 | 339 | m = mldl.rx_use(); |
DeMein | 0:67a55a82ce06 | 340 | if (m > rx_max) rx_max = m; |
DeMein | 0:67a55a82ce06 | 341 | m = mldl.tx_use(); |
DeMein | 0:67a55a82ce06 | 342 | if (m > tx_max) tx_max = m; |
DeMein | 0:67a55a82ce06 | 343 | |
DeMein | 0:67a55a82ce06 | 344 | c = getc(handles[han].fp); // read one byte |
DeMein | 0:67a55a82ce06 | 345 | // remove comment below to list all bytes read |
DeMein | 0:67a55a82ce06 | 346 | DBG_chr("do_ffread: ", c); |
DeMein | 0:67a55a82ce06 | 347 | if (c == EOF) { |
DeMein | 0:67a55a82ce06 | 348 | // EOF found, send <EOF> sequence |
DeMein | 0:67a55a82ce06 | 349 | mldl.tx_add(c_escape); |
DeMein | 0:67a55a82ce06 | 350 | mldl.tx_add(c_eof); |
DeMein | 0:67a55a82ce06 | 351 | DBG_int("do_ffread: EOF at byte ", count); |
DeMein | 0:67a55a82ce06 | 352 | } else { |
DeMein | 0:67a55a82ce06 | 353 | // no problem, just send data |
DeMein | 0:67a55a82ce06 | 354 | mldl.tx_addp(c); |
DeMein | 0:67a55a82ce06 | 355 | count++; // increase counter |
DeMein | 0:67a55a82ce06 | 356 | } |
DeMein | 0:67a55a82ce06 | 357 | // now check if we have to stop? |
DeMein | 0:67a55a82ce06 | 358 | if (!mldl.rx_empty()) { |
DeMein | 0:67a55a82ce06 | 359 | stopread = (mldl.rxx_read(data_mode) < 0); // intentional stop of read |
DeMein | 0:67a55a82ce06 | 360 | } |
DeMein | 0:67a55a82ce06 | 361 | go = !((c == EOF) || (count == numbytes) || stopread); |
DeMein | 0:67a55a82ce06 | 362 | } |
DeMein | 0:67a55a82ce06 | 363 | |
DeMein | 0:67a55a82ce06 | 364 | // in case the complete file is read, now wait until buffer is emptied |
DeMein | 0:67a55a82ce06 | 365 | while (!stopread && !mldl.tx_empty()) { |
DeMein | 0:67a55a82ce06 | 366 | // keep checking for EOF |
DeMein | 0:67a55a82ce06 | 367 | if (!mldl.rx_empty()) { |
DeMein | 0:67a55a82ce06 | 368 | stopread = (mldl.rxx_read(data_mode) < 0); |
DeMein | 0:67a55a82ce06 | 369 | } |
DeMein | 0:67a55a82ce06 | 370 | } |
DeMein | 0:67a55a82ce06 | 371 | |
DeMein | 0:67a55a82ce06 | 372 | if (stopread) { |
DeMein | 0:67a55a82ce06 | 373 | DBG_msg("do_ffread", "forced stop read received"); |
DeMein | 0:67a55a82ce06 | 374 | mldl.flush_tx(); // empty transmit buffer |
DeMein | 0:67a55a82ce06 | 375 | } |
DeMein | 0:67a55a82ce06 | 376 | |
DeMein | 0:67a55a82ce06 | 377 | DBG_int("do_ffread: end read at byte ", count); |
DeMein | 0:67a55a82ce06 | 378 | DBG_int("rx_max", rx_max); |
DeMein | 0:67a55a82ce06 | 379 | DBG_int("tx_max", tx_max); |
DeMein | 0:67a55a82ce06 | 380 | } |
DeMein | 0:67a55a82ce06 | 381 | |
DeMein | 0:67a55a82ce06 | 382 | /** write to file |
DeMein | 0:67a55a82ce06 | 383 | * |
DeMein | 0:67a55a82ce06 | 384 | * syntax: FW [handle] |
DeMein | 0:67a55a82ce06 | 385 | * \n [handle]: 0..9 |
DeMein | 0:67a55a82ce06 | 386 | * \ wait for prompt, then send data to be written. |
DeMein | 0:67a55a82ce06 | 387 | * End writing by sending >F |
DeMein | 0:67a55a82ce06 | 388 | */ |
DeMein | 0:67a55a82ce06 | 389 | void do_ffwrite() { |
DeMein | 0:67a55a82ce06 | 390 | int han, m; |
DeMein | 0:67a55a82ce06 | 391 | bool go = true; |
DeMein | 0:67a55a82ce06 | 392 | int count = 0; |
DeMein | 0:67a55a82ce06 | 393 | |
DeMein | 0:67a55a82ce06 | 394 | DBG_msg("do_ffwrite", inbuf); |
DeMein | 0:67a55a82ce06 | 395 | int c = inbuf[2]; // [handle] |
DeMein | 0:67a55a82ce06 | 396 | if ((c != NULL) && (c >= '0') && (c <= '9')) { |
DeMein | 0:67a55a82ce06 | 397 | // [handle] in range |
DeMein | 0:67a55a82ce06 | 398 | han = c - '0'; |
DeMein | 0:67a55a82ce06 | 399 | } else { |
DeMein | 0:67a55a82ce06 | 400 | do_fdefault(); |
DeMein | 0:67a55a82ce06 | 401 | return; // check how to exit with error |
DeMein | 0:67a55a82ce06 | 402 | } |
DeMein | 0:67a55a82ce06 | 403 | DBG_int("handle :", han); |
DeMein | 0:67a55a82ce06 | 404 | if (handles[han].fp == NULL) { // file handle not in use! |
DeMein | 0:67a55a82ce06 | 405 | DBG_msg("do_ffwrite", "no valid file handle"); |
DeMein | 0:67a55a82ce06 | 406 | send_error(err_no_handle); |
DeMein | 0:67a55a82ce06 | 407 | return; |
DeMein | 0:67a55a82ce06 | 408 | } |
DeMein | 0:67a55a82ce06 | 409 | send_prompt(); // now send a prompt and we are ready to go |
DeMein | 0:67a55a82ce06 | 410 | while (go) { // as long as we can continue |
DeMein | 0:67a55a82ce06 | 411 | m = mldl.rx_use(); |
DeMein | 0:67a55a82ce06 | 412 | if (m > rx_max) rx_max = m; |
DeMein | 0:67a55a82ce06 | 413 | m = mldl.tx_use(); |
DeMein | 0:67a55a82ce06 | 414 | if (m > tx_max) tx_max = m; |
DeMein | 0:67a55a82ce06 | 415 | c = mldl.rxx_read(data_mode); // get data |
DeMein | 0:67a55a82ce06 | 416 | if ((c == -1) || (c == -2)) go = false; // <EOF> or interrupt |
DeMein | 0:67a55a82ce06 | 417 | if (go) { |
DeMein | 0:67a55a82ce06 | 418 | // remove comment below to list all bytes written |
DeMein | 0:67a55a82ce06 | 419 | DBG_chr("fwrite", c); |
DeMein | 0:67a55a82ce06 | 420 | count++; |
DeMein | 0:67a55a82ce06 | 421 | |
DeMein | 0:67a55a82ce06 | 422 | fputc(c, handles[han].fp); |
DeMein | 0:67a55a82ce06 | 423 | } else { |
DeMein | 0:67a55a82ce06 | 424 | DBG_int("fwrite: ", c); |
DeMein | 0:67a55a82ce06 | 425 | } |
DeMein | 0:67a55a82ce06 | 426 | } |
DeMein | 0:67a55a82ce06 | 427 | DBG_int("fwrite written", count); |
DeMein | 0:67a55a82ce06 | 428 | DBG_int("rx_max", rx_max); |
DeMein | 0:67a55a82ce06 | 429 | DBG_int("tx_max", tx_max); |
DeMein | 0:67a55a82ce06 | 430 | } |
DeMein | 0:67a55a82ce06 | 431 | |
DeMein | 0:67a55a82ce06 | 432 | /** close file |
DeMein | 0:67a55a82ce06 | 433 | * |
DeMein | 0:67a55a82ce06 | 434 | * syntax: FC [handle] |
DeMein | 0:67a55a82ce06 | 435 | * \n [handle]: 0..9 |
DeMein | 0:67a55a82ce06 | 436 | */ |
DeMein | 0:67a55a82ce06 | 437 | void do_ffclose() { |
DeMein | 0:67a55a82ce06 | 438 | int han = 0; |
DeMein | 0:67a55a82ce06 | 439 | int rslt = 0; |
DeMein | 0:67a55a82ce06 | 440 | DBG_msg("do_ffclose", inbuf); |
DeMein | 0:67a55a82ce06 | 441 | |
DeMein | 0:67a55a82ce06 | 442 | char c = inbuf[2]; // file handle should be here |
DeMein | 0:67a55a82ce06 | 443 | if ((c != NULL) && (c >= '0') && (c <= '9')) { |
DeMein | 0:67a55a82ce06 | 444 | // [handle] in range |
DeMein | 0:67a55a82ce06 | 445 | han = c - '0'; |
DeMein | 0:67a55a82ce06 | 446 | } else { |
DeMein | 0:67a55a82ce06 | 447 | do_fdefault(); |
DeMein | 0:67a55a82ce06 | 448 | return; // check how to exit with error |
DeMein | 0:67a55a82ce06 | 449 | } |
DeMein | 0:67a55a82ce06 | 450 | if (handles[han].fp == NULL) { // file handle not in use! |
DeMein | 0:67a55a82ce06 | 451 | DBG_msg("do_ffclose", "no valid file handle"); |
DeMein | 0:67a55a82ce06 | 452 | send_error(err_no_handle); |
DeMein | 0:67a55a82ce06 | 453 | return; |
DeMein | 0:67a55a82ce06 | 454 | } |
DeMein | 0:67a55a82ce06 | 455 | rslt = fclose(handles[han].fp); |
DeMein | 0:67a55a82ce06 | 456 | handles[han].fp = NULL; |
DeMein | 0:67a55a82ce06 | 457 | DBG_int("do_ffclose result", rslt); |
DeMein | 0:67a55a82ce06 | 458 | } |
DeMein | 0:67a55a82ce06 | 459 | |
DeMein | 0:67a55a82ce06 | 460 | /** seek to file position |
DeMein | 0:67a55a82ce06 | 461 | * |
DeMein | 0:67a55a82ce06 | 462 | * syntax: FS [handle] [value] |
DeMein | 0:67a55a82ce06 | 463 | * \n [handle]: 0..9 |
DeMein | 0:67a55a82ce06 | 464 | * \n [value] : new position |
DeMein | 0:67a55a82ce06 | 465 | * \n if [value] is ommitted, will assume 0, |
DeMein | 0:67a55a82ce06 | 466 | * will always seek relative to the start of the file |
DeMein | 0:67a55a82ce06 | 467 | */ |
DeMein | 0:67a55a82ce06 | 468 | void do_ffseek() { |
DeMein | 0:67a55a82ce06 | 469 | DBG_msg("do_ffseek", inbuf); |
DeMein | 0:67a55a82ce06 | 470 | |
DeMein | 0:67a55a82ce06 | 471 | long int position = 0; // max value is 2147483647 |
DeMein | 0:67a55a82ce06 | 472 | int i; |
DeMein | 0:67a55a82ce06 | 473 | int han; |
DeMein | 0:67a55a82ce06 | 474 | |
DeMein | 0:67a55a82ce06 | 475 | int c = inbuf[2]; // [handle] |
DeMein | 0:67a55a82ce06 | 476 | if ((c != NULL) && (c >= '0') && (c <= '9')) { |
DeMein | 0:67a55a82ce06 | 477 | // [handle] in range |
DeMein | 0:67a55a82ce06 | 478 | han = c - '0'; |
DeMein | 0:67a55a82ce06 | 479 | } else { |
DeMein | 0:67a55a82ce06 | 480 | do_fdefault(); |
DeMein | 0:67a55a82ce06 | 481 | return; // check how to exit with error |
DeMein | 0:67a55a82ce06 | 482 | } |
DeMein | 0:67a55a82ce06 | 483 | DBG_int("handle :", han); |
DeMein | 0:67a55a82ce06 | 484 | if (handles[han].fp == NULL) { // file handle not in use! |
DeMein | 0:67a55a82ce06 | 485 | DBG_msg("do_ffseek", "no valid file handle"); |
DeMein | 0:67a55a82ce06 | 486 | send_error(err_no_handle); |
DeMein | 0:67a55a82ce06 | 487 | return; |
DeMein | 0:67a55a82ce06 | 488 | } |
DeMein | 0:67a55a82ce06 | 489 | |
DeMein | 0:67a55a82ce06 | 490 | // next chars on the commandline is the number of bytes to read |
DeMein | 0:67a55a82ce06 | 491 | if (inbuf[3] == NULL) { |
DeMein | 0:67a55a82ce06 | 492 | // no value on the command line |
DeMein | 0:67a55a82ce06 | 493 | position = 0; |
DeMein | 0:67a55a82ce06 | 494 | } else { |
DeMein | 0:67a55a82ce06 | 495 | // now process line |
DeMein | 0:67a55a82ce06 | 496 | for (i = 3; ((inbuf[i] >='0') && (inbuf[i] <= '9')); i++ ) { |
DeMein | 0:67a55a82ce06 | 497 | position = 10 * position + (inbuf[i] - '0'); |
DeMein | 0:67a55a82ce06 | 498 | } |
DeMein | 0:67a55a82ce06 | 499 | } |
DeMein | 0:67a55a82ce06 | 500 | |
DeMein | 0:67a55a82ce06 | 501 | if (fseek(handles[han].fp, position, SEEK_SET) < 0) { |
DeMein | 0:67a55a82ce06 | 502 | // error in fseek |
DeMein | 0:67a55a82ce06 | 503 | send_error(err_seek); |
DeMein | 0:67a55a82ce06 | 504 | return; |
DeMein | 0:67a55a82ce06 | 505 | } |
DeMein | 0:67a55a82ce06 | 506 | } |
DeMein | 0:67a55a82ce06 | 507 | |
DeMein | 0:67a55a82ce06 | 508 | /** flush file |
DeMein | 0:67a55a82ce06 | 509 | * |
DeMein | 0:67a55a82ce06 | 510 | * syntax: FF [handle] |
DeMein | 0:67a55a82ce06 | 511 | * \n [handle]: 0..9 |
DeMein | 0:67a55a82ce06 | 512 | * \n fflush is not implemented in the file systems |
DeMein | 0:67a55a82ce06 | 513 | */ |
DeMein | 0:67a55a82ce06 | 514 | void do_fflush() { |
DeMein | 0:67a55a82ce06 | 515 | DBG_msg("do_fflush", inbuf); |
DeMein | 0:67a55a82ce06 | 516 | } |
DeMein | 0:67a55a82ce06 | 517 | |
DeMein | 0:67a55a82ce06 | 518 | |
DeMein | 0:67a55a82ce06 | 519 | /** open directory and list first entry |
DeMein | 0:67a55a82ce06 | 520 | * |
DeMein | 0:67a55a82ce06 | 521 | * syntax: FD [medium] |
DeMein | 0:67a55a82ce06 | 522 | * \n [medium]: U, S, L |
DeMein | 0:67a55a82ce06 | 523 | * \n returns the first directory item, |
DeMein | 0:67a55a82ce06 | 524 | * subdirectories are not yet supported, |
DeMein | 0:67a55a82ce06 | 525 | * if the listing is empty >F is returned |
DeMein | 0:67a55a82ce06 | 526 | */ |
DeMein | 0:67a55a82ce06 | 527 | void do_fdir() { |
DeMein | 0:67a55a82ce06 | 528 | FILINFO finfo; |
DeMein | 0:67a55a82ce06 | 529 | FRESULT res ; |
DeMein | 0:67a55a82ce06 | 530 | struct dirent *p; |
DeMein | 0:67a55a82ce06 | 531 | char tmp[25]; |
DeMein | 0:67a55a82ce06 | 532 | |
DeMein | 0:67a55a82ce06 | 533 | DBG_msg("do_ffdir", inbuf); |
DeMein | 0:67a55a82ce06 | 534 | |
DeMein | 0:67a55a82ce06 | 535 | if (inbuf[2] != NULL) { |
DeMein | 0:67a55a82ce06 | 536 | switch (inbuf[2]) { |
DeMein | 0:67a55a82ce06 | 537 | case f_sdcard : res = f_opendir(&dj, "0:/"); |
DeMein | 0:67a55a82ce06 | 538 | odirectory = f_sdcard; |
DeMein | 0:67a55a82ce06 | 539 | break; |
DeMein | 0:67a55a82ce06 | 540 | case f_local : d = opendir(rt_local); |
DeMein | 0:67a55a82ce06 | 541 | odirectory = f_local; |
DeMein | 0:67a55a82ce06 | 542 | break; |
DeMein | 0:67a55a82ce06 | 543 | case f_usb : res = f_opendir(&dj, "1:/"); |
DeMein | 0:67a55a82ce06 | 544 | odirectory = f_usb; |
DeMein | 0:67a55a82ce06 | 545 | break; |
DeMein | 0:67a55a82ce06 | 546 | default : do_fdefault(); // command not recognized |
DeMein | 0:67a55a82ce06 | 547 | break; |
DeMein | 0:67a55a82ce06 | 548 | } |
DeMein | 0:67a55a82ce06 | 549 | } else { |
DeMein | 0:67a55a82ce06 | 550 | do_fdefault(); |
DeMein | 0:67a55a82ce06 | 551 | return; |
DeMein | 0:67a55a82ce06 | 552 | } |
DeMein | 0:67a55a82ce06 | 553 | |
DeMein | 0:67a55a82ce06 | 554 | if (odirectory == f_local) { |
DeMein | 0:67a55a82ce06 | 555 | // get listing from local flash |
DeMein | 0:67a55a82ce06 | 556 | if (d != NULL) { |
DeMein | 0:67a55a82ce06 | 557 | if ((p = readdir(d)) != NULL) { |
DeMein | 0:67a55a82ce06 | 558 | sprintf(tmp,"%s", p->d_name); |
DeMein | 0:67a55a82ce06 | 559 | DBG_msg("do_ffdir", tmp); |
DeMein | 0:67a55a82ce06 | 560 | upstring(tmp); |
DeMein | 0:67a55a82ce06 | 561 | mldl.tx_string(tmp); |
DeMein | 0:67a55a82ce06 | 562 | } else { |
DeMein | 0:67a55a82ce06 | 563 | DBG_msg("do_ffdir", "Last directory entry"); |
DeMein | 0:67a55a82ce06 | 564 | mldl.tx_add(c_escape); // send <EOF> sequence |
DeMein | 0:67a55a82ce06 | 565 | mldl.tx_add(c_eof); |
DeMein | 0:67a55a82ce06 | 566 | } |
DeMein | 0:67a55a82ce06 | 567 | } else { |
DeMein | 0:67a55a82ce06 | 568 | // could not open directory |
DeMein | 0:67a55a82ce06 | 569 | DBG_msg("do_ffdir", "Could not open directory"); |
DeMein | 0:67a55a82ce06 | 570 | send_error(err_directory); |
DeMein | 0:67a55a82ce06 | 571 | } |
DeMein | 0:67a55a82ce06 | 572 | } else { |
DeMein | 0:67a55a82ce06 | 573 | // get listing from USB or SD card |
DeMein | 0:67a55a82ce06 | 574 | |
DeMein | 0:67a55a82ce06 | 575 | /* File attribute bits for directory entry */ |
DeMein | 0:67a55a82ce06 | 576 | // #define AM_RDO 0x01 /* Read only */ |
DeMein | 0:67a55a82ce06 | 577 | // #define AM_HID 0x02 /* Hidden */ |
DeMein | 0:67a55a82ce06 | 578 | // #define AM_SYS 0x04 /* System */ |
DeMein | 0:67a55a82ce06 | 579 | // #define AM_VOL 0x08 /* Volume label */ |
DeMein | 0:67a55a82ce06 | 580 | // #define AM_LFN 0x0F /* LFN entry */ |
DeMein | 0:67a55a82ce06 | 581 | // #define AM_DIR 0x10 /* Directory */ |
DeMein | 0:67a55a82ce06 | 582 | // #define AM_ARC 0x20 /* Archive */ |
DeMein | 0:67a55a82ce06 | 583 | |
DeMein | 0:67a55a82ce06 | 584 | if (res == FR_OK) { |
DeMein | 0:67a55a82ce06 | 585 | res = f_readdir(&dj, &finfo); |
DeMein | 0:67a55a82ce06 | 586 | if ((res == FR_OK) && finfo.fname[0] != 0) { |
DeMein | 0:67a55a82ce06 | 587 | if ((finfo.fattrib & AM_DIR) == AM_DIR) { |
DeMein | 0:67a55a82ce06 | 588 | // file is a directory entry |
DeMein | 0:67a55a82ce06 | 589 | sprintf(tmp,"./%s %d", finfo.fname, finfo.fsize); |
DeMein | 0:67a55a82ce06 | 590 | } else { |
DeMein | 0:67a55a82ce06 | 591 | sprintf(tmp,"%s %d", finfo.fname, finfo.fsize); |
DeMein | 0:67a55a82ce06 | 592 | } |
DeMein | 0:67a55a82ce06 | 593 | DBG_msg("ffdir", tmp); |
DeMein | 0:67a55a82ce06 | 594 | upstring(tmp); |
DeMein | 0:67a55a82ce06 | 595 | mldl.tx_string(tmp); |
DeMein | 0:67a55a82ce06 | 596 | } else { |
DeMein | 0:67a55a82ce06 | 597 | DBG_msg("do_ffdir", "Last directory entry"); |
DeMein | 0:67a55a82ce06 | 598 | mldl.tx_add(c_escape); // send <EOF> sequence |
DeMein | 0:67a55a82ce06 | 599 | mldl.tx_add(c_eof); |
DeMein | 0:67a55a82ce06 | 600 | } |
DeMein | 0:67a55a82ce06 | 601 | } else { |
DeMein | 0:67a55a82ce06 | 602 | // could not open directory |
DeMein | 0:67a55a82ce06 | 603 | DBG_msg("do_ffdir", "Could not open directory"); |
DeMein | 0:67a55a82ce06 | 604 | send_error(err_directory); |
DeMein | 0:67a55a82ce06 | 605 | } |
DeMein | 0:67a55a82ce06 | 606 | } |
DeMein | 0:67a55a82ce06 | 607 | } |
DeMein | 0:67a55a82ce06 | 608 | |
DeMein | 0:67a55a82ce06 | 609 | /** lists the next directory item |
DeMein | 0:67a55a82ce06 | 610 | * |
DeMein | 0:67a55a82ce06 | 611 | * syntax: FN [medium] |
DeMein | 0:67a55a82ce06 | 612 | * \n [medium]: U, S, L |
DeMein | 0:67a55a82ce06 | 613 | * returns the next directory item, must be preceded by a FD call. |
DeMein | 0:67a55a82ce06 | 614 | * Subdirectories are not yet supported, |
DeMein | 0:67a55a82ce06 | 615 | * after the last item >F is returned |
DeMein | 0:67a55a82ce06 | 616 | */ |
DeMein | 0:67a55a82ce06 | 617 | void do_fndir() { |
DeMein | 0:67a55a82ce06 | 618 | FILINFO finfo; |
DeMein | 0:67a55a82ce06 | 619 | FRESULT res ; |
DeMein | 0:67a55a82ce06 | 620 | struct dirent *p; |
DeMein | 0:67a55a82ce06 | 621 | char tmp[25]; |
DeMein | 0:67a55a82ce06 | 622 | |
DeMein | 0:67a55a82ce06 | 623 | DBG_msg("do_fndir", inbuf); |
DeMein | 0:67a55a82ce06 | 624 | |
DeMein | 0:67a55a82ce06 | 625 | if (odirectory == f_local) { |
DeMein | 0:67a55a82ce06 | 626 | // get listing from local flash |
DeMein | 0:67a55a82ce06 | 627 | if (d != NULL) { |
DeMein | 0:67a55a82ce06 | 628 | if ((p = readdir(d)) != NULL) { |
DeMein | 0:67a55a82ce06 | 629 | sprintf(tmp,"%s", p->d_name); |
DeMein | 0:67a55a82ce06 | 630 | DBG_msg("ffdir", tmp); |
DeMein | 0:67a55a82ce06 | 631 | upstring(tmp); |
DeMein | 0:67a55a82ce06 | 632 | mldl.tx_string(tmp); |
DeMein | 0:67a55a82ce06 | 633 | } else { |
DeMein | 0:67a55a82ce06 | 634 | DBG_msg("ffdir", "Last directory entry"); |
DeMein | 0:67a55a82ce06 | 635 | mldl.tx_add(c_escape); // send <EOF> sequence |
DeMein | 0:67a55a82ce06 | 636 | mldl.tx_add(c_eof); |
DeMein | 0:67a55a82ce06 | 637 | } |
DeMein | 0:67a55a82ce06 | 638 | } |
DeMein | 0:67a55a82ce06 | 639 | } else { |
DeMein | 0:67a55a82ce06 | 640 | // get listing from USB or SD card |
DeMein | 0:67a55a82ce06 | 641 | res = f_readdir(&dj, &finfo); |
DeMein | 0:67a55a82ce06 | 642 | if ((res == FR_OK) && finfo.fname[0] != 0) { |
DeMein | 0:67a55a82ce06 | 643 | if ((finfo.fattrib & AM_DIR) == AM_DIR) { |
DeMein | 0:67a55a82ce06 | 644 | // file is a directory entry |
DeMein | 0:67a55a82ce06 | 645 | sprintf(tmp,"./%s %d", finfo.fname, finfo.fsize); |
DeMein | 0:67a55a82ce06 | 646 | } else { |
DeMein | 0:67a55a82ce06 | 647 | sprintf(tmp,"%s %d", finfo.fname, finfo.fsize); |
DeMein | 0:67a55a82ce06 | 648 | } |
DeMein | 0:67a55a82ce06 | 649 | DBG_msg("do_fndir", tmp); |
DeMein | 0:67a55a82ce06 | 650 | upstring(tmp); |
DeMein | 0:67a55a82ce06 | 651 | mldl.tx_string(tmp); |
DeMein | 0:67a55a82ce06 | 652 | } else { |
DeMein | 0:67a55a82ce06 | 653 | DBG_msg("do_fndir", "Last directory entry"); |
DeMein | 0:67a55a82ce06 | 654 | mldl.tx_add(c_escape); // send <EOF> sequence |
DeMein | 0:67a55a82ce06 | 655 | mldl.tx_add(c_eof); |
DeMein | 0:67a55a82ce06 | 656 | } |
DeMein | 0:67a55a82ce06 | 657 | } |
DeMein | 0:67a55a82ce06 | 658 | } |
DeMein | 0:67a55a82ce06 | 659 | |
DeMein | 0:67a55a82ce06 | 660 | /** returns the value of the current file pointer |
DeMein | 0:67a55a82ce06 | 661 | * |
DeMein | 0:67a55a82ce06 | 662 | * syntax: FT [handle] |
DeMein | 0:67a55a82ce06 | 663 | * \n [handle]: 0..9 |
DeMein | 0:67a55a82ce06 | 664 | * returns the value of the file pointer for the open file with the |
DeMein | 0:67a55a82ce06 | 665 | * given handle. |
DeMein | 0:67a55a82ce06 | 666 | */ |
DeMein | 0:67a55a82ce06 | 667 | void do_fftell() { |
DeMein | 0:67a55a82ce06 | 668 | int han = 0; |
DeMein | 0:67a55a82ce06 | 669 | int rslt = 0; |
DeMein | 0:67a55a82ce06 | 670 | char tmp[25]; |
DeMein | 0:67a55a82ce06 | 671 | |
DeMein | 0:67a55a82ce06 | 672 | DBG_msg("do_ftell", inbuf); |
DeMein | 0:67a55a82ce06 | 673 | |
DeMein | 0:67a55a82ce06 | 674 | char c = inbuf[2]; // file handle should be here |
DeMein | 0:67a55a82ce06 | 675 | if ((c != NULL) && (c >= '0') && (c <= '9')) { |
DeMein | 0:67a55a82ce06 | 676 | // [handle] in range |
DeMein | 0:67a55a82ce06 | 677 | han = c - '0'; |
DeMein | 0:67a55a82ce06 | 678 | } else { |
DeMein | 0:67a55a82ce06 | 679 | do_fdefault(); |
DeMein | 0:67a55a82ce06 | 680 | return; // check how to exit with error |
DeMein | 0:67a55a82ce06 | 681 | } |
DeMein | 0:67a55a82ce06 | 682 | if (handles[han].fp == NULL) { // file handle not in use! |
DeMein | 0:67a55a82ce06 | 683 | DBG_msg("do_ffclose", "no valid file handle"); |
DeMein | 0:67a55a82ce06 | 684 | send_error(err_no_handle); |
DeMein | 0:67a55a82ce06 | 685 | return; |
DeMein | 0:67a55a82ce06 | 686 | } |
DeMein | 0:67a55a82ce06 | 687 | rslt = ftell(handles[han].fp); |
DeMein | 0:67a55a82ce06 | 688 | sprintf(tmp,"%d", rslt); |
DeMein | 0:67a55a82ce06 | 689 | mldl.tx_string(tmp); |
DeMein | 0:67a55a82ce06 | 690 | |
DeMein | 0:67a55a82ce06 | 691 | DBG_int("do_ftell result", rslt); |
DeMein | 0:67a55a82ce06 | 692 | } |
DeMein | 0:67a55a82ce06 | 693 | |
DeMein | 0:67a55a82ce06 | 694 | /** returns the size of a file |
DeMein | 0:67a55a82ce06 | 695 | * |
DeMein | 0:67a55a82ce06 | 696 | * syntax: FZ [medium] [name] |
DeMein | 0:67a55a82ce06 | 697 | * \n [medium]: S, L or U |
DeMein | 0:67a55a82ce06 | 698 | * \n [name]: valid 8.3 filename |
DeMein | 0:67a55a82ce06 | 699 | * \n argument may contain %n for replacement by the Parameter n |
DeMein | 0:67a55a82ce06 | 700 | * returns the size of a file. This function will open and close the file! |
DeMein | 0:67a55a82ce06 | 701 | */ |
DeMein | 0:67a55a82ce06 | 702 | void do_ffsize() { |
DeMein | 0:67a55a82ce06 | 703 | int i = 0; |
DeMein | 0:67a55a82ce06 | 704 | int pos = 0; |
DeMein | 0:67a55a82ce06 | 705 | int pnum = 0; |
DeMein | 0:67a55a82ce06 | 706 | int size = 0; |
DeMein | 0:67a55a82ce06 | 707 | char filename[20]; |
DeMein | 0:67a55a82ce06 | 708 | char fullpath[50]; |
DeMein | 0:67a55a82ce06 | 709 | char tmp[25]; |
DeMein | 0:67a55a82ce06 | 710 | unsigned char c; |
DeMein | 0:67a55a82ce06 | 711 | char * cstr; |
DeMein | 0:67a55a82ce06 | 712 | |
DeMein | 0:67a55a82ce06 | 713 | wipesp(inbuf); |
DeMein | 0:67a55a82ce06 | 714 | |
DeMein | 0:67a55a82ce06 | 715 | DBG_msg("do_fsize", inbuf); |
DeMein | 0:67a55a82ce06 | 716 | |
DeMein | 0:67a55a82ce06 | 717 | // check for a % sign in inbuf |
DeMein | 0:67a55a82ce06 | 718 | pos = 2; |
DeMein | 0:67a55a82ce06 | 719 | while ((inbuf[pos] != NULL) && (inbuf[pos] != c_percent)) pos++; |
DeMein | 0:67a55a82ce06 | 720 | |
DeMein | 0:67a55a82ce06 | 721 | if ((inbuf[pos] != NULL) && ((pnum = getpnum(inbuf[pos + 1])) >= 0)) { |
DeMein | 0:67a55a82ce06 | 722 | // found and valid parameter, now insert |
DeMein | 0:67a55a82ce06 | 723 | cstr = new char [param[pnum].size() + 1]; |
DeMein | 0:67a55a82ce06 | 724 | strcpy (cstr, param[pnum].c_str()); |
DeMein | 0:67a55a82ce06 | 725 | DBG_msg("param", cstr); |
DeMein | 0:67a55a82ce06 | 726 | DBG_int("pos", pos); |
DeMein | 0:67a55a82ce06 | 727 | remchar(inbuf, pos, 2); // remove %n, works better for insert |
DeMein | 0:67a55a82ce06 | 728 | DBG_msg("do_fsize", inbuf); |
DeMein | 0:67a55a82ce06 | 729 | insertstr(inbuf, cstr, pos); // insert |
DeMein | 0:67a55a82ce06 | 730 | DBG_msg("do_fsize", inbuf); |
DeMein | 0:67a55a82ce06 | 731 | delete[] cstr; |
DeMein | 0:67a55a82ce06 | 732 | } |
DeMein | 0:67a55a82ce06 | 733 | |
DeMein | 0:67a55a82ce06 | 734 | c = inbuf[2]; // [medium] |
DeMein | 0:67a55a82ce06 | 735 | if (c != NULL) { |
DeMein | 0:67a55a82ce06 | 736 | switch (c) { |
DeMein | 0:67a55a82ce06 | 737 | case f_sdcard : strcpy(fullpath, fsp_sd); |
DeMein | 0:67a55a82ce06 | 738 | break; |
DeMein | 0:67a55a82ce06 | 739 | case f_local : strcpy(fullpath, fsp_local); |
DeMein | 0:67a55a82ce06 | 740 | break; |
DeMein | 0:67a55a82ce06 | 741 | case f_usb : strcpy(fullpath, fsp_usb); |
DeMein | 0:67a55a82ce06 | 742 | break; |
DeMein | 0:67a55a82ce06 | 743 | default : do_fdefault(); // command not recognized |
DeMein | 0:67a55a82ce06 | 744 | break; |
DeMein | 0:67a55a82ce06 | 745 | } |
DeMein | 0:67a55a82ce06 | 746 | } else { |
DeMein | 0:67a55a82ce06 | 747 | do_fdefault(); |
DeMein | 0:67a55a82ce06 | 748 | return; // terminate this function |
DeMein | 0:67a55a82ce06 | 749 | } |
DeMein | 0:67a55a82ce06 | 750 | |
DeMein | 0:67a55a82ce06 | 751 | // now get filename |
DeMein | 0:67a55a82ce06 | 752 | i = 0; |
DeMein | 0:67a55a82ce06 | 753 | while ((inbuf[i + 3] != NULL) && (i <= 13)) { |
DeMein | 0:67a55a82ce06 | 754 | // will not check until end of name, take max 13 chars |
DeMein | 0:67a55a82ce06 | 755 | filename[i] = inbuf[i + 3]; |
DeMein | 0:67a55a82ce06 | 756 | i++; |
DeMein | 0:67a55a82ce06 | 757 | filename[i] = NULL; // ensure null terminated string |
DeMein | 0:67a55a82ce06 | 758 | } |
DeMein | 0:67a55a82ce06 | 759 | |
DeMein | 0:67a55a82ce06 | 760 | // create full pathname |
DeMein | 0:67a55a82ce06 | 761 | strcat(fullpath, filename); |
DeMein | 0:67a55a82ce06 | 762 | |
DeMein | 0:67a55a82ce06 | 763 | DBG_msg("filename", fullpath); |
DeMein | 0:67a55a82ce06 | 764 | |
DeMein | 0:67a55a82ce06 | 765 | // now open file |
DeMein | 0:67a55a82ce06 | 766 | FILE *fp = fopen(fullpath, "r"); |
DeMein | 0:67a55a82ce06 | 767 | if (fp != NULL) { |
DeMein | 0:67a55a82ce06 | 768 | DBG_msg("do_fsize", "file opened"); |
DeMein | 0:67a55a82ce06 | 769 | } else { |
DeMein | 0:67a55a82ce06 | 770 | DBG_msg("do_fsize", "file NOT opened"); |
DeMein | 0:67a55a82ce06 | 771 | send_error(err_filenotopen); |
DeMein | 0:67a55a82ce06 | 772 | return; // and get out |
DeMein | 0:67a55a82ce06 | 773 | } |
DeMein | 0:67a55a82ce06 | 774 | |
DeMein | 0:67a55a82ce06 | 775 | fseek(fp, 0L, SEEK_END); // seek to end |
DeMein | 0:67a55a82ce06 | 776 | size = ftell(fp); // get size |
DeMein | 0:67a55a82ce06 | 777 | fclose(fp); // close file |
DeMein | 0:67a55a82ce06 | 778 | sprintf(tmp,"%d", size); |
DeMein | 0:67a55a82ce06 | 779 | mldl.tx_string(tmp); |
DeMein | 0:67a55a82ce06 | 780 | |
DeMein | 0:67a55a82ce06 | 781 | DBG_int("do_fsize result", size); |
DeMein | 0:67a55a82ce06 | 782 | |
DeMein | 0:67a55a82ce06 | 783 | } |
DeMein | 0:67a55a82ce06 | 784 | |
DeMein | 0:67a55a82ce06 | 785 | /** send error message, command not recognized, |
DeMein | 0:67a55a82ce06 | 786 | */ |
DeMein | 0:67a55a82ce06 | 787 | void do_fdefault() { |
DeMein | 0:67a55a82ce06 | 788 | // get version string |
DeMein | 0:67a55a82ce06 | 789 | DBG_msg("do_fdefault", "unsupported command"); |
DeMein | 0:67a55a82ce06 | 790 | send_error(err_novalidcommand); |
DeMein | 0:67a55a82ce06 | 791 | } |