FreeCalypso > hg > fc-magnetite
view src/cs/drivers/drv_app/ffs/board/tmffs.c @ 636:57e67ca2e1cb
pcmdata.c: default +CGMI to "FreeCalypso" and +CGMM to model
The present change has no effect whatsoever on Falconia-made and Openmoko-made
devices on which /pcm/CGMI and /pcm/CGMM files have been programmed in FFS
with sensible ID strings by the respective factories, but what should AT+CGMI
and AT+CGMM queries return when the device is a Huawei GTM900 or Tango modem
that has been converted to FreeCalypso with a firmware change? Before the
present change they would return compiled-in defaults of "<manufacturer>" and
"<model>", respectively; with the present change the firmware will self-identify
as "FreeCalypso GTM900-FC" or "FreeCalypso Tango" on the two respective targets.
This firmware identification will become important if someone incorporates an
FC-converted GTM900 or Tango modem into a ZeroPhone-style smartphone where some
high-level software like ofono will be talking to the modem and will need to
properly identify this modem as FreeCalypso, as opposed to some other AT command
modem flavor with different quirks.
In technical terms, the compiled-in default for the AT+CGMI query (which will
always be overridden by the /pcm/CGMI file in FFS if one is present) is now
"FreeCalypso" in all configs on all targets; the compiled-in default for the
AT+CGMM query (likewise always overridden by /pcm/CGMM if present) is
"GTM900-FC" if CONFIG_TARGET_GTM900 or "Tango" if CONFIG_TARGET_TANGO or the
original default of "<model>" otherwise.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 19 Jan 2020 20:14:58 +0000 |
parents | 945cf7f506b2 |
children |
line wrap: on
line source
/****************************************************************************** * Flash File System (ffs) * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com * * ffs testmode interface * * $Id: tmffs.c 1.51 Thu, 18 Dec 2003 10:50:52 +0100 tsj $ * ******************************************************************************/ #ifndef TARGET #include "ffs.cfg" #endif #if (TARGET == 1) #include "etm/etm.h" #include "etm/etm_api.h" #include "ffs/board/task.h" #endif #include "ffs/board/ffstrace.h" #include "ffs/board/tmffs.h" #include "ffs/ffs.h" #include "ffs/pcm.h" #include <string.h> /****************************************************************************** * Local globals for all protocols ******************************************************************************/ static int32 bufsize, tmpsize; static uint8 stringsize; effs_t ffs_initialize(void); effs_t ffs_exit(void); #define tmffs_put8(x) *outp++ = x; #define tmffs_put16(x) *outp++ = (x & 0xff); *outp++ = (x>>8); #if (TARGET == 1) int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize); // Not in use //#define tmffs_put32(x) tmffs_put16(x); tmffs_put16(x >> 16); /****************************************************************************** * TM FFS registration to ETM database *****************************************************************************/ /* Callback function registered in ETM database */ int etm_ffs1_pkt_receive(uint8 *data, int size) { int mid; T_ETM_PKT *pkt; ttw(ttr(TTrTmffs, "etm_ffs1_pkt_receive(*, %d)" NL, size)); /* Create TestMode return Packet */ if ((pkt = (T_ETM_PKT *) target_malloc(sizeof(T_ETM_PKT))) == NULL) { ttw(ttr(TTrTmffs, "etm_ffs1_pkt_receive(): Limit of memory bank reached" NL)); return ETM_NOMEM; } // Max packet size for TM3 is 128 bytes size = tm_ffs(pkt->data, TM3_PACKET_SIZE, data, size); pkt->size = size; pkt->status = ETM_OK; pkt->mid = ETM_FFS1; etm_pkt_send(pkt); target_free(pkt); return ETM_OK; } /* Callback function registered in ETM database */ int etm_ffs2_pkt_receive(uint8 *data, int size) { int status; T_ETM_PKT *pkt = NULL; ttw(ttr(TTrTmffs, "etm_ffs2_pkt_receive(*, %d)" NL, size)); /* Create TestMode return Packet */ if ((pkt = (T_ETM_PKT *) target_malloc(sizeof(T_ETM_PKT))) == NULL) { ttw(ttr(TTrTmffs, "etm_ffs2_pkt_receive(): Limit of memory bank reached" NL)); return ETM_NOMEM; } status = etm_ffs2(pkt, data, size); return status; } /* Init of FFS in the ETM database */ int etm_ffs_init(void) { int status; status = etm_register("FFS1", ETM_FFS1, 0, 0, etm_ffs1_pkt_receive); status = etm_register("FFS2", ETM_FFS2, 0, 0, etm_ffs2_pkt_receive); return status; } #endif // (TARGET == 1) /****************************************************************************** * FFS1 Protocol ******************************************************************************/ #ifndef TMFFS1 int tm_ffs(unsigned char *outp, int outsize, unsigned char *inp, int insize) { return -1; // FIXME handle error better } // Note these functions must be presented because ffs_query() use them but // they are only valid if FFS1_PROTOCOL is used. int tmffs_bufsize(void) { return EFFS_NOSYS; } unsigned char *tmffs_bufaddr(void) { return 0; } #else #if (GSMLITE == 1) #define TMFFS1_BUFFER_SIZE 4000 //previously 8192 #else #define TMFFS1_BUFFER_SIZE 8192 #endif #define TMFFS1_STRING_SIZE 127 /****************************************************************************** * Macros ******************************************************************************/ #define tmffs1_putdata(outp, src, size) \ tmffs_put8(FPI_DATA); \ tmffs_put16(size); \ memcpy(outp, src, size); \ outp += size; /****************************************************************************** * Local globals ******************************************************************************/ static unsigned char buffer[TMFFS1_BUFFER_SIZE]; static bufindex; static char string[TMFFS1_STRING_SIZE]; static effs_t tm_ffs_overflowck(void) { if (bufsize > TMFFS1_BUFFER_SIZE || stringsize > TMFFS1_STRING_SIZE) return EFFS_TOOBIG; return EFFS_OK; } /****************************************************************************** * tm_ffs ******************************************************************************/ /** * NOTEME: This has been introduced when the ffs 1MB device limit was * broken. This made location_t go from uint16 to uint32, messing up * with PCTM. * * This makes the xstat_s look the same to PCTM PC side, though * location will be forced to 0. */ void hack_xstat_2_look_like_old_xstat(struct xstat_s *xstat) { int i; char *location; xstat->location = 0; for (location = (char *) &(xstat->location) + 2; location <= (char *) &(xstat->sequence); location++) *location = location[2]; } // Parse input message and execute function. Then fill output buffer with // return values from the called function and transmit the message. Return // number of bytes inserted into output buffer. If return value is negative, // it represents an error code. int tm_ffs(unsigned char *outp, int outsize, unsigned char *inp, int insize) { int error; tmffs_cid_t fid; unsigned char *outp_start = outp; unsigned char *inp_start = inp; static uint8 i8[2]; static uint16 i8i; static uint16 i16[2]; static uint16 i16i; static uint32 i32[2]; static uint16 i32i; tw(tr(TR_BEGIN, TrTmffs, "TMFFS:\n")); while((fid = *inp++) != FPI_END) { switch(fid) { /********************************************************** * Generic Protocol Functions **********************************************************/ case FPI_BEGIN: // for (i8i = 0; i8i < TMFFS1_STRING_SIZE; i8i++) // DEBUG // string[i8i] = '#'; // for (i8i = 0; i8i < TMFFS1_BUFFER_SIZE; i8i++) // DEBUG // buffer[i8i] = '$'; i8i = i16i = i32i = bufsize = stringsize = 0; bufindex = 0; i8[0] = i8[1] = 0; i16[0] = i16[1] = 0; i32[0] = i32[1] = 0; string[0] = buffer[0] = 0; tw(tr(TR_FUNC, TrTmffs, "FPI_BEGIN\n")); ttw(ttr(TTrTmffs, "tm1" NL)); break; case FPI_TMFFS_VERSION: // NULL -> UINT16 tmffs_put16(TMFFS1_VERSION); break; case FPI_INT8: i8[i8i++] = inp[0]; inp += 1; tw(tr(TR_FUNC, TrTmffs, "FPI_INT8(%d/0x%x)\n", i8[i8i-1], i8[i8i-1])); ttw(ttr(TTrTmffs, "tm_i8" NL)); break; case FPI_INT16: i16[i16i++] = (inp[0]) | (inp[1] << 8); inp += 2; tw(tr(TR_FUNC, TrTmffs, "FPI_INT16(%d/0x%x)\n", i16[i16i-1], i16[i16i-1])); ttw(ttr(TTrTmffs, "tm_i16" NL)); break; case FPI_INT32: i32[i32i++] = inp[0] | (inp[1] << 8) | (inp[2] << 16) | (inp[3] << 24); inp += 4; tw(tr(TR_FUNC, TrTmffs, "FPI_INT32(%d/0x%x)\n", i32[i32i-1], i32[i32i-1])); ttw(ttr(TTrTmffs, "tm_i32" NL)); break; case FPI_BUFFER: bufsize = inp[0] | (inp[1] << 8); inp += 2; tw(tr(TR_FUNC, TrTmffs, "FPI_BUFFER(%d)\n", bufsize)); ttw(ttr(TTrTmffs, "tm_buf" NL)); break; case FPI_DATA: bufsize = inp[0] | (inp[1] << 8); inp += 2; memcpy(buffer, inp, bufsize); inp += bufsize; tw(tr(TR_FUNC, TrTmffs, "FPI_DATA(%d)\n", bufsize)); ttw(ttr(TTrTmffs, "tm_data" NL)); break; case FPI_STRBUF: // string buffer size MUST include null-terminator! stringsize = inp[0]; inp += 1; tw(tr(TR_FUNC, TrTmffs, "FPI_STRBUF(%d)\n", stringsize)); ttw(ttr(TTrTmffs, "tm_sbuf" NL)); break; case FPI_STRING: // stringsize MUST include null-terminator! // <INT8>, <BYTES> -> NULL (or ERROR) stringsize = inp[0]; inp += 1; if (stringsize <= TMFFS1_STRING_SIZE) memcpy(string, inp, stringsize); inp += stringsize; tw(tr(TR_FUNC, TrTmffs, "FPI_STRING(%d,'%s')\n", stringsize, string)); ttw(ttr(TTrTmffs, "tm_s" NL)); break; case FPI_BUFREAD: // <INT16> -> DATA tmpsize = inp[0] | (inp[1] << 8); inp += 2; tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_READ(%d)\n", tmpsize)); tmffs1_putdata(outp, &buffer[bufindex], tmpsize); bufindex += tmpsize; ttw(ttr(TTrTmffs, "tm_bufrd" NL)); break; case FPI_BUFWRITE: // <INT16>, <BYTES> -> NULL (or ERROR) tmpsize = inp[0] | (inp[1] << 8); inp += 2; tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_WRITE(%d)\n", tmpsize)); if (bufsize + tmpsize <= TMFFS1_BUFFER_SIZE) memcpy(&buffer[bufsize], inp, tmpsize); inp += tmpsize; bufsize += tmpsize; ttw(ttr(TTrTmffs, "tm_bufwr" NL)); break; case FPI_BUFSET: bufindex = inp[0] | (inp[1] << 8); inp += 2; tw(tr(TR_FUNC, TrTmffs, "FPI_BUF_SET(%d)\n", bufindex)); ttw(ttr(TTrTmffs, "tm_bufset" NL)); break; /********************************************************** * FFS Functions **********************************************************/ case FPI_PREFORMAT: // NULL -> ERROR if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_preformat_nb(i16[0], 0); if (error > 0) error = 0; // ignore request id tmffs_put8(error); tw(tr(TR_FUNC, TrTmffs, "FPI_PREFORMAT(0x%x)\n", i16[0])); ttw(ttr(TTrTmffs, "tm_pfmt" NL)); break; case FPI_FORMAT: // STRING -> ERROR if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_format_nb(&string[0], i16[0], 0); if (error > 0) error = 0; // ignore request id tmffs_put8(error); tw(tr(TR_FUNC, TrTmffs, "FPI_FORMAT(0x%x)\n", i16[0])); ttw(ttr(TTrTmffs, "tm_fmt" NL)); break; case FPI_FCREATE: // STRING, DATA -> ERROR if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_fcreate_nb(string, buffer, bufsize, 0); if (error > 0) error = 0; // ignore request id tmffs_put8(error); tw(tr(TR_FUNC, TrTmffs, "FPI_FCREATE('%s', 0x%x, %d/0x%x)\n", string, buffer, bufsize, bufsize)); ttw(ttr(TTrTmffs, "tm_fcr" NL)); break; case FPI_FUPDATE: // STRING, DATA -> ERROR if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_fupdate_nb(string, buffer, bufsize, 0); if (error > 0) error = 0; // ignore request id tmffs_put8(error); tw(tr(TR_FUNC, TrTmffs, "FPI_FUPDATE('%s', 0x%x, %d/0x%x)\n", string, buffer, bufsize, bufsize)); ttw(ttr(TTrTmffs, "tm_fup" NL)); break; case FPI_FWRITE: // STRING, DATA -> ERROR if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_fwrite_nb(string, buffer, bufsize, 0); if (error > 0) error = 0; // ignore request id tmffs_put8(error); tw(tr(TR_FUNC, TrTmffs, "FPI_FWRITE('%s', 0x%x, %d/0x%x)\n", string, buffer, bufsize, bufsize)); ttw(ttr(TTrTmffs, "tm_fwr" NL)); break; case FPI_FREAD: // STRING, BUFFER -> ERROR if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_file_read(string, buffer, TMFFS1_BUFFER_SIZE); // Because a 32-bit integer is returned, we have to saturate it // into an 8-bit value. if (error >= 0) error = 0; tmffs_put8(error); tw(tr(TR_FUNC, TrTmffs, "FPI_FREAD('%s', 0x%x, %d/0x%x)\n", string, buffer, bufsize, bufsize)); ttw(ttr(TTrTmffs, "tm_frd" NL)); break; case FPI_REMOVE: // STRING -> ERROR if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_remove_nb(string, 0); if (error > 0) error = 0; // ignore request id tmffs_put8(error); tw(tr(TR_FUNC, TrTmffs, "FPI_REMOVE()\n")); ttw(ttr(TTrTmffs, "tm_rm" NL)); break; case FPI_MKDIR: // STRING -> ERROR if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_mkdir_nb(string, 0); if (error > 0) error = 0; // ignore request id tmffs_put8(error); tw(tr(TR_FUNC, TrTmffs, "FPI_MKDIR()\n")); ttw(ttr(TTrTmffs, "tm_mkd" NL)); break; case FPI_OPENDIR: // STRING, BUFFER -> ERROR, DATA if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_opendir(string, (struct dir_s *) buffer); // Because a 32-bit integer is returned, we have to saturate it // into an 8-bit value. if (error >= 0) error = 0; tmffs_put8(error); tmffs1_putdata(outp, buffer, sizeof(struct dir_s)); tw(tr(TR_FUNC, TrTmffs, "FPI_OPENDIR()\n")); ttw(ttr(TTrTmffs, "tm_od" NL)); break; case FPI_READDIR: // DATA, STRBUF -> ERROR, DATA, STRING string[0] = 0; if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_readdir((struct dir_s *) buffer, string, stringsize); // Saturate error(i) in order to let it fit in type int8. if (error > 127) error = 127; tmffs_put8(error); tmffs1_putdata(outp, buffer, sizeof(struct dir_s)); stringsize = strlen(string) + 1; tmffs_put8(FPI_STRING); // put directory entry's name... tmffs_put8(stringsize); memcpy(outp, string, stringsize); outp += stringsize; tw(tr(TR_FUNC, TrTmffs, "FPI_READDIR()\n")); ttw(ttr(TTrTmffs, "tm_rdd" NL)); break; case FPI_STAT: // STRING, BUFFER -> ERROR, DATA if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_stat(&string[0], (struct stat_s *) buffer); tmffs_put8(error); tmffs1_putdata(outp, buffer, sizeof(struct stat_s)); tw(tr(TR_FUNC, TrTmffs, "FPI_STAT()\n")); ttw(ttr(TTrTmffs, "tm_st" NL)); break; case FPI_LINKSTAT: // STRING, BUFFER -> ERROR, DATA if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_xlstat(&string[0], (struct xstat_s *) buffer); tmffs_put8(error); hack_xstat_2_look_like_old_xstat((struct xstat_s *) buffer); tmffs1_putdata(outp, buffer, sizeof(struct xstat_s) - 2); tw(tr(TR_FUNC, TrTmffs, "FPI_()\n")); ttw(ttr(TTrTmffs, "tm_lst" NL)); break; case FPI_SYMLINK: // STRING, DATA -> ERROR if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_symlink_nb(string, (char *) buffer, 0); if (error > 0) error = 0; // ignore request id tmffs_put8(error); tw(tr(TR_FUNC, TrTmffs, "FPI_SYMLINK()\n")); ttw(ttr(TTrTmffs, "tm_sym" NL)); break; case FPI_READLINK: // STRING, BUFFER -> ERROR, DATA if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_readlink(string, (char *) buffer, TMFFS1_BUFFER_SIZE); // Because a 32-bit integer is returned, we have to saturate it // into an 8-bit value. if (error >= 0) error = 0; tmffs_put8(error); tmffs1_putdata(outp, buffer, bufsize); // put link contents tw(tr(TR_FUNC, TrTmffs, "FPI_READLINK()\n")); ttw(ttr(TTrTmffs, "tm_rdl" NL)); break; case FPI_QUERY: // INT8 -> ERROR, DATA error = ffs_query(i8[0], buffer); tmffs_put8(error); tmffs1_putdata(outp, buffer, 16); tw(tr(TR_FUNC, TrTmffs, "FPI_QUERY()\n")); ttw(ttr(TTrTmffs, "tm_q" NL)); break; case FPI_FCONTROL: // STRING INT8 INT32 -> ERROR if ((error = tm_ffs_overflowck()) == EFFS_OK) error = ffs_fcontrol_nb(string, i8[0], i32[0], 0); if (error > 0) error = 0; // ignore request id tmffs_put8(error); tw(tr(TR_FUNC, TrTmffs, "FPI_FCONTROL()\n")); ttw(ttr(TTrTmffs, "tm_fc" NL)); break; case FPI_INIT: // NULL -> ERROR error =ffs_initialize(); tmffs_put8(error); tw(tr(TR_FUNC, TrTmffs, "FPI_INIT()\n")); ttw(ttr(TTrTmffs, "tm_init" NL)); break; case FPI_EXIT: // NULL -> ERROR error = ffs_exit(); tmffs_put8(error); tw(tr(TR_FUNC, TrTmffs, "FPI_EXIT()\n")); ttw(ttr(TTrTmffs, "tm_exit" NL)); break; case FPI_TFFS: { // STRING -> ERROR #if (WITH_TFFS == 1) extern char ffs_test_string[]; // defined in task.c memcpy(ffs_test_string, string, stringsize); tw(tr(TR_FUNC, TrTmffs, "FPI_TFFS()\n")); ttw(ttr(TTrTmffs, "tm_tffs" NL)); #else tmffs_put8(EFFS_NOSYS); #endif break; } default: tw(tr(TR_FUNC, TrTmffs, "ERROR: Unknown tmffs protocol code\n")); ttw(ttr(TTrTmffs, "tm?" NL)); break; } // check if we read beyond buffer end if (inp > inp_start + insize) { tw(tr(TR_FUNC, TrTmffs, "ERROR: Read beyond end of input buffer\n")); ttw(ttr(TTrTmffs, "tm_fatal" NL)); // NOTEME: We really should reset output buffer and put a return // code that tells us what went wrong! return 0; } } tw(tr(TR_END, TrTmffs, "")); return outp - outp_start; } int tmffs_bufsize(void) { return TMFFS1_BUFFER_SIZE; } unsigned char *tmffs_bufaddr(void) { return buffer; } #endif // TMFFS1 /****************************************************************************** * FFS2 protocol ******************************************************************************/ #ifndef TMFFS2 #if (TARGET == 1) int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize) { int error; tw(tr(TR_BEGIN, TrTmffs, "FFS2 protocol not represented in target\n")); error = -1; // FIXME other error? #if 0 // Note we can only use this if etm is in target // We return a packet instead of waiting for timeout. pkt->size = 0; pkt->status = -error; pkt->mid = ETM_FFS2; etm_pkt_send(pkt); #endif target_free(pkt); tw(tr(TR_END, TrTmffs, "")); return error; } #endif // (TARGET == 1) #else #define TMFFS_BUFFER_SIZE 256 // FIXME change to packet size #define TMFFS_STRING_SIZE 127 /****************************************************************************** * Macros ******************************************************************************/ #define tmffs_get8() inp[0]; inp += 1; #define tmffs_get16() (inp[0]) | (inp[1] << 8); inp += 2; #define tmffs_get32() inp[0] | (inp[1] << 8) | (inp[2] << 16)\ | (inp[3] << 24); inp += 4; #define tmffs_getdata() bufsize = inp[0]; inp += 1; \ memcpy(buffer, inp, bufsize); inp += bufsize; /****************************************************************************** * Helper function ******************************************************************************/ // If size is less than zero it is because of a error and we dont have to put any // data if size is returned in status. int tmffs_putdata(unsigned char **buf, unsigned char *src, int size) { unsigned char *p = *buf; if (size > 0) { *p++ = size; memcpy(p, src, size); *buf += 1 + size; } return size; } int tmffs_putstring(unsigned char **buf, char *src, int size) { unsigned char *p = *buf; if (size > 0) { *p++ = size; memcpy(p, src, size); *buf += 1 + size; } return size; } int tmffs_getstring(unsigned char ** buf, char *string) { unsigned char *p = *buf; stringsize = *p++; if (stringsize > TMFFS_STRING_SIZE) return EFFS_TOOBIG; memcpy(string, p, stringsize); *buf += 1 + stringsize; return stringsize; } /****************************************************************************** * tm_ffs ******************************************************************************/ // Parse input message and execute function. Then fill output buffer with // return values from the called function and transmit the message. Return // number of bytes inserted into output buffer. If return value is negative, // it represents an error code. int etm_ffs2(T_ETM_PKT *pkt, unsigned char *inp, int insize) { tmffs2_cid_t fid; unsigned char buffer[TMFFS_BUFFER_SIZE]; char string[TMFFS_STRING_SIZE]; unsigned char *outp_start; unsigned char *inp_start = inp; unsigned char *outp; int error = 0, i, fdi, size, param, flags; uint8 type; bufsize = stringsize = tmpsize = 0; tw(tr(TR_BEGIN, TrTmffs, "TmFFS2\n")); outp_start = outp = pkt->data; fid = *inp++; ttw(ttr(TTrTmffs, "etm_ffs2 0x%x" NL, fid)); switch(fid) { /********************************************************** * Generic Protocol Functions **********************************************************/ case TMFFS_VERSION: tmffs_put16(TMFFS2_VERSION); break; /********************************************************** * FFS Functions **********************************************************/ case TMFFS_PREFORMAT: param = tmffs_get16(); error = ffs_preformat(param); tw(tr(TR_FUNC, TrTmffs, "TMFFS_PREFORMAT(0x%x)\n", param)); ttw(ttr(TTrTmffs, "tm_pfmt" NL)); break; case TMFFS_FORMAT: error = tmffs_getstring(&inp, string); param = tmffs_get16(); if (error >= 0) error = ffs_format(&string[0], param); tw(tr(TR_FUNC, TrTmffs, "TMFFS_FORMAT(0x%x)\n", param)); ttw(ttr(TTrTmffs, "tm_fmt" NL)); break; case TMFFS_FILE_WRITE: error = tmffs_getstring(&inp, string); tmffs_getdata(); flags = tmffs_get8(); if (error >= 0) error = ffs_file_write(string, buffer, bufsize, flags); ttw(ttr(TTrTmffs, "tm_fwr" NL)); break; case TMFFS_FILE_READ: error = tmffs_getstring(&inp, string); bufsize = tmffs_get8(); if (error >= 0) size = ffs_file_read(string, buffer, bufsize); error = tmffs_putdata(&outp, &buffer[0], size); tw(tr(TR_FUNC, TrTmffs, "TMFFS_FREAD('%s', 0x%x, %d/0x%x)\n", string, buffer, bufsize, bufsize)); ttw(ttr(TTrTmffs, "tm_frd" NL)); break; case TMFFS_REMOVE: error = tmffs_getstring(&inp, string); if (error >= 0) error = ffs_remove(string); tw(tr(TR_FUNC, TrTmffs, "TMFFS_REMOVE()\n")); ttw(ttr(TTrTmffs, "tm_rm" NL)); break; case TMFFS_OPEN: error = tmffs_getstring(&inp, string); flags = tmffs_get8(); if (error >= 0) error = ffs_open(string, flags); tmffs_put8(error); // fdi tw(tr(TR_FUNC, TrTmffs, "TMFFS_OPEN('%s', %d)\n", string, flags)); ttw(ttr(TTrTmffs, "tm_open" NL)); break; case TMFFS_CLOSE: fdi = tmffs_get8(); error = ffs_close(fdi); tw(tr(TR_FUNC, TrTmffs, "TMFFS_CLOSE(%d)\n", fdi)); ttw(ttr(TTrTmffs, "tm_close" NL)); break; case TMFFS_WRITE: fdi = tmffs_get8(); tmffs_getdata(); error = ffs_write(fdi, buffer, bufsize); tmffs_put8(error); // put size tw(tr(TR_FUNC, TrTmffs, "TMFFS_WRITE(%d, %d)\n", fdi, bufsize)); ttw(ttr(TTrTmffs, "tm_write" NL)); break; case TMFFS_READ: fdi = tmffs_get8(); size = tmffs_get8(); size = ffs_read(fdi, &buffer[0], size); error = tmffs_putdata(&outp, &buffer[0], size); tw(tr(TR_FUNC, TrTmffs, "TMFFS_READ(%d, %d)\n", fdi, size)); ttw(ttr(TTrTmffs, "tm_read" NL)); break; case TMFFS_MKDIR: error = tmffs_getstring(&inp, string); if (error >= 0) error = ffs_mkdir(string); tw(tr(TR_FUNC, TrTmffs, "TMFFS_MKDIR()\n")); ttw(ttr(TTrTmffs, "tm_mkd" NL)); break; case TMFFS_OPENDIR: error = tmffs_getstring(&inp, string); if (error >= 0) { error = ffs_opendir(string, (struct dir_s *) buffer); tmffs_put8(error); // Note: we must put error/number of objects. } if (error >= 0) tmffs_putdata(&outp, buffer, sizeof(struct dir_s)); tw(tr(TR_FUNC, TrTmffs, "TMFFS_OPENDIR()\n")); ttw(ttr(TTrTmffs, "tm_od" NL)); break; case TMFFS_READDIR: tmffs_getdata(); stringsize = tmffs_get8(); error = ffs_readdir((struct dir_s *) buffer, string, stringsize); tmffs_put8(error); // Note: we have to return bytes read. if (error >= 0) { tmffs_putdata(&outp, buffer, sizeof(struct dir_s)); stringsize = strlen(string) + 1; tmffs_putstring(&outp, string, stringsize); } tw(tr(TR_FUNC, TrTmffs, "TMFFS_READDIR()\n")); ttw(ttr(TTrTmffs, "tm_rdd" NL)); break; case TMFFS_STAT: error = tmffs_getstring(&inp, string); if (error >= 0) error = ffs_stat(string, (struct stat_s *) buffer); if (error >= 0) tmffs_putdata(&outp, buffer, sizeof(struct stat_s)); tw(tr(TR_FUNC, TrTmffs, "TMFFS_STAT()\n")); ttw(ttr(TTrTmffs, "tm_st" NL)); break; case TMFFS_XLSTAT: error = tmffs_getstring(&inp, string); if (error >= 0) error = ffs_xlstat(&string[0], (struct xstat_s *) buffer); if (error >= 0) tmffs_putdata(&outp, buffer, sizeof(struct xstat_s)); tw(tr(TR_FUNC, TrTmffs, "TMFFS_()\n")); ttw(ttr(TTrTmffs, "tm_xlst" NL)); break; case TMFFS_SYMLINK: error = tmffs_getstring(&inp, string); tmffs_getdata(); if (error >= 0) error = ffs_symlink(string, (char *) buffer); tw(tr(TR_FUNC, TrTmffs, "TMFFS_SYMLINK()\n")); ttw(ttr(TTrTmffs, "tm_sym" NL)); break; case TMFFS_READLINK: error = tmffs_getstring(&inp, string); tmffs_getdata(); if (error >= 0) { size = ffs_readlink(string, (char *) buffer, TMFFS_BUFFER_SIZE); error = tmffs_putdata(&outp, buffer, size); // put link contents } tw(tr(TR_FUNC, TrTmffs, "TMFFS_READLINK()\n")); ttw(ttr(TTrTmffs, "tm_rdl" NL)); break; case TMFFS_QUERY: param = tmffs_get8(); error = ffs_query(param, buffer); if (error >= 0) tmffs_putdata(&outp, buffer, 16); tw(tr(TR_FUNC, TrTmffs, "TMFFS_QUERY(%d)\n", param)); ttw(ttr(TTrTmffs, "tm_q" NL)); break; case TMFFS_FCONTROL: error = tmffs_getstring(&inp, string); type = tmffs_get8(); param = tmffs_get32(); if (error >= 0) error = ffs_fcontrol(string, type, param); tw(tr(TR_FUNC, TrTmffs, "TMFFS_FCONTROL()\n")); ttw(ttr(TTrTmffs, "tm_fc" NL)); break; case TMFFS_TFFS: { #if (WITH_TFFS == 1) extern char ffs_test_string[]; // defined in task.c error = tmffs_getstring(&inp, string); memcpy(ffs_test_string, string, stringsize); tw(tr(TR_FUNC, TrTmffs, "TMFFS_TFFS()\n")); ttw(ttr(TTrTmffs, "tm_tffs" NL)); tmffs_put8(EFFS_OK); #else tmffs_put8(EFFS_NOSYS); #endif break; } default: error = EFFS_NOSYS; tmffs_put8(EFFS_NOSYS); tw(tr(TR_FUNC, TrTmffs, "ERROR: Unknown tmffs protocol code\n")); ttw(ttr(TTrTmffs, "tm?" NL)); break; } // check if we read beyond buffer end if (inp > inp_start + insize) { tw(tr(TR_FUNC, TrTmffs, "ERROR: Read beyond end of input buffer\n")); ttw(ttr(TTrTmffs, "tm_fatal" NL)); ttw(ttr(TTrTmffs, "insize: %d, diff: %d" NL, insize, inp - (inp_start + insize))); // NOTEME: We really should reset output buffer and put a return // code that tells us what went wrong! error = ETM_PACKET; // FIXME find another error } ttw(ttr(TTrTmffs, "error %d" NL, error)); if (error > 0) error = 0; pkt->mid = ETM_FFS2; pkt->size = outp - outp_start; pkt->status = -error; etm_pkt_send(pkt); etm_free(pkt); tw(tr(TR_END, TrTmffs, "")); return ETM_OK; } #endif // TMFFS2