[Tinyos-contrib-commits] CVS: tinyos-1.x/contrib/rincon/apps/Blackbook3/demos/BlackbookConnect blackbookconnect_readme.txt, NONE, 1.1 BlackbookConnectM.nc, NONE, 1.1 Makefile, NONE, 1.1 BlackbookConnectC.nc, NONE, 1.1 BlackbookConnect.h, NONE, 1.1 readme.txt, NONE, 1.1 memorystick_readme.txt, NONE, 1.1

dmm rincon at users.sourceforge.net
Thu Apr 20 16:03:34 PDT 2006


Update of /cvsroot/tinyos/tinyos-1.x/contrib/rincon/apps/Blackbook3/demos/BlackbookConnect
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16174/contrib/rincon/apps/Blackbook3/demos/BlackbookConnect

Added Files:
	blackbookconnect_readme.txt BlackbookConnectM.nc Makefile 
	BlackbookConnectC.nc BlackbookConnect.h readme.txt 
	memorystick_readme.txt 
Log Message:
Uploaded the Blackbook file system, version 3.

--- NEW FILE: blackbookconnect_readme.txt ---
BLACKBOOKCONNECT 
@author David Moss (dmm at rincon.com)

I aliased "blackbook" to "java com.rincon.blackbook.BlackbookConnect"

First, connect to the mote with SerialForwarder and
let's look at what's available in Blackbook:


$ blackbook
Not enough arguments!

Blackbook Usage:
com.rincon.blackbook.TestBlackbook [interface] -[command] <params>
_____________________________________
  BDictionary
        -open <filename> <minimum size>
        -close
        -insert <key> <value> <length>
        -retrieve <key>
        -remove <key>
        -getFirstKey
        -getNextKey <current key>

  BFileDelete
        -delete <filename>

  BFileDir
        -getTotalFiles
        -getTotalNodes
        -getFreeSpace
        -checkExists <filename>
        -readFirst
        -readNext <current filename>
        -getReservedLength <filename>
        -getDataLength <filename>
        -checkCorruption <filename>

  BFileRead
        -open <filename>
        -close
        -read <amount>
        -seek <address>
        -skip <amount>
        -getRemaining

  BFileWrite
        -open <filename>
        -close
        -save
        -append <written data>
        -getRemaining



BFILEWRITE INTERFACE
Let's open a file for writing with at least 0x1000 bytes (4096 bytes).
Blackbook will attempt to allocate the minimum requested size, but 
the actual writable size will extend to the next sector boundary. 
Because the sector lengths are 64k, that's what Blackbook allocates to
this file:

$ blackbook bfilewrite
Not enough arguments
  BFileWrite
        -open <filename>
        -close
        -save
        -append <written data>
        -getRemaining
        

$ blackbook BFileWrite -open testfile 0x1000
BFileWrite opened SUCCESS: testfile

65512 bytes


That 65512 bytes is a sector length (65535 bytes) minus the metadata overhead.
Now let's append some data:

$ blackbook bfilewrite -append writing_to_my_file
BFileWrite append SUCCESS: 18 bytes


You can save the file, and if a catastrophic failure occurs, the
data from the file will be recovered up to the point where you hit save:

$ blackbook bfilewrite -save
BFileWrite save SUCCESS


Closing the file does the same thing as save, so don't save and then
close because it wastes space in the checkpoint file.

We can find out how many bytes we have left to write:

$ blackbook bfilewrite -getremaining
65494 bytes available for writing

Note that at the same time, the BFileDir interface can also provide information
about the file you currently have open for writing.

Continue to append:

$ blackbook bfilewrite -append 1234567890
BFileWrite append SUCCESS: 10 bytes

Now let's close the file:

$ blackbook bfilewrite -close
Closed SUCCESS

You can have multiple files open for reading and writing at the same
time, but you can't have the same file open for reading and writing.
To access multiple files, you'll wire up your app to two or more
Blackbook parameterized interfaces.



BFILEDIR INTERFACE
$ blackbook bfiledir
Not enough arguments
  BFileDir
        -getTotalFiles
        -getTotalNodes
        -getFreeSpace
        -checkExists <filename>
        -readFirst
        -readNext <current filename>
        -getReservedLength <filename>
        -getDataLength <filename>
        -checkCorruption <filename>

The space allocated to hold file and node information in RAM
is configurable in the BlackbookConst.h file.  You can increase
or decrease the amount of files/nodes on your own.  By default, 
Blackbook provides 8 files with a minimum of 3 nodes each, for a total
of 24 nodes.   Nodes are the actual allocated spaces
in flash that hold information, and nodes cannot cross sector
bounds.  So for one large file, you may have 1 file containing
15 nodes on the flash.  RAM is the only constraint here.  Anyway....

Get the total files and nodes used by the file system:

$ blackbook bfiledir -gettotalfiles
2 total files

$ blackbook bfiledir -gettotalnodes
2 total nodes


Get the approximate free space on flash.  This is approximate because
sometimes deleted files already exist on flash that are taking up
space.. that space will get cleaned up by the garbage collector (BClean),
but it's not guaranteed. 

$ blackbook bfiledir -getfreespace
1045842 bytes available


Here's how you traverse the existing filenames on the file system.  First you
start off with the command readFirst, or just call readNext(NULL) in
your app, then call readNext with the current filename as the argument:

$ blackbook bfiledir -readFirst
BFileDir next file SUCCESS: chkpoint.bb_

$ blackbook bfiledir -readnext chkpoint.bb_
BFileDir next file SUCCESS: testfile

$ blackbook bfiledir -readnext testfile
BFileDir next file FAIL: No next file


So two files on our file system:  chkpoint.bb_ and testfile.
Let's check if the file we just wrote is corrupted:

$ blackbook bfiledir -checkcorruption testfile
BFileDir corruption check SUCCESS: File OK


We can check to see if files exist:

$ blackbook bfiledir -checkExists testfile
BFileDir exists check SUCCESS: File Exists

$ blackbook bfiledir -checkExists testfile1
BFileDir exists check SUCCESS: File does not exist


And we can find out stats on these files:
$ blackbook bfiledir -getDataLength testfile
28 bytes

$ blackbook bfiledir -getReservedLength testfile
232 bytes reserved

Notice when we first opened that 'testfile' binary file, we had
65512 bytes reserved.  Now it says the file has 232 bytes reserved for
writing data. That allows the file system to continue writing other 
nodes to the same sector that the testfile is located on if it wants to,
but if you open the testfile back up again for writing and there are no
other nodes on the sector, that node will reserve the whole 65512 bytes of the
sector again so you can write as much as you want in it.  Blackbook makes a 
good attempt to minimize the number of nodes on flash, which 
minimizes RAM consumption.



BFILEREAD INTERFACE
$ blackbook bfileread
Not enough arguments
  BFileRead
        -open <filename>
        -close
        -read <amount>
        -seek <address>
        -skip <amount>
        -getRemaining
        
        
First let's open our testfile. You can't open the chkpoint.bb_ file because
that file is in use by the file system.

$ blackbook bfileread -open testfile
BFileRead opened SUCCESS: testfile
        28 bytes
        

Read some data:
$ blackbook bfileread -read 18
BFileRead readDone SUCCESS: 18 bytes read

77 72 69 74 69 6E 67 5F   74 6F 5F 6D 79 5F 66 69   |  writing_  to_my_fil
6C 65                                               |   e


$ blackbook bfileread -read 18
BFileRead readDone SUCCESS: 10 bytes read

31 32 33 34 35 36 37 38   39 30                     |  12345678  90


$ blackbook bfileread -read 18
BFileRead readDone SUCCESS: 0 bytes read

                                                    |
                                                    

The BFileRead interface supports random read access.  Let's rewind
back to the beginning by seeking address 0:

$ blackbook bfileread -seek 0
Seek success

$ blackbook bfileread -skip 10
Skip success

$ blackbook bfileread -getRemaining
18 bytes remaining

$ blackbook bfileread -read 18
BFileRead readDone SUCCESS: 18 bytes read

5F 6D 79 5F 66 69 6C 65   31 32 33 34 35 36 37 38   |  _my_file  123456789
39 30                                               |   0


And that's that.  Now let's close the file:
$ blackbook bfileread -close
Closed SUCCESS



BFILEDELETE INTERFACE
There's really only one command to the BFileDelete interface, and
it should be pretty self-explanatory:

$ blackbook bfiledelete
Not enough arguments
  BFileDelete
        -delete <filename>


$ blackbook bfiledelete -delete testfile
BFileDelete delete SUCCESS



BDICTIONARY INTERFACE
$ blackbook BDictionary
Not enough arguments
  BDictionary
        -open <filename> <minimum size>
        -close
        -insert <key> <value> <length>
        -retrieve <key>
        -remove <key>
        -getFirstKey
        -getNextKey <current key>
        
The BDictionary interface provides a lot of cool new features for letting
your apps interact with the flash.  Let your imagination run.

First let's open a dictionary file and reserve 0x1000 (4096 bytes) for
entries.  I'll call the file 'myTest.dict'

Dictionary files are different than binary files, although 
they can be read with BFileRead like binary files (but the data won't mean
much to anything else other than the Dictionary interface).  If it's 
the first time you're opening the dictionary, the 0x1000 bytes will
be reserved. If the dictionary already exists, your request for a minimum
reserved length is ignored and the size used to create the file
is loaded.

$ blackbook bdictionary -open myTest.dict 0x1000
BDictionary opened SUCCESS: 4328 bytes


Notice how it doesn't reserve the whole sector compared to how
BFileWrite operates.  This allows you to have open dictionary files
that you're constantly interacting with and writing to open 
on the same sector as other files that are open for writing.

Now let's insert some key-values pairs.  Keys are size uint32_t.
Values can be any size, up to the end of the file.

Like AM types, keys are managed by the components and applications 
themselves. You could produce a hash function or generate a crc for 
a string to make the keys more natural, but you risk conflicting keys.  
Each time an old key is re-inserted, the old value is lost.  The 12 
at the end denotes my value "I_Like_Steak" is 12 bytes long.

$ blackbook bdictionary -insert 0xBEEF I_Like_Steak 12
BDictionary inserted SUCCESS: Key 0xBEEF Inserted

$ blackbook bdictionary -insert 0xBABE Sup? 4
BDictionary inserted SUCCESS: Key 0xBABE Inserted

Keep in mind Java doesn't support unsigned anything, so sometimes
you may get a 0xFFFFFFFF<yourkey>  from the Java CLI if your key is really big

We can find the keys that exist in this dictionary file.
Get the first key, and then use it as the argument to getNextKey, 
just like in BFileDir:

$ blackbook bdictionary -getFirstKey
BDictionary next key SUCCESS: Next Key is 0xBEEF

$ blackbook bdictionary -getnextkey 0xBEEF
BDictionary next key SUCCESS: Next Key is 0xBABE

$ blackbook bdictionary -getnextkey 0xBABE
BDictionary next key FAIL


We can retrieve the values from a given key:

$ blackbook bdictionary -retrieve 0xbeef
BDictionary retrieved SUCCESS
49 5F 4C 69 6B 65 5F 53   74 65 61 6B               |  I_Like_S  teak

$ blackbook bdictionary -retrieve 0xbabe
BDictionary retrieved SUCCESS
53 75 70 3F                                         |  Sup?


Keys that don't exist return fail in the retrieve event:
$ blackbook bdictionary -retrieve 0x0
BDictionary retrieved FAIL


Remove a key:
$ blackbook bdictionary -remove 0xbeef
BDictionary removed SUCCESS: Key 0xBEEF Removed

Update an existing key:
$ blackbook bdictionary -insert 0xbabe hello_again 11
BDictionary inserted SUCCESS: Key 0xBABE Inserted

$ blackbook bdictionary -retrieve 0xbabe
BDictionary retrieved SUCCESS
68 65 6C 6C 6F 5F 61 67   61 69 6E                  |  hello_ag  ain

$ blackbook bdictionary -close
Closed SUCCESS


You can keep inserting and updating keys indefinitely, and if your file
size runs out a new file will be created somewhere on flash with the
valid keys from the original.  The only time inserting keys should fail
is when you insert all unique, valid keys in a single file and fill
up all the reserved space to the point where even copying out the
valid keys to a new file won't free up any space.

This dictionary stuff can be very useful to applications.
The following code won't actually work, but the flow
will give you an idea of what you can do:

  // Here are some settings we want to keep on flash
  typedef struct mySettings {
    uint16_t securityLevel;
    uint32_t frameCount;
    bool radioSecurityEnabled;
    bool uartSecurityEnabled;
  } mySettings;

  ...
  
  mySettings securitySettings;
  
  ...
  
  // When blackbook is done booting:
  call BDictionary.open("Settings.sec", 0x500);
  // Load your settings from flash:
  call BDictionary.retrieve(0x53C, &securitySettings, sizeof(securitySettings));
  
  ...
  
  event void BDictionary.retrieved(...) {
    if(result) {
      // The settings were loaded correctly into
      // the securitySettings struct.  No casting or
      // anything to do
      
    } else {
      // Setup default settings, and save it to flash:
      securitySettings.securityLevel = 5;
      securitySettings.frameCount = 0;
      securitySettings.radioSecurityEnabled = TRUE;
      securitySettings.uartSecurityEnabled = FALSE;
      call BDictionary.insert(0x53C, &securitySettings, sizeof(securitySettings));
    }
  }
  

--- NEW FILE: BlackbookConnectM.nc ---
/*
 * Copyright (c) 2004-2006 Rincon Research Corporation.  
 * All rights reserved.
 * 
 * Rincon Research will permit distribution and use by others subject to
 * the restrictions of a licensing agreement which contains (among other things)
 * the following restrictions:
 * 
 *  1. No credit will be taken for the Work of others.
 *  2. It will not be resold for a price in excess of reproduction and 
 *      distribution costs.
 *  3. Others are not restricted from copying it or using it except as 
 *      set forward in the licensing agreement.
 *  4. Commented source code of any modifications or additions will be 
 *      made available to Rincon Research on the same terms.
 *  5. This notice will remain intact and displayed prominently.
 * 
 * Copies of the complete licensing agreement may be obtained by contacting 
 * Rincon Research, 101 N. Wilmot, Suite 101, Tucson, AZ 85711.
 * 
 * There is no warranty with this product, either expressed or implied.  
 * Use at your own risk.  Rincon Research is not liable or responsible for 
 * damage or loss incurred or resulting from the use or misuse of this software.
 */

/**
 * Test Blackbook
 * @author David Moss - dmm at rincon.com
 */
 

includes Blackbook;
includes BlackbookConnect;
 
module BlackbookConnectM {
  provides {
    interface StdControl;
  }
  
  uses {
    interface BBoot;
    interface BClean;
    interface BFileRead;
    interface BFileWrite;
    interface BFileDelete;
    interface BFileDir;
    interface BDictionary;
    interface Transceiver;
    interface Transceiver as NodeTransceiver;
    interface Transceiver as FileTransceiver;
    interface Transceiver as SectorTransceiver;
    interface NodeMap;
    interface SectorMap; 
    interface State;
    interface Leds;
  }
}

implementation {

  /** The communication method the last message was received */
  uint8_t receiveMethod;
  
  /** TOS Message to write */
  TOS_MsgPtr tosPtr;
  
  /** Message payload to send */
  BlackbookConnectMsg *outMsg;
  

  /** Receive methods */
  enum {
    RADIO,
    UART,
  };

  /** States */
  enum {
    S_IDLE = 0,
    S_BUSY,
  };
  
  /***************** Prototypes ****************/
  /** Process an incoming message */
  TOS_MsgPtr processMsg(TOS_MsgPtr m);
  
  /** Make a new message */
  result_t newMessage();
  
  /** Send the message */
  void sendMsg();
  
  /***************** StdControl Commands ****************/
  command result_t StdControl.init() {
    call Leds.init(); 
    return SUCCESS;
  }
  
  command result_t StdControl.start() {
    call Leds.redOn();
    return SUCCESS;
  }
  
  command result_t StdControl.stop() {
    return SUCCESS;
  }
  
  /***************** Transceiver Events ****************/
  /**
   * A message was sent over radio.
   * @param m - a pointer to the sent message, valid for the duration of the 
   *     event.
   * @param result - SUCCESS or FAIL.
   */
  event result_t Transceiver.radioSendDone(TOS_MsgPtr m, result_t result) {
    return SUCCESS; 
  }
  
  /**
   * A message was sent over UART.
   * @param m - a pointer to the sent message, valid for the duration of the 
   *     event.
   * @param result - SUCCESS or FAIL.
   */
  event result_t Transceiver.uartSendDone(TOS_MsgPtr m, result_t result) {
    return SUCCESS; 
  }
  
  /**
   * Received a message over the radio
   * @param m - the receive message, valid for the duration of the 
   *     event.
   */
  event TOS_MsgPtr Transceiver.receiveRadio(TOS_MsgPtr m) {
    receiveMethod = RADIO;
    return processMsg(m);
  }
  
  /**
   * Received a message over UART
   * @param m - the receive message, valid for the duration of the 
   *     event.
   */
  event TOS_MsgPtr Transceiver.receiveUart(TOS_MsgPtr m) {
    receiveMethod = UART;
    return processMsg(m);
  }
  
  
  /***************** NodeTransceiver ****************/
  /**
   * Received a message over UART
   * @param m - the receive message, valid for the duration of the 
   *     event.
   */
  event TOS_MsgPtr NodeTransceiver.receiveUart(TOS_MsgPtr m) {
    TOS_MsgPtr nodeTosPtr;
    BlackbookNodeMsg *nodeOutMsg;
    BlackbookNodeMsg *inMsg = (BlackbookNodeMsg *) m->data;
    
    if((nodeTosPtr = call NodeTransceiver.requestWrite()) != NULL) {
      nodeOutMsg = (BlackbookNodeMsg *) nodeTosPtr->data;
      memcpy(&nodeOutMsg->focusedNode, call NodeMap.getNodeAtIndex(inMsg->focusedNode.fileElement), sizeof(node));
      call NodeTransceiver.sendUart(sizeof(BlackbookNodeMsg));
    }
    return m;
  }
  
  /**
   * A message was sent over radio.
   * @param m - a pointer to the sent message, valid for the duration of the 
   *     event.
   * @param result - SUCCESS or FAIL.
   */
  event result_t NodeTransceiver.radioSendDone(TOS_MsgPtr m, result_t result) {
    return SUCCESS; 
  }
  
  /**
   * A message was sent over UART.
   * @param m - a pointer to the sent message, valid for the duration of the 
   *     event.
   * @param result - SUCCESS or FAIL.
   */
  event result_t NodeTransceiver.uartSendDone(TOS_MsgPtr m, result_t result) {
    return SUCCESS; 
  }
  
  /**
   * Received a message over the radio
   * @param m - the receive message, valid for the duration of the 
   *     event.
   */
  event TOS_MsgPtr NodeTransceiver.receiveRadio(TOS_MsgPtr m) {
    return m;
  }
  

  
  /***************** File Transceiver *****************/
   /**
   * Received a message over UART
   * @param m - the receive message, valid for the duration of the 
   *     event.
   */
  event TOS_MsgPtr FileTransceiver.receiveUart(TOS_MsgPtr m) {
    TOS_MsgPtr fileTosPtr;
    BlackbookFileMsg *fileOutMsg;
    BlackbookFileMsg *inMsg = (BlackbookFileMsg *) m->data;
    
    if((fileTosPtr = call FileTransceiver.requestWrite()) != NULL) {
      fileOutMsg = (BlackbookFileMsg *) fileTosPtr->data;
      memcpy(&fileOutMsg->focusedFile, call NodeMap.getFileAtIndex(inMsg->focusedFile.type), sizeof(file));
      call FileTransceiver.sendUart(sizeof(BlackbookFileMsg));
    }
    return m;
  }
  
 
  /**
   * A message was sent over radio.
   * @param m - a pointer to the sent message, valid for the duration of the 
   *     event.
   * @param result - SUCCESS or FAIL.
   */
  event result_t FileTransceiver.radioSendDone(TOS_MsgPtr m, result_t result) {
    return SUCCESS; 
  }
  
  /**
   * A message was sent over UART.
   * @param m - a pointer to the sent message, valid for the duration of the 
   *     event.
   * @param result - SUCCESS or FAIL.
   */
  event result_t FileTransceiver.uartSendDone(TOS_MsgPtr m, result_t result) {
    return SUCCESS; 
  }
  
  /**
   * Received a message over the radio
   * @param m - the receive message, valid for the duration of the 
   *     event.
   */
  event TOS_MsgPtr FileTransceiver.receiveRadio(TOS_MsgPtr m) {
    return m;
  }
  

  
  /***************** Sector Transceiver ****************/  
  /**
   * Received a message over UART
   * @param m - the receive message, valid for the duration of the 
   *     event.
   */
  event TOS_MsgPtr SectorTransceiver.receiveUart(TOS_MsgPtr m) {
    TOS_MsgPtr sectorTosPtr;
    BlackbookSectorMsg *sectorOutMsg;
    BlackbookSectorMsg *inMsg = (BlackbookSectorMsg *) m->data;
    
    if((sectorTosPtr = call SectorTransceiver.requestWrite()) != NULL) {
      sectorOutMsg = (BlackbookSectorMsg *) sectorTosPtr->data;
      memcpy(&sectorOutMsg->focusedSector, call SectorMap.getSectorAtVolume(inMsg->focusedSector.index), sizeof(flashsector));
      call SectorTransceiver.sendUart(sizeof(BlackbookSectorMsg));
    }
    return m;
  }
  
  /**
   * A message was sent over radio.
   * @param m - a pointer to the sent message, valid for the duration of the 
   *     event.
   * @param result - SUCCESS or FAIL.
   */
  event result_t SectorTransceiver.radioSendDone(TOS_MsgPtr m, result_t result) {
    return SUCCESS; 
  }
  
  /**
   * A message was sent over UART.
   * @param m - a pointer to the sent message, valid for the duration of the 
   *     event.
   * @param result - SUCCESS or FAIL.
   */
  event result_t SectorTransceiver.uartSendDone(TOS_MsgPtr m, result_t result) {
    return SUCCESS; 
  }
  
  /**
   * Received a message over the radio
   * @param m - the receive message, valid for the duration of the 
   *     event.
   */
  event TOS_MsgPtr SectorTransceiver.receiveRadio(TOS_MsgPtr m) {
    return m;
  }

  
  /***************** BBoot Events ****************/
  /**
   * The file system finished booting
   * @param totalNodes - the total number of nodes found on flash
   * @param result - SUCCESS if the file system is ready for use.
   */
  event void BBoot.booted(uint16_t totalNodes, uint8_t totalFiles, result_t result) {
    call Leds.redOff();
    call Leds.yellowOn();
    
    if(newMessage()) {
      outMsg->cmd = REPLY_BOOT;
      outMsg->length = totalNodes;
      outMsg->data[0] = totalFiles;
      outMsg->result = result;
      sendMsg();
    }
  }
  
  
  /***************** BClean Events ****************/
  /**
   * The Garbage Collector is erasing a sector - this may take awhile
   */
  event void BClean.erasing() {
    call Leds.yellowOff();
    
    if(newMessage()) {
      outMsg->cmd = REPLY_BCLEAN_ERASING;
      sendMsg();
    }
  }
  
  /**
   * Garbage Collection is complete
   * @return SUCCESS if any sectors were erased.
   */
  event void BClean.gcDone(result_t result) {
    call Leds.yellowOn();
    
    if(newMessage()) {
      outMsg->cmd = REPLY_BCLEAN_DONE;
      outMsg->result = result;
      sendMsg();
    }
  }
  
  /***************** BFileRead Events ****************/
  /**
   * A file has been opened
   * @param fileName - name of the opened file
   * @param len - the total data length of the file
   * @param result - SUCCESS if the file was successfully opened
   */
  event void BFileRead.opened(char *fileName, uint32_t amount, result_t result) {
    memcpy(outMsg->data, fileName, sizeof(filename));
    outMsg->length = amount;
    outMsg->result = result;
    outMsg->cmd = REPLY_BFILEREAD_OPEN;
    sendMsg();
  }

  /**
   * Any previously opened file is now closed
   * @param result - SUCCESS if the file was closed properly
   */
  event void BFileRead.closed(result_t result) {
    outMsg->result = result;
    outMsg->cmd = REPLY_BFILEREAD_CLOSE;
    sendMsg();
  }

  /**
   * File read complete
   * @param *buf - this is the buffer that was initially passed in
   * @param len - the length of the data read into the buffer
   * @param result - SUCCESS if there were no problems reading the data
   */
  event void BFileRead.readDone(char *fileName, void *buf, uint16_t len, result_t result) {
    // data is already setup
    outMsg->length = len;
    outMsg->result = result;
    outMsg->cmd = REPLY_BFILEREAD_READ;
    sendMsg();
  }
  
  
  /***************** BFileWrite Events ****************/
  /**
   * Signaled when a file has been opened, with the results
   * @param fileName - the name of the opened write file
   * @param len - The total reserved length of the file
   * @param result - SUCCSES if the file was opened successfully
   */
  event void BFileWrite.opened(char *fileName, uint32_t len, result_t result) {
    memcpy(outMsg->data, fileName, sizeof(filename));
    outMsg->length = len;
    outMsg->result = result;
    outMsg->cmd = REPLY_BFILEWRITE_OPEN;
    sendMsg();
  }

  /** 
   * Signaled when the opened file has been closed
   * @param result - SUCCESS if the file was closed properly
   */
  event void BFileWrite.closed(result_t result) {
    outMsg->result = result;
    outMsg->cmd = REPLY_BFILEWRITE_CLOSE;
    sendMsg();
  }

  /**
   * Signaled when this file has been saved.
   * This does not require the save() command to be called
   * before being signaled - this would happen if another
   * file was open for writing and that file was saved, but
   * the behavior of the checkpoint file required all files
   * on the system to be saved as well.
   * @param fileName - name of the open write file that was saved
   * @param result - SUCCESS if the file was saved successfully
   */
  event void BFileWrite.saved(char *fileName, result_t result) {
    outMsg->result = result;
    outMsg->cmd = REPLY_BFILEWRITE_SAVE;
    sendMsg();
    
  }

  /**
   * Signaled when data is written to flash. On some media,
   * the data is not guaranteed to be written to non-volatile memory
   * until save() or close() is called.
   * @param fileName
   * @param data The buffer of data appended to flash
   * @param amountWritten The amount written to flash
   * @param result
   */
  event void BFileWrite.appended(char *fileName, void *data, uint16_t amountWritten, result_t result) {
    outMsg->length = amountWritten;
    outMsg->result = result;
    outMsg->cmd = REPLY_BFILEWRITE_APPEND;
    sendMsg();
  }
  
  
  /***************** BFileDelete Events ****************/
  /**
   * A file was deleted
   * @param result - SUCCESS if the file was deleted from flash
   */
  event void BFileDelete.deleted(result_t result) {
    outMsg->result = result;
    outMsg->cmd = REPLY_BFILEDELETE_DELETE;
    sendMsg();
  }
  
  
  /***************** BFileDir Events ****************/
  /**
   * The corruption check on a file is complete
   * @param fileName - the name of the file that was checked
   * @param isCorrupt - TRUE if the file's actual data does not match its CRC
   * @param result - SUCCESS if this information is valid.
   */
  event void BFileDir.corruptionCheckDone(char *fileName, bool isCorrupt, result_t result) {
    outMsg->result = result;
    outMsg->length = isCorrupt;
    outMsg->cmd = REPLY_BFILEDIR_CHECKCORRUPTION;
    sendMsg();
  }

  /**
   * The check to see if a file exists is complete
   * @param fileName - the name of the file
   * @param doesExist - TRUE if the file exists
   * @param result - SUCCESS if this information is valid
   */
  event void BFileDir.existsCheckDone(char *fileName, bool doesExist, result_t result) {
    outMsg->result = result;
    outMsg->length = doesExist;
    outMsg->cmd = REPLY_BFILEDIR_EXISTS;
    sendMsg();
  }
  
  
  /**
   * This is the next file in the file system after the given
   * present file.
   * @param fileName - name of the next file
   * @param result - SUCCESS if this is actually the next file, 
   *     FAIL if the given present file is not valid or there is no
   *     next file.
   */  
  event void BFileDir.nextFile(char *fileName, result_t result) {
    memcpy(outMsg->data, fileName, sizeof(filename));
    outMsg->result = result;
    outMsg->cmd = REPLY_BFILEDIR_READNEXT;
    sendMsg();
  }
    
  
  /***************** BDictionary Events ****************/
  /**
   * A Dictionary file was opened successfully.
   * @param totalSize - the total amount of flash space dedicated to storing
   *     key-value pairs in the file
   * @param remainingBytes - the remaining amount of space left to write to
   * @param result - SUCCESS if the file was successfully opened.
   */
  event void BDictionary.opened(uint16_t totalSize, uint16_t remainingBytes, result_t result) {
    outMsg->length = totalSize;
    outMsg->result = result;
    outMsg->cmd = REPLY_BDICTIONARY_OPEN;
    sendMsg();
  }
  
  /** 
   * The opened Dictionary file is now closed
   * @param result - SUCCSESS if there are no open files
   */
  event void BDictionary.closed(result_t result) {
    outMsg->result = result;
    outMsg->cmd = REPLY_BDICTIONARY_CLOSE;
    sendMsg();
  }
  
  /**
   * A key-value pair was inserted into the currently opened Dictionary file.
   * @param key - the key used to insert the value
   * @param value - pointer to the buffer containing the value.
   * @param valueSize - the amount of bytes copied from the buffer into flash
   * @param result - SUCCESS if the key was written successfully.
   */
  event void BDictionary.inserted(uint32_t key, void *value, uint16_t valueSize, result_t result) {
    outMsg->result = result;
    outMsg->length = key;
    outMsg->cmd = REPLY_BDICTIONARY_INSERT;
    sendMsg();
  }
  
  /**
   * A value was retrieved from the given key.
   * @param key - the key used to find the value
   * @param valueHolder - pointer to the buffer where the value was stored
   * @param valueSize - the actual size of the value.
   * @param result - SUCCESS if the value was pulled out and is uncorrupted
   */
  event void BDictionary.retrieved(uint32_t key, void *valueHolder, uint16_t valueSize, result_t result) {
    outMsg->result = result;
    outMsg->length = valueSize;
    outMsg->cmd = REPLY_BDICTIONARY_RETRIEVE;
    sendMsg();
  }
  
  /**
   * A key-value pair was removed
   * @param key - the key that should no longer exist
   * @param result - SUCCESS if the key was really removed
   */
  event void BDictionary.removed(uint32_t key, result_t result) {
    outMsg->result = result;
    outMsg->length = key;
    outMsg->cmd = REPLY_BDICTIONARY_REMOVE;
    sendMsg();
  }
  
  /**
   * The next key in the open Dictionary file
   * @param nextKey - the next key
   * @param result - SUCCESS if this is the really the next key,
   *     FAIL if the presentKey was invalid or there is no next key.
   */
  event void BDictionary.nextKey(uint32_t nextKey, result_t result) {
    outMsg->result = result;
    outMsg->length = nextKey;
    outMsg->cmd = REPLY_BDICTIONARY_NEXTKEY;
    sendMsg();
  }
  
  
  /***************** Functions ****************/
  /**
   * Process the incoming message
   */
  TOS_MsgPtr processMsg(TOS_MsgPtr m) {
    BlackbookConnectMsg *inMsg = (BlackbookConnectMsg *) m->data;
    
    if(!call State.requestState(S_BUSY)) {
      return m;
    }
    
    if(!newMessage()) {
      return m;
    }
    
    switch(inMsg->cmd) {
    
      /** BFileWrite Commands */
      case CMD_BFILEWRITE_OPEN:
        if(!call BFileWrite.open((char *) inMsg->data, inMsg->length)) {
          outMsg->cmd = ERROR_BFILEWRITE_OPEN;
          sendMsg();
        }
        break;
      
      case CMD_BFILEWRITE_CLOSE:
        if(!call BFileWrite.close()) {
          outMsg->cmd = ERROR_BFILEWRITE_CLOSE;
          sendMsg();
        }
        break;
        
      case CMD_BFILEWRITE_APPEND:
        if(!call BFileWrite.append(inMsg->data, inMsg->length)) {
          outMsg->cmd = ERROR_BFILEWRITE_APPEND;
          sendMsg();
        }
        break;
        
      case CMD_BFILEWRITE_SAVE:
        if(!call BFileWrite.save()) {
          outMsg->cmd = ERROR_BFILEWRITE_SAVE;
          sendMsg();
        }
        break;
        
      case CMD_BFILEWRITE_REMAINING:
        outMsg->length = call BFileWrite.getRemaining();
        outMsg->cmd = REPLY_BFILEWRITE_REMAINING;
        sendMsg();
        break;
  
  
      /** BFileRead Commands */
      case CMD_BFILEREAD_OPEN:
        if(!call BFileRead.open((char *) inMsg->data)) {
          outMsg->cmd = ERROR_BFILEREAD_OPEN;
          sendMsg();
        }
        break;
        
      case CMD_BFILEREAD_CLOSE:
        if(!call BFileRead.close()) {
          outMsg->cmd = ERROR_BFILEREAD_CLOSE;
          sendMsg();
        }
        break;
        
      case CMD_BFILEREAD_READ:
        if(inMsg->length > sizeof(outMsg->data)) {
          inMsg->length = sizeof(outMsg->data);
        }
        
        if(!call BFileRead.read(outMsg->data, inMsg->length)) {
          outMsg->cmd = ERROR_BFILEREAD_READ;
          sendMsg();
        }
        break;
        
      case CMD_BFILEREAD_SEEK:
        if(!call BFileRead.seek(inMsg->length)) {
          outMsg->cmd = ERROR_BFILEREAD_SEEK;
          sendMsg();
        } else {
          outMsg->cmd = REPLY_BFILEREAD_SEEK;
          outMsg->result = SUCCESS;
          sendMsg();
        }
        break;
        
      case CMD_BFILEREAD_SKIP:
        if(!call BFileRead.skip(inMsg->length)) {
          outMsg->cmd = ERROR_BFILEREAD_SKIP;
          sendMsg();
        } else { 
          outMsg->cmd = REPLY_BFILEREAD_SKIP;
          outMsg->result = SUCCESS;
          sendMsg();
        }
        break;
        
      case CMD_BFILEREAD_REMAINING:
        outMsg->length = call BFileRead.getRemaining();
        outMsg->cmd = REPLY_BFILEREAD_REMAINING;
        sendMsg();
        break;
  
  
      /** BFileDelete Commands */
      case CMD_BFILEDELETE_DELETE:
        if(!call BFileDelete.delete((char *) inMsg->data)) {
          outMsg->cmd = ERROR_BFILEDELETE_DELETE;
          sendMsg();
        }
        break;
        
        
      /** BFileDir Commands */
      case CMD_BFILEDIR_TOTALFILES:
        outMsg->length = call BFileDir.getTotalFiles();
        outMsg->cmd = REPLY_BFILEDIR_TOTALFILES;
        sendMsg();
        break;
        
      case CMD_BFILEDIR_TOTALNODES:
        outMsg->length = call BFileDir.getTotalNodes();
        outMsg->cmd = REPLY_BFILEDIR_TOTALNODES;
        sendMsg();
        break;
        
      case CMD_BFILEDIR_GETFREESPACE:
        outMsg->length = call BFileDir.getFreeSpace();
        outMsg->cmd = REPLY_BFILEDIR_GETFREESPACE;
        sendMsg();
        break;
        
      case CMD_BFILEDIR_EXISTS:
        if(!call BFileDir.checkExists((char *) inMsg->data)) {
          outMsg->cmd = ERROR_BFILEDIR_EXISTS;
          sendMsg();
        }
        break;
        
      case CMD_BFILEDIR_READNEXT:
        if(!call BFileDir.readNext((char *) inMsg->data)) {
          outMsg->cmd = ERROR_BFILEDIR_READNEXT;
          sendMsg();
        }
        break;
       
      case CMD_BFILEDIR_READFIRST:
        if(!call BFileDir.readFirst()) {
          outMsg->cmd = ERROR_BFILEDIR_READFIRST;
          sendMsg();
        }
        break;
 
      case CMD_BFILEDIR_RESERVEDLENGTH:
        outMsg->length = call BFileDir.getReservedLength((char *) inMsg->data);
        outMsg->cmd = REPLY_BFILEDIR_RESERVEDLENGTH;
        sendMsg();
        break;
        
      case CMD_BFILEDIR_DATALENGTH:
        outMsg->length = call BFileDir.getDataLength((char *) inMsg->data);
        outMsg->cmd = REPLY_BFILEDIR_DATALENGTH;
        sendMsg();
        break;
        
      case CMD_BFILEDIR_CHECKCORRUPTION:
        if(!call BFileDir.checkCorruption((char *) inMsg->data)) {
          outMsg->cmd = ERROR_BFILEDIR_CHECKCORRUPTION;
          sendMsg();
        }
        break;
        
        
      /** BDicitonary Commands */
      case CMD_BDICTIONARY_OPEN:
        if(!call BDictionary.open((char *) inMsg->data, inMsg->length)) {
          outMsg->cmd = ERROR_BDICTIONARY_OPEN;
          sendMsg();
        }
        break;
        
      case CMD_BDICTIONARY_CLOSE:
        if(!call BDictionary.close()) {
          outMsg->cmd = ERROR_BDICTIONARY_CLOSE;
          sendMsg();
        }
        break;
        
      case CMD_BDICTIONARY_INSERT:
        // length = key
        // data = value
        // result = valueSize
        if(!call BDictionary.insert(inMsg->length, inMsg->data, inMsg->result)) {
          outMsg->cmd = ERROR_BDICTIONARY_INSERT;
          sendMsg();
        }
        break;
        
      case CMD_BDICTIONARY_RETRIEVE:
        if(!call BDictionary.retrieve(inMsg->length, outMsg->data, sizeof(outMsg->data))) {
          outMsg->cmd = ERROR_BDICTIONARY_RETRIEVE;
          sendMsg();
        }
        break;
        
      case CMD_BDICTIONARY_REMOVE:
        if(!call BDictionary.remove(inMsg->length)) {
          outMsg->cmd = ERROR_BDICTIONARY_REMOVE;
          sendMsg();
        }
        break;
      
      case CMD_BDICTIONARY_NEXTKEY:
        if(!call BDictionary.getNextKey(inMsg->length)) {
          outMsg->cmd = ERROR_BDICTIONARY_NEXTKEY;
          sendMsg();
        }
        break;
        
      case CMD_BDICTIONARY_FIRSTKEY:
        if(!call BDictionary.getFirstKey()) {
          outMsg->cmd = ERROR_BDICTIONARY_FIRSTKEY;
          sendMsg();
        }
        break;
       

      default:    
    }
    
    return m;
  }
  
  /**
   * Create a new message
   */
  result_t newMessage() {
    if((tosPtr = call Transceiver.requestWrite()) != NULL) {
      outMsg = (BlackbookConnectMsg *) tosPtr->data;
      memset(outMsg->data, 0, sizeof(outMsg->data));
      return SUCCESS;
    }
    return FAIL;
  }
 
  /** 
   * Send the message
   */
  void sendMsg() {
    call State.toIdle();
    if(receiveMethod == RADIO) {
      call Transceiver.sendRadio(TOS_BCAST_ADDR, sizeof(BlackbookConnectMsg));
    } else {
      call Transceiver.sendUart(sizeof(BlackbookConnectMsg));
    }
  }
}



--- NEW FILE: Makefile ---
COMPONENT=BlackbookConnectC

# Choose one:
#CFLAGS += -I../../implementation/AT45DB
CFLAGS += -I../../implementation/STM25P

CFLAGS += -I../FlashBridgeViewer
CFLAGS +=  -I../../ -I../../interfaces -I../../implementation

CFLAGS += -I../../../../tos/lib/State -I../../../../tos/lib/Transceiver -I../../../../tos/lib/JDebug

include $(TOSROOT)/apps/Makerules




--- NEW FILE: BlackbookConnectC.nc ---
/*
 * Copyright (c) 2004-2006 Rincon Research Corporation.  
 * All rights reserved.
 * 
 * Rincon Research will permit distribution and use by others subject to
 * the restrictions of a licensing agreement which contains (among other things)
 * the following restrictions:
 * 
 *  1. No credit will be taken for the Work of others.
 *  2. It will not be resold for a price in excess of reproduction and 
 *      distribution costs.
 *  3. Others are not restricted from copying it or using it except as 
 *      set forward in the licensing agreement.
 *  4. Commented source code of any modifications or additions will be 
 *      made available to Rincon Research on the same terms.
 *  5. This notice will remain intact and displayed prominently.
 * 
 * Copies of the complete licensing agreement may be obtained by contacting 
 * Rincon Research, 101 N. Wilmot, Suite 101, Tucson, AZ 85711.
 * 
 * There is no warranty with this product, either expressed or implied.  
 * Use at your own risk.  Rincon Research is not liable or responsible for 
 * damage or loss incurred or resulting from the use or misuse of this software.
 */

/**
 * BlackbookConnect Module
 * This interacts with the com.rincon.blackbook.BlackbookConnect
 * program to provide direct access to the Blackbook interfaces
 * from your desktop.
 * 
 * You can also use com.rincon.blackbook.memorystick.MemoryStick
 * to upload/download files on your computer to flash.
 *
 * @author David Moss - dmm at rincon.com
 */

includes Blackbook;
includes BlackbookConnect;

configuration BlackbookConnectC {
}

implementation {
  components Main, BlackbookConnectM, BlackbookC, FlashBridgeViewerC, StateC, TransceiverC, LedsC;
  components NodeMapC, SectorMapC;
  
  Main.StdControl -> BlackbookConnectM;
  Main.StdControl -> BlackbookC;
  Main.StdControl -> FlashBridgeViewerC;
  Main.StdControl -> TransceiverC;
  Main.StdControl -> StateC;
  
  BlackbookConnectM.Transceiver -> TransceiverC.Transceiver[AM_BLACKBOOKCONNECTMSG];
  BlackbookConnectM.NodeTransceiver -> TransceiverC.Transceiver[AM_BLACKBOOKNODEMSG];
  BlackbookConnectM.FileTransceiver -> TransceiverC.Transceiver[AM_BLACKBOOKFILEMSG];
  BlackbookConnectM.SectorTransceiver -> TransceiverC.Transceiver[AM_BLACKBOOKSECTORMSG];
  BlackbookConnectM.State -> StateC.State[unique("State")];
  BlackbookConnectM.Leds -> LedsC;
  
  // This stuff is for debugging purposes.
  BlackbookConnectM.NodeMap -> NodeMapC;
  BlackbookConnectM.SectorMap -> SectorMapC;

  // These are all the actual Blackbook interfaces you can wire up to your app.
  BlackbookConnectM.BBoot -> BlackbookC;
  BlackbookConnectM.BClean -> BlackbookC;
  BlackbookConnectM.BFileRead -> BlackbookC.BFileRead[unique("BFileRead")];
  BlackbookConnectM.BFileWrite -> BlackbookC.BFileWrite[unique("BFileWrite")];
  BlackbookConnectM.BFileDelete -> BlackbookC.BFileDelete[unique("BFileDelete")];
  BlackbookConnectM.BFileDir -> BlackbookC.BFileDir[unique("BFileDir")];
  BlackbookConnectM.BDictionary -> BlackbookC.BDictionary[unique("BDictionary")];
  

}

--- NEW FILE: BlackbookConnect.h ---
/*
 * Copyright (c) 2004-2006 Rincon Research Corporation.  
 * All rights reserved.
 * 
 * Rincon Research will permit distribution and use by others subject to
 * the restrictions of a licensing agreement which contains (among other things)
 * the following restrictions:
 * 
 *  1. No credit will be taken for the Work of others.
 *  2. It will not be resold for a price in excess of reproduction and 
 *      distribution costs.
 *  3. Others are not restricted from copying it or using it except as 
 *      set forward in the licensing agreement.
 *  4. Commented source code of any modifications or additions will be 
 *      made available to Rincon Research on the same terms.
 *  5. This notice will remain intact and displayed prominently.
 * 
 * Copies of the complete licensing agreement may be obtained by contacting 
 * Rincon Research, 101 N. Wilmot, Suite 101, Tucson, AZ 85711.
 * 
 * There is no warranty with this product, either expressed or implied.  
 * Use at your own risk.  Rincon Research is not liable or responsible for 
 * damage or loss incurred or resulting from the use or misuse of this software.
 */


#include "AM.h"

typedef struct BlackbookConnectMsg {
  uint32_t length;
  uint8_t cmd;
  uint8_t result;
  uint8_t data[TOSH_DATA_LENGTH - 6];
} BlackbookConnectMsg;

typedef struct BlackbookNodeMsg {
  struct node focusedNode;
} BlackbookNodeMsg;

typedef struct BlackbookFileMsg {
  struct file focusedFile;
} BlackbookFileMsg;

typedef struct BlackbookSectorMsg {
  struct flashsector focusedSector;
} BlackbookSectorMsg;

enum {
  AM_BLACKBOOKCONNECTMSG = 0xBB,
  AM_BLACKBOOKNODEMSG = 0xBC,
  AM_BLACKBOOKFILEMSG = 0xBD,
  AM_BLACKBOOKSECTORMSG = 0xBE,
};



enum {
  CMD_BFILEWRITE_OPEN = 0,
  CMD_BFILEWRITE_CLOSE = 1,
  CMD_BFILEWRITE_APPEND = 2,
  CMD_BFILEWRITE_SAVE = 3,
  CMD_BFILEWRITE_REMAINING = 4,
  
  CMD_BFILEREAD_OPEN = 10,
  CMD_BFILEREAD_CLOSE = 11,
  CMD_BFILEREAD_READ = 12,
  CMD_BFILEREAD_SEEK = 13,
  CMD_BFILEREAD_SKIP = 14,
  CMD_BFILEREAD_REMAINING = 15,
  
  CMD_BFILEDELETE_DELETE = 20,
  
  CMD_BFILEDIR_TOTALFILES = 30,
  CMD_BFILEDIR_TOTALNODES = 31,
  CMD_BFILEDIR_EXISTS = 32,
  CMD_BFILEDIR_READNEXT = 33,
  CMD_BFILEDIR_RESERVEDLENGTH = 34,
  CMD_BFILEDIR_DATALENGTH = 35,
  CMD_BFILEDIR_CHECKCORRUPTION = 36,
  CMD_BFILEDIR_READFIRST = 37,
  CMD_BFILEDIR_GETFREESPACE = 38,
 
  CMD_BDICTIONARY_OPEN = 40,
  CMD_BDICTIONARY_CLOSE = 41,
  CMD_BDICTIONARY_INSERT = 42,
  CMD_BDICTIONARY_RETRIEVE = 43,
  CMD_BDICTIONARY_REMOVE = 44, 
  CMD_BDICTIONARY_NEXTKEY = 45,
  CMD_BDICTIONARY_FIRSTKEY = 46,
  
  
  ERROR_BFILEWRITE_OPEN = 100,
  ERROR_BFILEWRITE_CLOSE = 101,
  ERROR_BFILEWRITE_APPEND = 102,
  ERROR_BFILEWRITE_SAVE = 103,
  ERROR_BFILEWRITE_REMAINING = 104,
  
  ERROR_BFILEREAD_OPEN = 110,
  ERROR_BFILEREAD_CLOSE = 111,
  ERROR_BFILEREAD_READ = 112,
  ERROR_BFILEREAD_SEEK = 113,
  ERROR_BFILEREAD_SKIP = 114,
  ERROR_BFILEREAD_REMAINING = 115,
  
  ERROR_BFILEDELETE_DELETE = 120,
  
  ERROR_BFILEDIR_TOTALFILES = 130,
  ERROR_BFILEDIR_TOTALNODES = 131,
  ERROR_BFILEDIR_EXISTS = 132,
  ERROR_BFILEDIR_READNEXT = 133,
  ERROR_BFILEDIR_RESERVEDLENGTH = 134,
  ERROR_BFILEDIR_DATALENGTH = 135,
  ERROR_BFILEDIR_CHECKCORRUPTION = 136,
  ERROR_BFILEDIR_READFIRST = 137,
  ERROR_BFILEDIR_GETFREESPACE = 138,
    
  ERROR_BDICTIONARY_OPEN = 140,
  ERROR_BDICTIONARY_CLOSE = 141,
  ERROR_BDICTIONARY_INSERT = 142,
  ERROR_BDICTIONARY_RETRIEVE = 143,
  ERROR_BDICTIONARY_REMOVE = 144,
  ERROR_BDICTIONARY_NEXTKEY = 145,
  ERROR_BDICTIONARY_FIRSTKEY = 146,
   
  REPLY_BFILEWRITE_OPEN = 200,
  REPLY_BFILEWRITE_CLOSE = 201,
  REPLY_BFILEWRITE_APPEND = 202,
  REPLY_BFILEWRITE_SAVE = 203,
  REPLY_BFILEWRITE_REMAINING = 204,
  
  REPLY_BFILEREAD_OPEN = 210,
  REPLY_BFILEREAD_CLOSE = 211,
  REPLY_BFILEREAD_READ = 212,
  REPLY_BFILEREAD_SEEK = 213,
  REPLY_BFILEREAD_SKIP = 214,
  REPLY_BFILEREAD_REMAINING = 215,
  
  REPLY_BFILEDELETE_DELETE = 220,
  
  REPLY_BFILEDIR_TOTALFILES = 230,
  REPLY_BFILEDIR_TOTALNODES = 231,
  REPLY_BFILEDIR_EXISTS = 232,
  REPLY_BFILEDIR_READNEXT = 233,
  REPLY_BFILEDIR_RESERVEDLENGTH = 234,
  REPLY_BFILEDIR_DATALENGTH = 235,
  REPLY_BFILEDIR_CHECKCORRUPTION = 236,
  REPLY_BFILEDIR_GETFREESPACE = 238,
  
  REPLY_BDICTIONARY_OPEN = 240,
  REPLY_BDICTIONARY_CLOSE = 241,
  REPLY_BDICTIONARY_INSERT = 242,
  REPLY_BDICTIONARY_RETRIEVE = 243,
  REPLY_BDICTIONARY_REMOVE = 244,
  REPLY_BDICTIONARY_NEXTKEY = 245,
  REPLY_BDICTIONARY_FIRSTKEY = 246,
  
  REPLY_BOOT = 250,
  REPLY_BCLEAN_ERASING = 251,
  REPLY_BCLEAN_DONE = 252,
};


--- NEW FILE: readme.txt ---
BlackbookConnect

This is the application I used to debug Blackbook, but it does
everything you want it to.  You can use it
to see exactly how Blackbook works and what it does.  It essentially
takes all the interfaces to Blackbook and makes them available
to you on the computer, so you can run commands from the computer
to the mote, just as if you were part of the mote itself.  The 
Java interfaces in the com.rincon.blackbook directory
are just like the interfaces you'd see on the mote itself.

When BlackbookConnect is compiled to the mote, a green LED means
the FlashBridgeViewer is running, and a yellow/blue LED means
the BlackbookConnect stuff is running. You'll see the yellow/blue
LED go off when a sector is being erased.

There are 3 basic chunks of functionality provided by BlackbookConnect:

1. Execute all commands and receive all events from all interfaces
   provided by Blackbook on the computer.
   
2. View the status of all nodes, sectors, and file structs inside
   Blackbook. This is useful mostly for debugging or to fill your
   curiosity.
   
3. View the contents of the flash through the FlashBridgeViewer interface
   to see what Blackbook is doing under the hood.
   
Two Java applications work with BlackbookConnect to show off the features.
You'll need to copy the com.rincon.<whatever> directories into your own 
tinyos-1.x/tools/java directory.  These apps will interact
with BlackbookConnect:

com.rincon.blackbook.BlackbookConnect
com.rincon.blackbook.memorystick.MemoryStick
com.rincon.blackbook.printstatus.PrintFile
com.rincon.blackbook.printstatus.PrintNode
com.rincon.blackbook.printstatus.PrintSector
com.rincon.flashbridgeviewer.FlashViewer


Read the "blackbookconnect_readme.txt" for information 
and a walk through of all the stuff you can do with the Blackbook
interfaces from your desktop.

Read the "memorystick_readme.txt" for information and a walk
through of all the stuff you can do with the MemoryStick application


Shoot me some feedback on how this stuff works out for you.  Enjoy...

@author David Moss (dmm at rincon.com)


_____________________________________________________________________
com.rincon.blackbook.BlackbookConnect






--- NEW FILE: memorystick_readme.txt ---

MEMORYSTICK
@author David Moss (dmm at rincon.com)

Make sure your serial forwarder is enabled and BlackbookConnect is installed
on the mote before using the Java MemoryStick program.

I alias "memorystick" to "java com.rincon.blackbook.memorystick.MemoryStick"

$ memorystick
Not enough arguments
  MemoryStick
        -get [filename on mote] [as <filename on computer>]
        -put [filename on computer] [as <filename on mote>]
        -dir
        -delete [filename on mote]
        -isCorrupt [filename on mote]
        -freeSpace
        
        
$ memorystick -dir
2 total files:
        myTest.dict
        chkpoint.bb_


$ memorystick -delete myTest.dict
File deleted on mote.


$ memorystick -put BlackbookConnectM.nc
Writing BlackbookConn (25140 bytes)
  [##################################################] 100%

25140 bytes written to BlackbookConnectM.nc


$ memorystick -dir
2 total files:
        BlackbookConn
        chkpoint.bb_


$ memorystick -get BlackbookConn as DownloadedFile.txt
Getting BlackbookConn  (25140 bytes)
  [##################################################] 100%

25140 bytes read into C:\TinyOS\cygwin\opt\tinyos-1.1.15\contrib\Rincon\Apps\Bla
ckbook3\demos\BlackbookConnect\DownloadedFile.txt


$ diff DownloadedFile.txt BlackbookConnectM.nc

$ memorystick -isCorrupt BlackbookConn
Please wait, this could take awhile for large files...
File is OK on flash!

$ memorystick -freeSpace
950364 bytes available

$ memorystick -delete BlackbookConn
File deleted on mote.

$ memorystick -freeSpace
925020 bytes available

Remember, free space is approximate. The file size went down because the 
BlackbookConn file was finalized and deleted on flash, but
if we really needed more bytes than 925020, the garbage collector
would just allocate it.  Your data doesn't get erased until
the garbage collector says it should get erased.





More information about the Tinyos-contrib-commits mailing list