libcdio-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Libcdio-devel] New MMC functions to detect media type


From: Frank Endres
Subject: [Libcdio-devel] New MMC functions to detect media type
Date: Sun, 7 Feb 2010 17:35:46 -0100

Hi !

cdio_get_discmode and mmc_get_discmode functions, although returning the
same type doesn't return the same information. After reading the source, I
saw that the mmc variant is incomplete (it doesn't detects DVDs), so I
completed with success this function, ... and decided to cancel the changes
after:
- I thought CDIO_DISCMODE_NO_INFO was used when no media is detected, but
after reading the source of cdio_is_discmode_cdrom, I saw that it is not
true.
- discmode mix - I think - two different types of information: CD content
and DVD media type. My opinion is that it is not a good idee to do so (it is
somehow inconsistent - or there is something I have not understood).

Those two reason drove me to cancel the modification of mmc_get_discmode
function, and I have decided to implement a new media detection solution,
using GET CONFIGURATION MMC command (as someone suggested). Maybe as I read,
it would be better to put these functions somewhere else than in mmc.c.


typedef enum {
  MMC_DISCTYPE_NO_DISC,

  MMC_DISCTYPE_CD_ROM,
  MMC_DISCTYPE_CD_R,
  MMC_DISCTYPE_CD_RW,

  MMC_DISCTYPE_DVD_ROM,
  MMC_DISCTYPE_DVD_RAM,
  MMC_DISCTYPE_DVD_R,
  MMC_DISCTYPE_DVD_RW,
  MMC_DISCTYPE_DVD_R_DL,
  MMC_DISCTYPE_DVD_PRW,
  MMC_DISCTYPE_DVD_PR,
  MMC_DISCTYPE_DVD_PRW_DL,
  MMC_DISCTYPE_DVD_PR_DL,

  MMC_DISCTYPE_BD_ROM,
  MMC_DISCTYPE_BD_R,
  MMC_DISCTYPE_BD_RE,

  MMC_DISCTYPE_HD_DVD_ROM,
  MMC_DISCTYPE_HD_DVD_R,
  MMC_DISCTYPE_HD_DVD_RAM
} disctype_t;


/**
  Detects the disc type using the SCSI-MMC GET CONFIGURATION command.

  @param p_cdio the CD object to be acted upon.

  @param opt_i_status, if not NULL, on return will be set indicate whether
  the operation was a success (DRIVER_OP_SUCCESS) or if not to some
  other value.

  @return the disc type.
 */
disctype_t
mmc_get_disctype (const CdIo_t *p_cdio,
      driver_return_code_t *opt_i_status) {

  uint8_t buf[500] = { 0, };
  mmc_cdb_t cdb = {{0, }};
  driver_return_code_t i_status;
  uint8_t *p, *q;
  uint8_t profiles_list_length;
  uint16_t profile_number;
  bool profile_active;
  disctype_t disctype;

  CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_GET_CONFIGURATION);
  CDIO_MMC_SET_READ_LENGTH8(cdb.field, sizeof(buf));
  cdb.field[1] = CDIO_MMC_GET_CONF_ALL_FEATURES;
  cdb.field[3] = 0x0;

  i_status = mmc_run_cmd(p_cdio, 0, &cdb, SCSI_MMC_DATA_READ,
        sizeof(buf), &buf);
  if (opt_i_status != NULL) *opt_i_status = i_status;

  if (i_status == DRIVER_OP_SUCCESS) {
    p = buf + 8; //there is always a profile list feature listed at the
first place of the features list
    profiles_list_length = p[3];
    q = p+4;
    disctype = MMC_DISCTYPE_NO_DISC;

    while ((disctype == MMC_DISCTYPE_NO_DISC) && (q < p +
profiles_list_length)) {
      profile_number = CDIO_MMC_GET_LEN16(q);
      profile_active = q[2] & 0x01;

      switch (profile_number) {
        case 0x08: disctype = MMC_DISCTYPE_CD_ROM; break;
        case 0x09: disctype = MMC_DISCTYPE_CD_R; break;
        case 0x0A: disctype = MMC_DISCTYPE_CD_RW; break;

        case 0x10: disctype = MMC_DISCTYPE_DVD_ROM; break;
        case 0x11: disctype = MMC_DISCTYPE_DVD_R; break;
        case 0x12: disctype = MMC_DISCTYPE_DVD_RAM; break;
        case 0x13: disctype = MMC_DISCTYPE_DVD_RW; break;
        case 0x14: disctype = MMC_DISCTYPE_DVD_RW; break;
        case 0x15: disctype = MMC_DISCTYPE_DVD_R_DL; break;
        case 0x16: disctype = MMC_DISCTYPE_DVD_R_DL; break;
        case 0x1A: disctype = MMC_DISCTYPE_DVD_PRW; break;
        case 0x1B: disctype = MMC_DISCTYPE_DVD_PR; break;
        case 0x2A: disctype = MMC_DISCTYPE_DVD_PRW_DL; break;
        case 0x2B: disctype = MMC_DISCTYPE_DVD_PR_DL; break;

        case 0x40: disctype = MMC_DISCTYPE_BD_ROM; break;
        case 0x41: disctype = MMC_DISCTYPE_BD_R; break;
        case 0x42: disctype = MMC_DISCTYPE_BD_R; break;
        case 0x43: disctype = MMC_DISCTYPE_BD_RE; break;

        case 0x50: disctype = MMC_DISCTYPE_HD_DVD_ROM; break;
        case 0x51: disctype = MMC_DISCTYPE_HD_DVD_R; break;
        case 0x52: disctype = MMC_DISCTYPE_HD_DVD_RAM; break;
      }
      if (! profile_active) //whatever the profile is, disctype is reset in
not active
        disctype = MMC_DISCTYPE_NO_DISC;
      q += 4;
    }
  }

  return disctype; //the first active profile found (profiles are ordered
        //from the most desirable to least desirable) or
MMC_DISCTYPE_NO_DISC
}


bool
mmc_is_disctype_cdrom (disctype_t disctype) {
  switch (disctype) {
  case MMC_DISCTYPE_CD_ROM:
  case MMC_DISCTYPE_CD_R:
  case MMC_DISCTYPE_CD_RW:
    return true;
  default:
    return false;
  }
}


bool
mmc_is_disctype_dvd (disctype_t disctype) {
  switch (disctype) {
  case MMC_DISCTYPE_DVD_ROM:
  case MMC_DISCTYPE_DVD_RAM:
  case MMC_DISCTYPE_DVD_R:
  case MMC_DISCTYPE_DVD_RW:
  case MMC_DISCTYPE_DVD_R_DL:
  case MMC_DISCTYPE_DVD_PRW:
  case MMC_DISCTYPE_DVD_PR:
  case MMC_DISCTYPE_DVD_PRW_DL:
  case MMC_DISCTYPE_DVD_PR_DL:
    return true;
  default:
    return false;
  }
}


bool
mmc_is_disctype_bd (disctype_t disctype) {
  switch (disctype) {
  case MMC_DISCTYPE_BD_ROM:
  case MMC_DISCTYPE_BD_R:
  case MMC_DISCTYPE_BD_RE:
    return true;
  default:
    return false;
  }
}

bool
mmc_is_disctype_hd_dvd (disctype_t disctype) {
  switch (disctype) {
  case MMC_DISCTYPE_HD_DVD_ROM:
  case MMC_DISCTYPE_HD_DVD_R:
  case MMC_DISCTYPE_HD_DVD_RAM:
    return true;
  default:
    return false;
  }
}


bool
mmc_is_disctype_rewritable (disctype_t disctype) {
  switch (disctype) {
  case MMC_DISCTYPE_CD_RW:
  case MMC_DISCTYPE_DVD_RW:
  case MMC_DISCTYPE_DVD_PRW:
  case MMC_DISCTYPE_DVD_PRW_DL:
  case MMC_DISCTYPE_BD_RE:
  case MMC_DISCTYPE_HD_DVD_RAM:
    return true;
  default:
    return false;
  }
}


I hope You will find them usefull. I made tests with almost all types of CDs
and DVDs.

Best regards !


-- 
Frank Endres


reply via email to

[Prev in Thread] Current Thread [Next in Thread]