---
name: "ifp.h"
section: "3"
platform: "linux"
package: "libifp-dev"
version: "1.0.0.2-5+b2"
release: "Debian 10 (Buster)"
platforms: ["linux"]
url: "https://new.carta.tech/ifp.h"
---

# ifp.h(3)

## NAME

ifp.h -

## Detailed Description

An interface for iRiver's flash-based portable music players.

**Author:**

Copyright (C) Geoff Oakham, 2004; \<oakhamg@users.sourceforge.net\>

Calling Conventions (unless otherwise stated):

- •

  integer return value 0 indicates success, error otherwise

- •

  argument 'dev' is a device handle

- •

  argument 'f' is the full path to a remote file or directory. (eg. '\\foo\\bar.mp3')

- •

  argument 'b' is a buffer for returning data

- •

  remote pathnames use '\\' instead of '/' for separating directories (eg '\\classical\\mozart\\magicflute.ogg')

- •

  functions that return numerical values (eg. **ifp\_freespace**) return negative values on error

## SYNOPSIS

### Setup and initialization

int **ifp\_init** (struct **ifp\_device** \*dev, void \*dev\_handle)\
 *Initializes device.*  int **ifp\_finalize** (struct **ifp\_device** \*dev)\
 *Releases device. Releases any resources aquired by* **ifp\_init***. Basically, when* **ifp\_init** *returns 0 (success),* **ifp\_finalize** *must be called after you're finished with dev.*  void \* **ifp\_find\_device** (void)\
 *Scans the system and returns the first compatible iFP device.*  int **ifp\_release\_device** (void \*)\
 *Releases device handle allocated by* **ifp\_find\_device***.*  int **ifp\_selftest** (struct **ifp\_device** \*dev)\
 *Tests communications with the device.*  int **ifp\_format** (struct **ifp\_device** \*dev)\
 *Reformats the device's storage media.*  int **ifp\_update\_firmware** (struct **ifp\_device** \*dev, const char \*localfile, **ifp\_progress** fn, void \*context)\
 *Upgrades the firmware.*

### Device status

int **ifp\_device\_info** (struct **ifp\_device** \*dev, char \*b, int n)\
 *Creates a human readable status string.*  int **ifp\_battery** (struct **ifp\_device** \*dev)\
 *Reports the battery's status on the scale from 0 to 4.*  int **ifp\_capacity** (struct **ifp\_device** \*dev)\
 *Reports the device's capacity in bytes.*  int **ifp\_freespace** (struct **ifp\_device** \*dev)\
 *Reports the device's available free space in bytes.*  int **ifp\_model** (struct **ifp\_device** \*dev, char \*b, int n)\
 *Reads in the device's model number into 's'.*  int **ifp\_delta** (struct **ifp\_device** \*dev, int \*values)\
 *(experimental) retrieves a mystery value.*  int **ifp\_firmware\_version** (struct **ifp\_device** \*dev)\
 *Reads the device's firmware version. The firmware version is returned in raw BCD. For human consumption, I suggest:.*  const char \* **ifp\_error\_message** (int n)\
 *Return an English string describing an error number.*

### Metadata

int **ifp\_rename** (struct **ifp\_device** \*dev, const char \*old\_path, const char \*new\_path)\
 *Renames a file or directory.*  int **ifp\_delete** (struct **ifp\_device** \*dev, const char \*f)\
 *Delete the file f.*  int **ifp\_mkdir** (struct **ifp\_device** \*dev, const char \*f)\
 *Creates a new directory, f.*  int **ifp\_rmdir** (struct **ifp\_device** \*dev, const char \*f)\
 *Deletes the directory f.*  int **ifp\_list\_dirs** (struct **ifp\_device** \*dev, const char \*dirname, int(\*callbk)(void \*, int, const char \*, int), void \*context)\
 *Reads directory contents.*  int **ifp\_treewalk\_open** (struct **ifp\_device** \*dev, const char \*directory, void \*\*handle)\
 *Recursively walk a remote directory. (Interface similar to 'fts.h'.).*  int **ifp\_treewalk\_close** (void \*tws\_p)\
 *Releases the resources used in a treewalk.*  **ifp\_treewalk\_entry** \* **ifp\_treewalk\_next** (void \*tws\_p)\
 *Returns the next file or directory in a treewalk.*

### Reading files

int **ifp\_read\_open** (struct **ifp\_device** \*dev, const char \*f)\
 *Opens the file f for reading.*  int **ifp\_read\_close** (struct **ifp\_device** \*dev)\
 *Closes a file open for reading.*  int **ifp\_read\_seek** (struct **ifp\_device** \*dev, int abs\_position)\
 *Fast-forward within the current file.*  int **ifp\_read\_data** (struct **ifp\_device** \*dev, void \*b, int bytes)\
 *Reads from an open file. Reads the next 'bytes' of data into 'buff'.*  int **ifp\_read\_eof** (struct **ifp\_device** \*dev)\
 *Check if we've reached the end of the file. (EOF).*  int **ifp\_read\_size** (struct **ifp\_device** \*dev)\
 *Returns the size of the current file in bytes.*

### Creating files

int **ifp\_write\_open** (struct **ifp\_device** \*dev, const char \*f, int fsize)\
 *Opens the file f for writing.*  int **ifp\_write\_close** (struct **ifp\_device** \*dev)\
 *Closes a file open for writing.*  int **ifp\_write\_data** (struct **ifp\_device** \*dev, void \*b, int bytes)\
 *Writes 'bytes' of data from buff to the file.*

### Bulk file transfers (userland only)

int **ifp\_read\_file\_progress** (struct **ifp\_device** \*dev, FILE \*dst, const char \*f, int(\*progress)(void \*, int), void \*context)\
 *Downloads a file; includes a hook for a progress metre.*  int **ifp\_write\_file\_progress** (struct **ifp\_device** \*dev, FILE \*src, int filesize, const char \*f, int(\*progress)(void \*, int), void \*context)\
 *Uploads a file; includes a hook for a progress metre. Creates a new file 'f' on the device and populates it with data from 'src'. Filesize is the number of bytes to be uploaded from 'src'.*  static int **ifp\_read\_file** (struct **ifp\_device** \*dev, FILE \*dst, const char \*f)\
 *Reads the file 'f' into dst.*  static int **ifp\_write\_file** (struct **ifp\_device** \*dev, FILE \*src, int filesize, const char \*f)\
 *Creates a new file 'f' from src.*  int **ifp\_download\_file** (struct **ifp\_device** \*dev, const char \*remotefile, const char \*localfile, **ifp\_progress** fn, void \*fn\_context)\
 *Downloads 'remotefile' and saves it directly on the filesystem as 'localfile'.*  int **ifp\_upload\_file** (struct **ifp\_device** \*dev, const char \*localfile, const char \*remotefile, **ifp\_progress** fn, void \*fn\_context)\
 *Uploads 'localfile' from the filesystem onto the device as 'remotefile'.*  int **ifp\_delete\_dir\_recursive** (struct **ifp\_device** \*dev, const char \*f)\
 *Deletes the directory 'f', its files and subdirectories. (Think of 'rm -Rf'.).*  int **ifp\_download\_dir** (struct **ifp\_device** \*dev, const char \*remotedir, const char \*localdir, **ifp\_progress** fn, void \*fn\_context)\
 *Downloads the contents of 'remotedir' (including all subdirectories) and saves it as 'localdir'.*  int **ifp\_upload\_dir** (struct **ifp\_device** \*dev, const char \*localdir, const char \*remotedir, **ifp\_progress** fn, void \*fn\_context)\
 *Uploads the contents of 'localdir' (including all subdirectories) to the device as 'remotedir'.*

### Boolean tests

int **ifp\_is\_file** (struct **ifp\_device** \*dev, const char \*f)\
 *Tests if f is a file.*  int **ifp\_is\_dir** (struct **ifp\_device** \*dev, const char \*f)\
 *Tests if f is a directory.*  int **ifp\_exists** (struct **ifp\_device** \*dev, const char \*f)\
 *Tests for the existance of f.*

### FM Tuner preset station manipulation

int **ifp\_get\_tuner\_presets** (struct **ifp\_device** \*dev, void \*data, int n)\
 *Retrieves the tuner preset file into 'data'.*  int **ifp\_set\_tuner\_presets** (struct **ifp\_device** \*dev, void \*data, int n)\
 *Stores the tuner preset file 'data' on the device.*  int **ifp\_get\_station** (int n, void \*b, char \*callsign, int \*freq)\
 *Reads station #n from the binary datablock into more useful forms.*  int **ifp\_set\_station** (int n, void \*data, const char \*callsign, int freq)\
 *Sets station #n to 'freq' and 'callsign'.*

### Defines

\#define **IFP\_1XX**   0x1001\
 \#define **IFP\_3XX**   0x1003\
 \#define **IFP\_5XX**   0x1005\
 \#define **IFP\_7XX**   0x1007\
 \#define **IFP\_8XX**   0x1008\
 \#define **IFP\_9XX**   0x1008\
 \#define **IFP\_N10**   0x1011\
 \#define **IFP\_FILE**   1\
 \#define **IFP\_DIR**   2\
 \#define **IFP\_ERR\_DEV\_FUBAR**   8\
 \#define **IFP\_ERR\_BAD\_FREQUENCY**   9\
 \#define **IFP\_ERR\_BAD\_FILENAME**   10\
 \#define **IFP\_ERR\_USER\_CANCEL**   11\
 \#define **IFP\_TUNER\_PRESET\_DATA**   240\
 \#define **IFP\_FREQ\_MIN**   8750\
 \#define **IFP\_FREQ\_MAX**   10800\
 \#define **IFP\_PRESET\_TOTAL**   20\
 \#define **IFP\_TUNER\_LABEL**   6\

### Typedefs

typedef int(\* **ifp\_progress** )(void \*, struct **ifp\_transfer\_status** \*)\
 *Callback for implementing a progress metre.*

### Enumerations

enum { **IFP\_WALK\_FILE** =  IFP\_FILE, **IFP\_WALK\_DIR\_PRE** =  IFP\_DIR, **IFP\_WALK\_DIR\_POST**, **IFP\_WALK\_NONE** }\
 *File types for treewalking.*

## Define Documentation

### #define IFP\_1XX 0x1001

Model number for iFP-100 series

### #define IFP\_3XX 0x1003

Model number for iFP-300 series

### #define IFP\_5XX 0x1005

Model number for iFP-500 series

### #define IFP\_7XX 0x1007

Model number for iFP-700 series

### #define IFP\_8XX 0x1008

Model number for iFP-800 series

### #define IFP\_9XX 0x1008

Model number for iFP-900 series

### #define IFP\_N10 0x1011

Model number for N10

### #define IFP\_FILE 1

File 'type'.

### #define IFP\_DIR 2

Dir 'type'.

### #define IFP\_ERR\_DEV\_FUBAR 8

device not responding; try jiggling handle

### #define IFP\_ERR\_BAD\_FREQUENCY 9

tuner frequency out of range

### #define IFP\_ERR\_BAD\_FILENAME 10

filename is invalid. Likely causes are unsupported characters, or a filename that's too long (more than ::IFP\_MAXFILENAMELEN chars).

note: linux's fatfs returns EINVAL instead. Should we switch?

### #define IFP\_ERR\_USER\_CANCEL 11

A user callback requested the transfer be cancelled.

### #define IFP\_TUNER\_PRESET\_DATA 240

Tuner preset buffer size.

### #define IFP\_FREQ\_MIN 8750

lowist valid frequency (87.5kHz)

### #define IFP\_FREQ\_MAX 10800

highist valid frequency (108.0kHz)

### #define IFP\_PRESET\_TOTAL 20

number of preset stations.

### #define IFP\_TUNER\_LABEL 6

max size of label string.

## Typedef Documentation

### typedef int(\* ifp\_progress)(void \*, struct ifp\_transfer\_status \*)

Callback for implementing a progress metre.

If provided, this function is typically called several times during a file transfer to give GUI applications a chance provide user feedback.

This function should return 0 for 'success' or 1 to request the transfer be cancelled when possible. (The request might be ignored.) Other values are considered 'error values'.

The first parameter is whatever if you passed to the main function as 'context'. You may use this for anything you like or leave it NULL.

The second parameter is a pointer to information about the transfer in progress. The only value guaranteed to be valid for \_all\_ transfers is file\_bytes. Which values \*are\* valid should be obvious from context. To be on the safe side, please guard against NULL pointers and divide-by -zero errors. (The structure itself won't be NULL. I promise.)

## Enumeration Type Documentation

### anonymous enum

File types for treewalking.

**Enumeration values:**

- *IFP\_WALK\_FILE*

  *file*

- *IFP\_WALK\_DIR\_PRE*

  *directory, before visiting its children*

- *IFP\_WALK\_DIR\_POST*

  *directory, after visiting its children*

- *IFP\_WALK\_NONE*

  *none of the above*

## Function Documentation

### int ifp\_init (struct ifp\_device \* dev, void \* device\_handle)

*Initializes device.*

*Initialzies and tests the device for use with device\_handle. (***ifp\_finalize** *should be called when you're finished with 'dev'.)*

**Parameters:**

*dev Unitialized memory ready for use as an* **ifp\_device***.* \
 *device\_handle The iFP USB hardware device handle.*

**Returns:**

**IFP\_ERR\_DEV\_FUBAR** *if the self-test failed. (Ask the user to jiggle the handle.)*

*0 on success.*

**Examples:**  **simple.c***.*

### void\* ifp\_find\_device (void)

*Scans the system and returns the first compatible iFP device.*

*If no device is found, NULL is returned. The handle must be released with* **ifp\_release\_device***.*

**Examples:**  **simple.c***.*

### int ifp\_selftest (struct ifp\_device \* dev)

*Tests communications with the device.*

*This is done automatically on startup by* **ifp\_init***, so normal shouldn't need to call this.. unless they really want to.*

### int ifp\_format (struct ifp\_device \* dev)

*Reformats the device's storage media.*

*(Deletes all your stuff.) Returns 0 on success, 1 on error. This function hasn't been tested--please report if you've successfully used it.*

### int ifp\_update\_firmware (struct ifp\_device \* dev, const char \* localfile, ifp\_progress fn, void \* fn\_context)

*Upgrades the firmware.*

*This is much like a file upload, except: the filename on the local disk must be in the format 'IFP-?XXT.HEX', 'IFP-1XXTC.HEX' or 'N10.HEX'. The progress meter only tracks the firmware upload. The flash-upgrading itself and reboot take extra time we can't predict.*

*Immediately after calling ifp\_update\_firmware, the caller should release 'dev', and wait a healthy ammount of time (10 or more seconds) before trying to reconnect. During this time, you'll see the message 'upgrading firmware please don't touch' on the device, after which the device will shutdown: user will likely have to turn it back on themselves.*

*I welcome suggestions and/or code on how to help monitor the device status during a firmware upgrade.*

### int ifp\_device\_info (struct ifp\_device \* dev, char \* s, int n)

*Creates a human readable status string.*

*Creates a human readable status string similar to 'model IFP-007T, firmware 1.14, battery =\[####\], delta 1.8.4.42'.*

**Examples:**  **simple.c***.*

### int ifp\_battery (struct ifp\_device \* dev)

*Reports the battery's status on the scale from 0 to 4.*

*Typical values are 4, 0 and occasionally 2.*

### int ifp\_model (struct ifp\_device \* dev, char \* s, int size)

*Reads in the device's model number into 's'.*

*('size' is the size of the buffer s points to.) Typical results look like 'IFP-590T'.*

### int ifp\_delta (struct ifp\_device \* dev, int \* values)

*(experimental) retrieves a mystery value.*

*I've coined this mystery value 'Delta' until a better name is chosen.*

**Parameters:**

*values an empty int\[4\] for the output values.*

*Integers returned in 'values' are my interpretation of the data. The actual raw data has been varried widely:*

```
 0108 0312 ffff ffff
 0108 0415 ffff ffff
 0108 0616 ffff ffff
 0108 0417 0000 0000
 0108 0418 ffff ffff
```

*Two devices returned 4 bytes instead of 8.*

### int ifp\_firmware\_version (struct ifp\_device \* dev)

*Reads the device's firmware version. The firmware version is returned in raw BCD. For human consumption, I suggest:.*

```
      sprintf(s, '%x.%02x', r/0x0100, r%0x100)
```

### const char\* ifp\_error\_message (int n)

*Return an English string describing an error number.*

*(Available only in userland.)*

### int ifp\_rename (struct ifp\_device \* dev, const char \* old\_path, const char \* new\_path)

*Renames a file or directory.*

*Renames or moves the object 'old\_path' to 'new\_path'.*

**Parameters:**

*old\_path an existing file or directory.* \
 *new\_path an available path for a new file or directory. (Ie, the path's parent directory exists and the path isn't in use by another object in that directory.)*

*Returns 0 on success and -ENOENT, -EEXIST, -EACCES, IFP\_ERR\_BAD\_FILENAME on failure, as appropriate.*

### int ifp\_delete (struct ifp\_device \* dev, const char \* f)

*Delete the file f.*

*Returns -ENOENT if f doesn't exist.*

### int ifp\_mkdir (struct ifp\_device \* dev, const char \* f)

*Creates a new directory, f.*

*Returns -ENOENT if f's parent doesn't exist, -EEXISTS the dirname 'f' is allready in use, and IFP\_ERR\_BAD\_FILENAME if 'f' contains unsupported characters.*

### int ifp\_rmdir (struct ifp\_device \* dev, const char \* d)

*Deletes the directory f.*

*Returns 0 on success or: -ENOENT -ENOTEMPTY -EACCES*

### int ifp\_list\_dirs (struct ifp\_device \* dev, const char \* filename, int(\*)(void \*, int, const char \*, int) callbk, void \* context)

*Reads directory contents.*

*Passes the contents of 'dirname' to a callback function, one entry at a time. The parameters given to the callback function are:*

- •

  *void \* context is the same context passed to list\_dirs*

- •

  *int type is either* **IFP\_FILE** *or* **IFP\_DIR**

- •

  *char \* name is the entry name without a full path. (Ie, no '\\' chars)*

- •

  *int filesize is the number of bytes in a file (undefied for directories)*

*The callback can return '0' on success, '1' to 'break' (leave early without error) or \<0 on error.*

*Returns 0 on success or -ENOENT if the directory doesn't exist.*

**Examples:**  **simple.c***.*

### struct int ifp\_treewalk\_open (struct ifp\_device \* dev, const char \* directory, void \*\* handle)

*Recursively walk a remote directory. (Interface similar to 'fts.h'.).*

*Start a treewalk for the 'directory' on the device. The handle for this session is placed at \*handle; this handle is freed by calling* **ifp\_treewalk\_close***.*

 *'dev' won't be left in a 'special state' after calling treewalk-family functions. Likewise, please don't leave dev in a 'special state' before calling* **ifp\_treewalk\_open** *or* **ifp\_treewalk\_next***.*

*Returns -ENOENT if the directory doesn't exist.*

### int ifp\_treewalk\_close (void \* tws\_p)

*Releases the resources used in a treewalk.*

*Must be called after each successful call of* **ifp\_treewalk\_open***.*

### struct ifp\_treewalk\_entry\* ifp\_treewalk\_next (void \* tws\_p)

*Returns the next file or directory in a treewalk.*

*The structure returned is valid until the next* **ifp\_treewalk\_next** *or* **ifp\_treewalk\_close** *function call. See* **ifp\_treewalk\_entry** *for details about the fields.*

*Likewise, please don't leave 'dev' in a 'special state' before calling* **ifp\_treewalk\_next***.*

*NULL is returned after the last entry.*

### int ifp\_read\_open (struct ifp\_device \* dev, const char \* f)

*Opens the file f for reading.*

*Returns -ENOENT if 'f' doesn't exist and -EACCES if 'f' is read-protected by the device.*

### int ifp\_read\_seek (struct ifp\_device \* dev, int bytes)

*Fast-forward within the current file.*

*In the current open file, skip forward to 'bytes' (ignoring the data). Caution: the implementation isn't particularily fast, and can only seek forward. Avoid it if you can.*

### int ifp\_read\_data (struct ifp\_device \* dev, void \* buff, int bytes)

*Reads from an open file. Reads the next 'bytes' of data into 'buff'.*

**Returns:**

*the number of bytes read, or \<0 on error.*

### int ifp\_write\_open (struct ifp\_device \* dev, const char \* f, int filesize)

*Opens the file f for writing.*

*Creates and opens a new file of 'filesize' bytes with the name 'f'. Returns -EEXIST if the name 'f' isn't available. (Ie, if there allready exists a file or directory with the same name.) Returns -ENOENT, -ENOSPC, or IFP\_ERR\_BAD\_FILENAME*

### int ifp\_write\_data (struct ifp\_device \* dev, void \* buff, int bytes)

*Writes 'bytes' of data from buff to the file.*

*Returns 0 on success. (Does not return the number of bytes written--it's all or nothing.)*

### int ifp\_read\_file\_progress (struct ifp\_device \* dev, FILE \* dst, const char \* f, int(\*)(void \*, int) fn, void \* fn\_context)

*Downloads a file; includes a hook for a progress metre.*

*Reads the file 'f' from the device and saves it in 'dst'.*

**Parameters:**

*f name of the remote file we're downloading* \
 *dst where the data will be saved* \
 *progress Optional. If given, this function will be called occationally so an application can update a progress metre. (For example.)* \
 *context Context for the progress metre. (Safe to leave NULL.)*

*(Available only in userland.)*

*Returns -ENOENT if 'f' doesn't exist; -EACCES if 'f' is read-protected by the device; -ENOSPC; and* **IFP\_ERR\_USER\_CANCEL** *if the callback requested the transfer cancelled.*

*(Available only in userland.)*

### int ifp\_write\_file\_progress (struct ifp\_device \* dev, FILE \* src, int filesize, const char \* f, int(\*)(void \*, int) fn, void \* fn\_context)

*Uploads a file; includes a hook for a progress metre. Creates a new file 'f' on the device and populates it with data from 'src'. Filesize is the number of bytes to be uploaded from 'src'.*

*(Note: it appears the device might not need to know the number of bytes in a file ahead time. The current implementation doesn't support this, but if you don't have access to the filesize ahead of time, you might be able to hack libifp to let you do it anyways.)*

**Parameters:**

*src data to be uploaded* \
 *filesize number of bytes to copy from src* \
 *f name of the file to be created* \
 *progress Optional. If given, this function will be called occationally so an application can update its progress metre.* \
 *context Context for the progress metre. (Safe to leave NULL.)*

*Returns -EEXIST, -ENOENT, -ENOSPC,* **IFP\_ERR\_BAD\_FILENAME***,* **IFP\_ERR\_USER\_CANCEL**

*(Available only in userland.)*

### struct int ifp\_download\_file (struct ifp\_device \* dev, const char \* remotefile, const char \* localfile, ifp\_progress fn, void \* fn\_context)

*Downloads 'remotefile' and saves it directly on the filesystem as 'localfile'.*

*The progress callback function 'fn' and its context pointer are optional. See* **ifp\_progress** *and* **ifp\_transfer\_status** *for more information.*

*Returns -ENOENT, -EACCES, -ENOSPC and* **IFP\_ERR\_USER\_CANCEL** *(Available only in userland.)*

*Note: There is currently a 'EPIPE' bug in the wild that is relatively rare but causes file corruption during download. ifp\_download\_file and ifp\_download\_dir detect and recover from it automatically, but you might see the progress numbers 'jump backwards' occasionally.*

### int ifp\_upload\_file (struct ifp\_device \* dev, const char \* localfile, const char \* remotefile, ifp\_progress fn, void \* fn\_context)

*Uploads 'localfile' from the filesystem onto the device as 'remotefile'.*

*The progress callback function 'fn' and its context pointer are optional. See* **ifp\_progress** *and* **ifp\_transfer\_status** *for more information.*

*Returns -EEXIST, -ENOENT, -ENOSPC,* **IFP\_ERR\_BAD\_FILENAME***,* **IFP\_ERR\_USER\_CANCEL** *(Available only in userland.)*

### int ifp\_delete\_dir\_recursive (struct ifp\_device \* dev, const char \* f)

*Deletes the directory 'f', its files and subdirectories. (Think of 'rm -Rf'.).*

*Will return -ENOENT if 'f' doesn't exist or isn't a directory.*

*(Available only in userland, at this time.)*

### int ifp\_download\_dir (struct ifp\_device \* dev, const char \* remotedir, const char \* localdir, ifp\_progress fn, void \* fn\_context)

*Downloads the contents of 'remotedir' (including all subdirectories) and saves it as 'localdir'.*

*Note that 'localdir' must not allready exist. Example: suppose localdir was '/tmp/tunes/tame' and remotedir was '\\classical\\junk'. The directory '/tmp/tunes/tame' will be created and the file '\\classical\\junk\\buz\\fud.ogg' will be copied as '/tmp/tunes/tame/buz/fud.ogg'*

*The progress callback function 'fn' and its context pointer are optional. See* **ifp\_progress** *and* **ifp\_transfer\_status** *for more information.*

*Returns -ENOENT, -EACCES, -ENOSPC* **IFP\_ERR\_USER\_CANCEL**

*(Available only in userland.)*

*Note: There is currently a 'EPIPE' bug in the wild that is relatively rare but causes file corruption during download. ifp\_download\_file and ifp\_download\_dir detect and recover from it automatically, but you might see the progress numbers 'jump backwards' occasionally.*

### int ifp\_upload\_dir (struct ifp\_device \* dev, const char \* localdir, const char \* remotedir, ifp\_progress fn, void \* fn\_context)

*Uploads the contents of 'localdir' (including all subdirectories) to the device as 'remotedir'.*

*Note that 'remotedir' must not exist on the remote device. Example: suppose localdir was '/tmp/tunes/tame' and remotedir was '\\classical\\junk'. The directory '\\classical\\junk' will be created and the file '/tmp/tunes/tame/buz/fud.ogg' will be copied as '\\classical\\junk\\buz\\fud.ogg'.*

*The progress callback function 'fn' and its context pointer are optional. See* **ifp\_progress** *and* **ifp\_transfer\_status** *for more information.*

*Returns -EEXIST, -ENOENT, -ENOSPC,* **IFP\_ERR\_BAD\_FILENAME***, or* **IFP\_ERR\_USER\_CANCEL***. FIXME: handle invalid filenames from local filesystem with more grace*

*(Available only in userland.)*

### int ifp\_is\_file (struct ifp\_device \* dev, const char \* f)

*Tests if f is a file.*

*Returns 1 if it is, and 0 if it doesn't exist or isn't a file.*

### int ifp\_is\_dir (struct ifp\_device \* dev, const char \* f)

*Tests if f is a directory.*

*Returns 1 if it is, and 0 if it doesn't exist or isn't a dir.*

### int ifp\_exists (struct ifp\_device \* dev, const char \* f)

*Tests for the existance of f.*

**Returns:**

**IFP\_FILE** *if f is a file*

**IFP\_DIR** *if f is a directory*

*0 if f doesn't exist*

*\<0 error.*

### int ifp\_get\_tuner\_presets (struct ifp\_device \* dev, void \* data, int n)

*Retrieves the tuner preset file into 'data'.*

 *'data' is a buffer of 'n' bytes.. n must be at least* **IFP\_TUNER\_PRESET\_DATA** *bytes.*

### int ifp\_set\_tuner\_presets (struct ifp\_device \* dev, void \* data, int n)

*Stores the tuner preset file 'data' on the device.*

 *'data' is tuner preset file to be stored.. it is extactly* **IFP\_TUNER\_PRESET\_DATA** *bytes. 'n' must be exactly* **IFP\_TUNER\_PRESET\_DATA**

### int ifp\_get\_station (int n, void \* b, char \* callsign, int \* freq)

*Reads station #n from the binary datablock into more useful forms.*

*b is the block of data loaded using* **ifp\_get\_tuner\_presets***, n is a number between 0 and* **IFP\_PRESET\_TOTAL***-1, callsign is a pointer to a buffer of at least* **IFP\_TUNER\_LABEL***+1 bytes, freq is a pointer to an integer, where the station's frequency will be saved. The frequency units are 10\*kHz (0.01MHz) and should range from* **IFP\_FREQ\_MIN** *to* **IFP\_FREQ\_MAX***.*

*Apon successful return, 'callsign' will be loaded the station's label as a zero-terminated string, and 'freq' will be the station's frequency in units of 10\*kHz (0.01MHz).*

### int ifp\_set\_station (int n, void \* b, const char \* callsign, int freq)

*Sets station #n to 'freq' and 'callsign'.*

*b is the block of data loaded using* **ifp\_get\_tuner\_presets***, n is a number between 0 and* **IFP\_PRESET\_TOTAL***-1, callsign is a zero-terminated string (but only the first 6 characters will be used), freq is the FM frequency in units of Hz\*10^4 (or 0.01 MHz); freq should range from* **IFP\_FREQ\_MIN** *to* **IFP\_FREQ\_MAX***.*

*eg: //sets station #4 to 94.9MHz and labeled 'bbc1' i =* **ifp\_set\_station***(3, p, 'bbc1', 9490);*

*Notes: -***ifp\_set\_tuner\_presets** *must be called before any changes to take affect.*

*-Although this interface suggests frequency accuracy of 0.01MHz is possible, I've found some players only support increments 0.05MHz. Setting a frequency to a more accurate value is \*not\* an error: the hardware will silently truncate to a nearby acceptable value.*

*-User interfaces can provide feedback to the user of the above 'effect' by saving and reloading the preset data after every change. Any trunction by the hardware will be immediately obvious.*

*Returns* **IFP\_ERR\_BAD\_FREQUENCY** *if the frequency is out of range.*

## Author

*Generated automatically by Doxygen for libifp from the source code.*
