c-SCSI感测到字符串



大多数人都知道使用过SCSI,如果发出SCSI命令,设备可以返回一个带有附加信息的所谓感测代码。

基本上,你有3个数字,它们加在一起有意义。

以下是维基百科上的列表:http://en.wikipedia.org/wiki/Key_Code_Qualifier

我需要一个函数,它接受这3个数字,识别发生了什么错误,并根据它返回一个char数组。我一直在想一个好方法。如果语句看起来很不合法,就分支。。。

我想知道是否有一种简单的方法可以做到这一点,而不需要一些复杂的功能。

对于这种问题,嵌套开关是最糟糕的方法。查找表要简单得多。你可能需要这样的东西:

struct SCSILookupTableElement
{
  unsigned char key;
  unsigned char asc;
  unsigned char ascq;
  const char *errorcondition;
} SCSILookupTable[] =
{
  {   0,    0,    0,      "No error"},
  {   0, 0x5d,    0,      "No sense - PFA threshold reached"},
  {   1,    1,    0,      "Recovered Write error - no index"},
  ...
  {0xff,    5,    0,      "Illegal request"}  // 0xff stands for X
  ...
};

const char *SCSIErrortext(int key, int asc, int ascq)
{
  int i ;
  for (i = 0; i < sizeof(SCSILookupTable)/sizeof(struct SCSILookupTableElement); i++)
  {
    if (  (SCSILookupTable[i].key == key || SCSILookupTable[i].key == 0xff)
        && SCSILookupTable[i].asc == asc
        && SCSILookupTable[i].ascq == ascq)
    {
      return SCSILookupTable[i].errorcondition;
    }
  }
  return "Unknown error";
}

void main()
{
  printf ("%sn", SCSIErrortext(0, 0x5d, 0));
  printf ("%sn", SCSIErrortext(0xfe, 0x05, 0));
  printf ("%sn", SCSIErrortext(0x00, 0x05, 0));
}

它再简单不过了,尽管肯定还有改进的余地。

您可以看看libscsicmd,这是一个我正在慢慢开发的库。它包括一个感知缓冲区解析器和KCQ到字符串的映射,以供人类使用。

可以在http://github.com/baruch/libscsicmd

不过,为了回答您的直接问题,Sense Key和ASC/ASCQ是独立的,所以我选择返回两个不同的字符串,一个用于Sense Key,另一个用于ASC/ASCQ对。每个字符串都通过T10文本文件中自动生成的更大的switch语句来解决。

如果您想要一个单独的字符串,只需将其与sprintf或strcat组合即可。

最新更新