大多数人都知道使用过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组合即可。