mcd

Media Content Detector utility

Syntax:

mcd options* config_file &

Runs on:

Neutrino

Targets:

ARM, PowerPC, SH, x86

Options:

-D
Set the name of the mediastore list directory; the default is .devices.
-E
Set the name of the mediastore eject file; the default is .eject.
-I
Set the name of the mediastore insert file; the default is .insert.
-L
Run the MCD in local mode, even when Qnet is running. See Local mode below.
-n
Set the subsystem mountpoint; the default is /dev/mcd.
-v
Increase the verbosity of messages written to sloginfo, from 0 to 7.
-V
Print output messages to console, as well as sloginfo.
config_file
The pathname to a required configuration file; see Configuring the MCD below.

Local mode

The local mode option (-L) may permit simpler configuration when stand-alone systems are used, as describe here.

Use local mode if a system using MCD is to be run as a stand-alone with respect to any services that use the MCD, and Qnet is running on the system (for example, for debugging).

When the MCD runs in local mode, the MCD:

Limitations

When the local mode option is used:

Description:

The mcd utility (media content detector, or MCD) monitors device and mediastore insertions and removals, and the presence of specified media content.

This utility page contains:

Overview

The MCD is a stand-alone utility for detecting devices, mediastores and specified media content. It is positioned between storage and USB device drivers, and any client application that needs to be informed of a device or mediastore activity, or of the presence of specified media types.

The MCD design separates the definition of actions conducted by the system from the implementation of these actions so that the actions can be easily edited or updated without changes to code.

MCD rules

The MCD provides a binary decision tree framework, applying rules and branching between rules according to match/fail results. These rules are used for detecting device and mediastore insertions and removals, and for classifying their content. They are specified in the MCD configuration file, and implemented with user callouts.

You can write rules for the MCD instructing it to monitor the presence or absence of any device, mediastore or file, as shown by the three examples below:

Monitor a mediastore

The rule below tells the MCD to monitor the physical insertion or removal of a CD-ROM mediastore on a device (the hardware) at the location /dev/cd*.

[/dev/cd*]
Callout=CD_MEDIA_IOBLK

Monitor namespace changes

The rule below monitors changes (mount or unmount) of a device or mediastore (such as a USB storage device) on the system. These sorts of changes usually indicate the physical insertion or removal of the device (the hardware) and its filesystem mounting or unmounting.

[/fs/usb*]
Callout=PATH_MEDIA_PROCMGR

Monitor the presence of files

The rule below polls the contents of /directory looking for files or directories that have been created in or removed from the directory being monitored. For example, typing touch /directory/file from a shell satisfies this rule, though no physical device has been inserted or removed.

[/directory/*]
Callout=PATH_MEDIA_SCAN

Note: The MCD can be used as a framework from which to build an independent content detection system.

MCD server

The MCD server:


Note: In this documentation:
  • mediastore is never a specific mediastore, but always any mediastore of the specified type: a CD and not, for example, the CD I'm Your Man by Leonard Cohen.
  • an unformatted CD or USB stick is considered a device, because in its current state it cannot have any media content
  • a USB stick with, for example, two partitions is one device with two mediastores

Operational flow

This section describes the MCD's operational flow at startup, and on detection of a new device, mediastore or file.

Startup

At startup, the MCD server proceeds as follows:

  1. Read the configuration file.
  2. Create a single, dedicated thread to provide the resource manager interface.
  3. For each mediastore listed in the configuration file:
    1. Create a dedicated, device detection thread.
    2. Run the notification routine in its own thread.

Note: Multiple detection threads, each for different mediastores, may be running concurrently.

Device or insertion

On detection of a device or mediastore insertion, or of the presence of a file of interest, the MCD proceeds as follows:

Configuring the MCD

The operation of the MCD is controlled by a configuration file. This file consists of named sections, each section defined by a name enclosed in square brackets: [ ], followed by parameter lines with the form key = value. These parameters apply only to the section in which they appear.


Note: The sample MCD configuration file 2phase.cfg is delivered with the MCD; the sample configuration file mcd.conf provides examples for use with the Aviage Multimedia suite (MME).

The MCD ignores blank lines and any leading or trailing white spaces. It treats lines beginning with a “#” or a “;” character as comments and ignores them as well.

Configuration file sections

A section of the MCD configuration file can be one of:

The example below presents a description: [/dev/cd0] and a rule: [DVD_AUDIO]:

[/dev/cd0]
Callout     =   CD_MEDIA_IOBLK
Argument    =   1000,2000
Priority    =   11,9
Start Rule  =   DVD_OR_CD

[DVD_AUDIO]
Callout     =   FNAME_MATCH
Argument    =   /AUDIO_TS/AUDIO_TS.IFO
Match Rule  =   DVD_VIDEO
Fail Rule   =   DVD_VIDEO

Entity descriptions

For entity (device, mediastore or file) description sections, the section name is the entity the MCD monitors. This name can be a single name, such as /media/drive, or a wildcard pattern, such as /dev/umass*. If the section name is a wildcard pattern, the event notification routine defined by the Callout= for the section must be capable of handling every entity that matches the wildcard pattern.

Parameters

Configuration parameters are used differently according to the type of section (mediastore description, or content rule) in which they are used.

Parameters in an entity section of the configuration file are used as follows:

Callout=
The notification routine that the MCD runs when it detects the entity defined in the section name. Each notification routine is run in its own thread, allowing it to either block or poll as necessary.

If you provide no Callout= routine, you should handle device, file or mediastore transitions externally with the notification provided through the resource manager interface.

Argument=
An optional argument to pass to the notification routine defined by the Callout= parameter.
Priority=
The priorities at which to run, if applicable, for the entity defined in the current section:
Start Rule=
The root of the decision tree executed to determine media content type; that is, the first rule to apply to each entity following insertion notification.
Stop Rule=
The root of the callouts to execute when the entity is removed.

Media content rules

For media content rule sections of the mcd configuration file, the section name is the name of the rule.

Parameters

Parameters in a media content rule section of the configuration file are used as follows:

Callout=
The notification routine that the MCD runs when it detects an entity matching the content rule in the section name. See Notification routine below.
Argument=
An optional argument to pass to the notification routine defined by the Callout= parameter.
Match Rule=
The branch of the decision tree to execute when media content matches the content rule.
Fail Rule=
The branch of the callouts to execute when no media content matches the content rule.

Note: A rule runs at the priority given in the entity section that starts the rule chain.

Notification routine

The notification routine that runs when a mediastore matches a rule produces a match/fail result to indicate whether or not the media on the mediastore satisfies the routine's particular requirements. Based on the result produced by the rule, the MCD takes a branch to another rule, as specified by the Match Rule= or Fail Rule= parameters in the current section.

If no associated branch rule is provided for a rule's result, the MCD considers the rule to be terminal and content detection complete.


Note: If a rule contains no Callout= parameter, the MCD assumes that the rule either matches or fails, based on the presence of an associated branch rule. When debugging, you can use this characteristic to disable a test and always make a branch to the next rule.

Using the MCD as a filesystem automounter

The MCD can be used as a filesystem automounter by creating a set of two-phase rules in the MCD configuration file. Two-phase rules are implemented in the MCD as follows:

First-level entries

Second-level entries

For an example of how to use the MCD as a filesystem automounter, see Two-phase filesystem mount example in the “Examples” section below.

The mcd resource manager interface

The MCD server presents a standard QNX resource manager (filesystem-like) interface. The default top-level directory is /dev/mcd; it includes:


Note: To change the top-level directory, use the -n command-line option.

.insert and .eject files

The .insert and .eject files are write-only files in /dev/mcd. External programs can trigger the MCD's content detection process on the insertion or ejection of an entity by writing to the appropriate file the pathname of the entity that has been inserted or ejected; for example /dev/cd1 .


Note: If the hardware for the device with an ejected mediastore doesn't support removal notification, then the MCD treats a subsequent insertion notification as an implicit ejection event.

.devices directory

The .devices directory in /dev/mcd contains an entry for each entity (device, mediastore and monitored file) known to the system. Each entity is represented by a S_IFCHR/char-special file in this directory. These files hold information about the entity in fields as follows:


Note: An entry appears in .devices directory only for entities that have been inserted at least once. Since entity sections can be wildcards, a full list of potential entity matches can not be known in advance. The MCD can only know about an entity after it has been inserted. Thus, if a client application tries to stat() a particular device and fails with ENOENT, it should treat this failure as though the st_ino field is 0 (i.e., device ejected).

The Client API section below includes an example that illustrates how to use this interface.


Sequence number

The sequence number stored in st_ino for any entity (device, mediastore or file) can be either zero or non-zero. A value of zero means that the entity is not present in the system. A non-zero value means that the entity is present in the system.

At each re-insertion of the entity, the MCD increases the sequence number for that entity. Thus, for example, for a mediastore the values of st_ino might be in sequence: 1 (first insertion), 0 (removal), 3 (re-insertion), 0 (removal), 5 (re-insertion).

A client application can use the incrementing value of st_ino at each state change to check that it is up to date with, for example, a mediastore's activity after a series of rapid insertions and removals. For more information, see Stale rules below.

Example: Filesystem hierarchy

Below is a sample filesystem hierarchy:

$ ls -al /dev/mcd
dr-xr-xr-x  1 root   root  11 Aug 02 19:46 .
n-w--w--w-  1 root   root   0 Aug 02 19:46 .eject
n-w--w--w-  1 root   root   0 Aug 02 19:46 .insert
nr--r--r--  1 root   root   0 Aug 02 19:46 CDDA_OR_DTS
nr--r--r--  1 root   root   0 Aug 02 19:46 CD_AUDIO
nr--r--r--  1 root   root   0 Aug 02 19:46 DVD_AUDIO
nr--r--r--  1 root   root   0 Aug 02 19:46 DVD_OR_CD
nr--r--r--  1 root   root   0 Aug 02 19:46 DVD_VIDEO
nr--r--r--  1 root   root   0 Aug 02 19:46 MIXED_AV
nr--r--r--  1 root   root   0 Aug 02 19:46 SVIDEO_CD
nr--r--r--  1 root   root   0 Aug 02 19:46 VIDEO_CD

Read-only entries for rules

The top-level /dev/mcd directory contains read-only entries for each rule defined in the configuration file.

Client applications can read from here the name of the device that satisfied a particular rule, with the read blocking until a device with content matching that rule is available. A non-blocking select and notify mechanism is also available to allow the client to wait on multiple rules, or to perform other work until a rule is triggered. Following the notification, the client application can read the rule to determine the device.

Callout templates

The MCD server provides a framework from which you can build a content detection system. Callout routines provide all the specific functionality in such a content detection system.

The MCD includes some common routines available for use where required in a static-linked library bound into the server. The MCD also supports extension routines provided by third-parties in DLLs dynamically linked at runtime. Thus, the system is extensible: if you require a new, unsupported detection test, you can implement it outside the server framework and ship it as a separate library.

In the content detection system configuration file, all Callout= items refer to a callout. These callouts are identified as internal or external by their names:


Note: Extension modules must include the MCD header file <sys/mcd.h> for appropriate manifests and type definitions.

Insertion and ejection notification

The prototype for media insertion notification callouts is:

void mcd_notify( char *iomgr[2], char *device, void *arg );

The MCD creates this routine in a dedicated thread, that should continually monitor the device. This thread should not return, except in the event of a serious error. If the thread encounters a serious error, it should set errno appropriately and return. On the return of an entity detection thread, the MCD will:

Arguments

iomgr
An array containing the names of the interface entries where insertion and ejection events are reported. In a default system iomgr[0] = "/dev/mcd/.insert" and iomgr[1] = "/dev/mcd/.eject", but the actual strings will reflect any command-line overrides.
device
A pointer to the name of the device, mediastore or file to monitor.
device may be a wildcard, requiring the routine to monitor a group of devices, files or mediastores. When a device event occurs, the routine should write to the appropriate iomgr[] path the name of the specific device, mediastore or file that is affected by the event.
arg
A pointer to a routine-specific argument. This routine-specific argument is provided as the Argument= parameter of the relevant device entry in the configuration file.

Built-in notification routines

The MCD's built-in media notification routines include:

CD_MEDIA_IOBLK
This routine interfaces the system to CD and DVD drives managed by the devb/io-blk filesystem. It exploits the filesystem feature of automatically invalidating open file descriptors upon media change: it opens the device block-special file and periodically polls it, treating any EBADF result as a transition indicator. It distinguishes between insertion and ejection by examining the advertised size of the device.

The Argument= option sets the polling periods (in milliseconds) at which to probe the file descriptor when the mediastore missing, and when it is present. The default for this argument is "1000,2000", which corresponds to a one-second interval when the mediastore is missing, and a two-second interval when the mediastore is present.

USB_MEDIA_ENUM
Targets running QNX Neutrino 6.3.n releases only. This routine interfaces the system to the umass-enum utility (which is replaced by enum-usb in QNX Neutrino 6.4.0). It translates USB state change events from their native format into the insertion and ejection events expected by the USB enumeration server named by the Argument= option.

The Argument= option sets the name of the USB enumeration server to connect to (typically "/dev/umass-enum").

PATH_MEDIA_PROCMGR
This routine connects the system to any device that dynamically attaches a resource manager pathname when the resource manager is present, and detaches the pathname when the resource manager is absent. It uses the procmgr_event() facility (available from QNX Neutrino 6.3.0 SP2 onwards) to receive notification of any changes to the global pathname space, then scans for the addition and/or removal of any device mountpoints matching the pattern defined by the callout name.

The Argument= option sets the name of the special directory where the OS pathmgr maintains mountpoints (typically "/proc/mount").

PATH_MEDIA_SCAN
This routine scans for the presence of filenames that match the pattern defined by the callout name. It is similar to the PATH_MEDIA_PROCMGR routine, but since the creation and deletion of files doesn't trigger any filesystem events, this routine operates by scanning the specified directory at regular intervals.

The PATH_MEDIA_SCAN cause the MCD to behave differently, based on the presence or absence of a trailing “/” character at the end of the pathname, as follows:

The Argument= option sets the poll period, in milliseconds, for scanning the directory.

Media content determination

The prototype for content detection rule callouts is:

int mcd_content( char *device, void *arg );

Arguments

device
The name of the raw device or mediastore
arg
A pointer to a routine-specific argument. This routine-specific argument is provided as the Argument= parameter of the relevant rule entry in the configuration file.

Returns

This routine returns values as follows:


Note: If the routine invoked by the callout requires access to a filesystem on the device, it can use the DCMD_FSYS_MOUNTED_BY devctl to locate the appropriate mountpoint.

Built-in content detection rules

The MCD's built-in content detection routines include:

DVD_OR_CD
This rule determines if a disk mediastore is a DVD rather than a CD (by issuing a READ DVD STRUCT command).

It ignores The Argument= option. The rule matches only if the media is a DVD.

CD_AUDIO
This rule determines if the CD media has any audio content (by issuing a READ TOC command). It ignores the Argument= option. The rule matches only if the media contains audio tracks.

Note: To facilitate the detection of mixed-mode and enhanced CDs that contain both audio and filesystem components, you can configure the CD_AUDIO rule as a non-terminal state; that is, with both the Match Rule= branch and the Fail Rule= branch provided. With the rule configured this way, after matching audio content, you can continue on with other rules to detect data content.

BLANK_CD
This rule determines if the CD media is blank or unrecorded (by issuing a READ DISK INFORMATION command). It ignores the Argument= option.

Note: The READ DISK INFORMATION command and the physical detection of blank disks is only supported by newer CD-RW hardware, and will fail on older CD-ROM hardware. In fact, older hardware may not even detect the insertion of a blank or unrecorded disk.

FNAME_MATCH
This rule uses fnmatch() to match file pathnames on a device's filesystem. It requires that the inserted mediastore either be a filesystem, or have a filesystem mounted on it, because it is implemented with access() probing. The rule will automatically resolve to the filesystem level, if appropriate.

This behavior means that:

The Argument= option is a comma-separated list of pathnames, based from the root of the filesystem. If the MCD finds any of the pathnames in the list on the mediastore, the rule is matched.

FNAME_PATTERN
This rule uses fnmatch() to match filename patterns on a mediastore's filesystem. It requires that the inserted mediastore either be a filesystem or have a filesystem mounted on it, because it is implemented with a nftw() traversal. The rule will automatically find any such filesystem.

The Argument= option sets a comma-separated list of patterns. If a filename matching any of the listed patterns exists in any directory on the filesystem, the rule is matched.

This option supports several other options that can be embedded in the listed patterns. For example: Argument = depth=2,*.c,*.h". These “embedded” options are:

By default the scan for a pattern match is the entire target filesystem. You can use the basedir= and depth= options to direct and limit this scan.

MOUNT_FSYS
This rule is used to mount a filesystem onto a specified device, and is used to extend the MCD to operate as an auto-mounter.

The Argument= option sets the filename of a file of mount rules. Since this option is opened and parsed each time the rule is run, you should consider locating this filename on a ramdisk or in /dev/shmem.

This rule is typically used as the Start Rule= of a two-phase configuration, where the resulting mount operation triggers a PATH_MEDIA_PROCMGR action. The rules are processed from the file in order, stopping at the first (fnmatch()) match that either succeeds or specifies to skip the device (when the rule has only a pattern and no mount information). In order to select the appropriate filesystem, you can specify multiple rules for a removable device.

The file format is one rule per line, with each line containing fields separated by white spaces. For example:



#Device_pattern    Mount_point Fsys_type Mount_options
/dev/cd*           /fs/cd%#    udf       normv,format=udf,rrip,joliet,iso9660e,iso9660,audio
/dev/umass*t1[124] /fs/usb%0   dos       fsi=use
/dev/umass*t[146]  /fs/usb%0   dos
/dev/hd*

The rules shown in the example above instruct the MCD to:

See MOUNT_FSYS special sequences below for more information about the mountpoint sequences. For more information about UDF, see fs-udf.so.


Note: The normv option is required to work around OS namespace race conditions if the filesystem format is not known when trying multiple mounts with different DLLs. It is also useful to prevent a mount if the media is ejected before the rule is scheduled to run.

UNMOUNT_FSYS
This rule unmounts the filesystem from the mediastore specified in the rule name. It ignores the Argument= option.

This rule is typically used as the Stop Rule= of a CD_MEDIA_IOBLK mediastore that uses the MOUNT_FSYS action, when a mount would otherwise persist after the mediastore ejection. If the mediastore is presented by a resmgr that will exit or be terminated by an external manager (such as USB), then that presentation implicitly unmounts any relevant filesystem without the need for this rule. However, in most instances where a MOUNT_FSYS is used, you should also configure a matching UNMOUNT_FSYS in order to ensure that the filesystem for an ejected mediastore is duly unmounted.

MOUNT_FSYS special sequences

The MOUNT_FSYS rule uses special sequences, as follows:

Below is a sample mcd.mnt file that uses the %# and %0 special sequences.

#------------------------------------------------------
# Device                    Mountpt     Type  Options
#------------------------------------------------------
/dev/cd*                    /fs/cd%#    udf    normv
/dev/umass[0-9]*            /           enum
/dev/umass[0-9]*t1[1234]    /fs/usb%0   dos
/dev/umass[0-9]*t1[1234].*  /fs/usb%0   dos
/dev/umass[0-9]*t[146]      /fs/usb%0   dos
/dev/umass[0-9]*t[146].*    /fs/usb%0   dos
/dev/umass*t7[789]          /fs/usb%0   qnx4
/dev/umass*t17[789]         /fs/usb%0   qnx6  sync=optional
/dev/umass[0-9]*            /fs/usb%0   dos

Client API

The MCD uses special rule entries created in the resource manager filesystem to notify client applications of media content matches.

A client application can call open() to access the rule entry in which it is interested, and when that rule is matched, it can then use read() to read from the entry the name of the relevant mediastore. If QNET is active and the -L is not specified, the device name returned from reading the MCD rule entry is a fully-qualified-path-name (FQPN); this feature allows the string to be used as-is by any process on any node.

The read() function blocks until a match is made (unless oflag is set to O_NONBLOCK). For non-blocking notifications, use ionotify(). To wait on multiple rules, use select().

Maintained information

In order to inform each client once and only once of each match, the MCD server maintains state information about each mediastore, matched rule, and client application.

When a new mediastore is inserted, any matched rule triggers notifications to the interested clients. If the mediastore was inserted before a client registered with the MCD, the first read the client makes is satisfied immediately. This behavior eliminates any start-up race conditions, such as, for example, there being media already in a drive at system startup, and the content detection process completing before the higher-level client applications are even started.

Example: Media player

A very simple media player might be designed as follows:

int     fd, cd;
char    device[_POSIX_PATH_MAX];

// Open the CD_AUDIO rule and wait for it to be matched.
fd = open("/dev/mcd/CD_AUDIO", O_RDONLY);
while (read(fd, device, sizeof(device)) != -1) {
    // At this point, device contains an audio CD ...
    cd = open(device, O_RDONLY);
    // ... read the toc, play it, etc.
    // Could monitor playback status with
    // DCMD_CAM_CDROMSUBCHNL.
    // If disk is ejected, this will fail.
    // Can loop back waiting for next insertion.
    // The rule will be re-armed for the
    // next match.
    close(cd);
}
close(fd);

Example: Polling

The mcd device Start Rule= and Stop Rule= rule chains are mutually exclusive: the ejection of a device cancels out inserted rules for that device (and vice-versa). Therefore, if you use select() or ionotify(), you should use them in conjunction with a non-blocking read(), as there is no guarantee that the notified state and/or rules of the trigger will remain valid (for example, if the media is ejected between the calls to ionotify() and read()).

The code snippet below illustrates one way to use ionotify() in conjunction with a non-blocking read():

<PRE>
   fd = open(rulename, O_RDONLY | O_NONBLOCK);
   SIGEV_UNBLOCK_INIT(&evt);
   for (;;) {
       while (ionotify(fd, _NOTIFY_ACTION_POLLARM, _NOTIFY_COND_INPUT,
                       &evt) != 0) {
           while (read(fd, device, sizeof(device)) > 0) {
               // 'device' matched on 'rulename'
           }
       }
       pause();
   }
</PRE>

Note: In a real application, the event would likely be a pulse, and there would be an event-driven loop rather than a pause as in the code snippet above.

Stale Rules

Stale rules may occur if there is client decoupling, and/or a delay between the notification and the use of inserted mediastore; for example, due to the spawning of a separate media application.

To avoid stale rules, the MCD can include the mediastore's insertion sequence number with the rule notification, and applications can then match this number against the device entry in the /dev/mcd/.devices directory. If the device has been ejected since the rule was triggered, these values will no longer match, indicating that the rule no longer applies to the current device content, and that new rules may have been re-triggered.

If the client application requires an insertion sequence number, the MCD uses an XTYPE read to return an additional uint32_t of data with the mediastore name, and the _IO_XTYPE_MQUEUE message priority code, avoiding the need to make changes to the global <sys/io_msg.h> header file.

// Get rule notification using an XTYPE read
int        fd;
uint32_t   seq1;
char       device[_POSIX_PATH_MAX];

fd = open("/dev/mcd/CD_AUDIO", O_RDONLY);
_readx(fd, device, sizeof(device), _IO_XFLAG_BLOCK | _IO_XTYPE_MQUEUE,
    &seq1, sizeof(seq1));

// Open and check the current version of the inserted device
int         fd;
struct stat st;
uint32_t    seq2;
char        entry[_POSIX_PATH_MAX];

fd = open(device, O_RDONLY);

sprintf(device, "/dev/mcd/.devices/%s", device);
seq2 = (stat(device, &st) != -1) ? st.st_ino : 0;

// If these match, the CD_AUDIO rule is the same and still valid
// and 'fd' is open on that version of the media
if (seq1 == seq2) ...

Additional Information

This section describes how to use the MCD for specific operations:

Detecting other kinds of system media

To detect system media not handled by the routines included with the MCD:

  1. Determine what distinguishes your new media type from all other media types. In many cases, the difference might simply be the presence of certain files or directories on the mediastore. For example, a navigation update disk might be identified by the presence of acios_db.ini or config.nfm files. In this case, a built-in routine such as FNAME_MATCH, could perform the detection; or you might have to write a custom routine and provide it to the MCD in an external DLL.
  2. Determine the precedence to probe for this media amongst the existing media tests (first, last, after checking for audio content but before checking any other data rules, etc).
  3. In the configuration file, make a new rule section for this test, with the appropriate Callout= rule, and splice it into the appropriate point of the decision tree by editing the Match Rule= or Fail Rule= parameters of both the preceding rule and the new rule. The name of the new rule can be used to trigger any client application when the new content is matched.

Detecting USB and iPod devices

The MCD can manage any kind of device, provided that a notification mechanism is available to report on insertions and start the detection process.

For USB devices, you can use the following entry in the MCD configuration file:

[/fs/usb*]
Callout     = PATH_MEDIA_PROCMGR
Argument    = /proc/mount
Priority    = 11,10
Start Rule  = ...

Targets running QNX Neutrino 6.3.n releases only. For USB devices, the umass-enum server in conjunction with the MCD's built-in USB_MEDIA_ENUM routine can provide the notification mechanism and start the detection process. Invoke umass-enum with the -r option to activate its resource manager interface, and use the following device entry in the MCD configuration file:

[/dev/umass/*]
Callout     =   USB_MEDIA_ENUM
Argument    =   /dev/umass-enum
Priority    =   11,10
Start Rule  =   ...

For iPod devices, the device entries dynamically attach pathnames (when these pathnames are present), and so can be handled with the MCD's built-in PATH_MEDIA_PROCMGR() routine. Use the following device entry in the MCD configuration file for iPods:

[/fs/ipod*]
Callout     =   PATH_MEDIA_PROCMGR
Argument    =   /proc/mount
Priority    =   11,10
Start Rule  =   ...

Pattern matching and case-sensitivity

The MCD's FNAME_MATCH routine attempts to access listed files by using the underlying filesystem, which applies any rules appropriate for that filesystem in conjunction with any specified mount options. Thus, case-sensitivity in pattern matching depends on:

The table below lists the case-sensitivity and case-preserving characteristics of some common filesystems:

filesystem case-sensitive case-preserving
FAT No No
ISO-9660 No No
Joliet No Yes
QNX4 Yes Yes
RRIP Yes Yes
VFAT No Yes

Since the majority of mediastores used for multimedia storage are formatted for DOS/Windows use, it is likely that the filesystem will be case-insensitive. This case-insensitivity means that in any FNAME_MATCH rules the Argument= filename list can be given in either upper or lower case.

The FNAME_PATTERN routine processes directory entries from the filesystem through the libc fnmatch() function, which is case sensitive.

The directory output from each filesystem depends on whether it is case-preserving. If the filesystem is not case-preserving, then default rules are used to control the filename presentation. Refer to the cd case=lower|upper or the dos sfn=lower|upper|windows filesystem mount options.

Since the most common multimedia formats are case-preserving and will use the exact filename that a user or media application used to create their files, in any FNAME_PATTERN rules the Argument= pattern list should be given in both upper and lower case (as in the MIXED_AV rule in the Examples below.).

Matching a single rule

If you don't want multiple media types to match and only want to match the first rule, you can use the fact that if a matched rule has no Match Rule= branch the MCD stops its detection process.

In the configuration file, simply arrange the rules, from the Start Rule= through the Fail Rule= links, in priority order. Do not provide any Match Rule= branches. The MCD detection framework will test these rules in sequence until one is matched, then stop. For an example, see the VIDEO_CD and SVIDEO_CD entries in the Examples below.

Detecting CD insertion with non-media content

To be notified when a CD is inserted regardless of what content it contains, simply:

Your application can now block on that new rule, via the normal resource manager interface ("/dev/mcd/DISC_INSERTED"), waiting for device insertion. For example, one of the example configurations in this document could be modified as follows:

[/dev/cd0]
Callout      =    CD_MEDIA_IOBLK
Argument     =    1000,2000
Priority     =    11,9
Start Rule   =    DISC_INSERTED

[DISC_INSERTED]
Match Rule   =    DVD_OR_CD

CD-changer controlled by external firmware

To detect insertion events from a CD-changer that is controlled by external firmware (e.g. FJ-10), you should not use any of the built-in MCD detection callouts, but trigger the insertion notification directly from the CD-changer controller stack.

Internally, all built-in device detection callouts do their specific work, then write the name of the device to the special /dev/mcd/.insert entry. This behavior means that to detect insertions on changers controlled by external firmware, proceed as follows:

In the configuration file, the relevant device entry would be like this (note that no Callout= is specified in this situation):

[/dev/cd0]
Priority     =    11
Start Rule   =    ...

The insertion notification code in the driver is basically this:

int    notify;

notify = open("/dev/mcd/.insert", O_WRONLY);
write(notify, "/dev/cd0", 8);
close(notify);

Similar code to handle ejections can be written to /dev/mcd/.eject.

Using the MCD as a partition enumerator

The MCD's MOUNT_FSYS rule can be used to determine if partition enumeration has occurred on a device (USB stick). This capability can be used to try to mount a filesystem on the raw device, if the device has not been partitioned.

In order to determine if partition has occurred, use the following configuration:

The control flow for this configuration is as follows:

  1. USB stick inserted.
  2. USB enumerator detects insertion and launches devb-umass.
  3. devb-umass puts up /dev/umassX pathname, triggering the MCD.
  4. The MCD runs the MOUNT_FSYS rule.
  5. If the media is non-partitioned:
    1. The enum rule is executed and fails.
    2. The code falls through and attempts fs-dos mount on raw device, which should succeed, resulting in the appearance of an /fs/usb*.
  6. If the media is partitioned:
    1. The enum rule enumerates partitions and, thus, succeed, terminating the callout.
    2. The enumeration makes /dev/umassXtN names appear, re-entering the MCD device rule with a pattern that skips the enum rules, and instead tries fs-dos mounts on a partition, resulting in appearance of an /fs/usb*.
  7. Following either of the above two cases (5 or 6), MOUNT_FSYS is successful with a mount, and the MCD continues with /fs/usb* rules, typically some form of content detection or the triggering of a dummy INSERT rule.

Note: X is the disk number (0, 1, 2, etc.). and N is the partition type (4, 11, 12, etc.); for example: /dev/umass[0-9]* or /dev/umass[0-9]*t1[124]. Thus, a path with umassX refers to a device, while a path with umassXtN refers to a partition.

Examples:

Consider the following sample configuration file for a CD-based system:

# Sample CD/DVD disk identification rules.

[/dev/cd0]
Callout     =   CD_MEDIA_IOBLK
Argument    =   1000,2000
Priority    =   11,9
Start Rule  =   DVD_OR_CD

[DVD_OR_CD]
Callout     =   DVD_OR_CD
Match Rule  =   DVD_AUDIO
Fail Rule   =   CD_AUDIO

[DVD_AUDIO]
Callout     =   FNAME_MATCH
Argument    =   /AUDIO_TS/AUDIO_TS.IFO
Match Rule  =   DVD_VIDEO
Fail Rule   =   DVD_VIDEO

[DVD_VIDEO]
Callout     =   FNAME_MATCH
Argument    =   /VIDEO_TS/VIDEO_TS.IFO
Fail Rule   =   VIDEO_CD

[CD_AUDIO]
Callout     =   CD_AUDIO
Match Rule  =   VIDEO_CD
Fail Rule   =   VIDEO_CD

[VIDEO_CD]
Callout     =   FNAME_MATCH
Argument    =   /VCD/INFO.VCD,/MPEGAV/AVSEQ01.DAT,/MPEGAV/MUSIC01.DAT
Fail Rule   =   SVIDEO_CD

[SVIDEO_CD]
Callout     =   FNAME_MATCH
Argument    =   /SVCD/INFO.SVD,/MPEGAV/AVSEQ01.MPG,/MPEG2/AVSEQ01.MPG
Fail Rule   =   MIXED_AV

[MIXED_AV]
Callout     =   FNAME_PATTERN
Argument    =   *.MP3,*.mp3,*.WMV,*.wmv,*.WMA,*.wma,*.AAC,*.aac,*.JPG,*.jpg,*.MPG,*.mpg

A single device, /dev/cd0, is monitored by the built-in CD_MEDIA_IOBLK() routine:

During the content detection processing phase, any clients that have registered against any matched rules will be notified. Multiple rules, or no rules at all, might be matched by an inserted CD: an enhanced audio CD with a bonus music video might match both CD_AUDIO and MIXED_AV rules, whereas a data CD backup of a development system would match none.

Two-phase filesystem mount example

Below is a configuration file involving USB devices; it requires that an external USB enumerator invoke devb-umass blk auto=partition disk name=umass in response to insertions.

[/dev/umass*t*]
Callout     =   PATH_MEDIA_PROCMGR
Argument    =   /proc/mount
Priority    =   11,10
Start Rule  =   MOUNT

[MOUNT]
Callout     =   MOUNT_FSYS
Argument    =   /dev/shmem/mcd.mnt

[/fs/usb*]
Callout     =   PATH_MEDIA_PROCMGR
Argument    =   /proc/mount
Priority    =   11,10
Start Rule  =   MIXED_AV

[MIXED_AV]
Callout     =   FNAME_PATTERN
Argument    =   *.MP3,*.mp3,*.WMV,*.wmv,*.WMA,*.wma,*.AAC,*.aac,*.JPG,*.jpg,*.MPG,*.mpg

Note that the device pattern specified in the example above avoids the raw device itself and only applies to partition entries. The mount configuration /dev/shmem/mcd.mnt referred to contains:

/dev/umass*t1[124]      /fs/usb%#   dos
/dev/umass*t[146]       /fs/usb%#   dos

See also:

MultiMedia Engine (MME) Configuration Guide