USB Host Shield 2.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
hidescriptorparser.cpp
Go to the documentation of this file.
1 #include "hidescriptorparser.h"
2 
3 const char * const ReportDescParserBase::usagePageTitles0[] PROGMEM = {
19 };
20 
21 const char * const ReportDescParserBase::usagePageTitles1[] PROGMEM = {
28 };
29 const char * const ReportDescParserBase::genDesktopTitles0[] PROGMEM = {
38 
39 };
40 const char * const ReportDescParserBase::genDesktopTitles1[] PROGMEM = {
41  pstrUsageX,
42  pstrUsageY,
43  pstrUsageZ,
66 };
67 const char * const ReportDescParserBase::genDesktopTitles2[] PROGMEM = {
88 };
89 const char * const ReportDescParserBase::genDesktopTitles3[] PROGMEM = {
99 };
100 const char * const ReportDescParserBase::genDesktopTitles4[] PROGMEM = {
109 };
110 const char * const ReportDescParserBase::simuTitles0[] PROGMEM = {
123 };
124 const char * const ReportDescParserBase::simuTitles1[] PROGMEM = {
131 };
132 const char * const ReportDescParserBase::simuTitles2[] PROGMEM = {
166 };
167 const char * const ReportDescParserBase::vrTitles0[] PROGMEM = {
178 };
179 const char * const ReportDescParserBase::vrTitles1[] PROGMEM = {
182 };
183 const char * const ReportDescParserBase::sportsCtrlTitles0[] PROGMEM = {
188 };
189 const char * const ReportDescParserBase::sportsCtrlTitles1[] PROGMEM = {
190  pstrUsageOar,
200 };
201 const char * const ReportDescParserBase::sportsCtrlTitles2[] PROGMEM = {
222 };
223 const char * const ReportDescParserBase::gameTitles0[] PROGMEM = {
227 };
228 const char * const ReportDescParserBase::gameTitles1[] PROGMEM = {
254 };
255 const char * const ReportDescParserBase::genDevCtrlTitles[] PROGMEM = {
263 };
264 const char * const ReportDescParserBase::ledTitles[] PROGMEM = {
284  pstrUsageCAV,
285  pstrUsageCLV,
342 };
343 const char * const ReportDescParserBase::telTitles0 [] PROGMEM = {
351 };
352 const char * const ReportDescParserBase::telTitles1 [] PROGMEM = {
371 };
372 const char * const ReportDescParserBase::telTitles2 [] PROGMEM = {
377 };
378 const char * const ReportDescParserBase::telTitles3 [] PROGMEM = {
384 };
385 const char * const ReportDescParserBase::telTitles4 [] PROGMEM = {
401 };
402 const char * const ReportDescParserBase::telTitles5 [] PROGMEM = {
419 };
420 const char * const ReportDescParserBase::consTitles0[] PROGMEM = {
427 };
428 const char * const ReportDescParserBase::consTitles1[] PROGMEM = {
432 };
433 const char * const ReportDescParserBase::consTitles2[] PROGMEM = {
441 
442 };
443 const char * const ReportDescParserBase::consTitles3[] PROGMEM = {
453 };
454 const char * const ReportDescParserBase::consTitles4[] PROGMEM = {
462 };
463 const char * const ReportDescParserBase::consTitles5[] PROGMEM = {
501 };
502 const char * const ReportDescParserBase::consTitles6[] PROGMEM = {
534 };
535 const char * const ReportDescParserBase::consTitles7[] PROGMEM = {
544  pstrUsageMPX,
547 };
548 const char * const ReportDescParserBase::consTitles8[] PROGMEM = {
555 };
556 const char * const ReportDescParserBase::consTitles9[] PROGMEM = {
571 };
572 const char * const ReportDescParserBase::consTitlesA[] PROGMEM = {
579 };
580 const char * const ReportDescParserBase::consTitlesB[] PROGMEM = {
592 };
593 const char * const ReportDescParserBase::consTitlesC[] PROGMEM = {
599 };
600 const char * const ReportDescParserBase::consTitlesD[] PROGMEM = {
673 };
674 const char * const ReportDescParserBase::consTitlesE[] PROGMEM = {
816 };
817 const char * const ReportDescParserBase::digitTitles0[] PROGMEM = {
819  pstrUsagePen,
831 };
832 const char * const ReportDescParserBase::digitTitles1[] PROGMEM = {
836 
837 };
838 const char * const ReportDescParserBase::digitTitles2[] PROGMEM = {
844  pstrUsageTap,
862 };
863 const char * const ReportDescParserBase::aplphanumTitles0[] PROGMEM = {
866 };
867 const char * const ReportDescParserBase::aplphanumTitles1[] PROGMEM = {
887  pstrUsageRow,
914 };
915 const char * const ReportDescParserBase::aplphanumTitles2[] PROGMEM = {
937 };
938 const char * const ReportDescParserBase::medInstrTitles0[] PROGMEM = {
947 };
948 const char * const ReportDescParserBase::medInstrTitles1[] PROGMEM = {
954 };
955 const char * const ReportDescParserBase::medInstrTitles2[] PROGMEM = {
958 };
959 const char * const ReportDescParserBase::medInstrTitles3[] PROGMEM = {
970 };
971 const char * const ReportDescParserBase::medInstrTitles4[] PROGMEM = {
974 };
975 
976 void ReportDescParserBase::Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset) {
977  uint16_t cntdn = (uint16_t)len;
978  uint8_t *p = (uint8_t*)pbuf;
979 
980 
981  totalSize = 0;
982 
983  while (cntdn) {
984  //Serial.println("");
985  //PrintHex<uint16_t>(offset + len - cntdn);
986  //Serial.print(":");
987 
988  ParseItem(&p, &cntdn);
989 
990  //if (ParseItem(&p, &cntdn))
991  // return;
992  }
993  //USBTRACE2("Total:", totalSize);
994 }
995 
996 void ReportDescParserBase::PrintValue(uint8_t *p, uint8_t len) {
997  Notify(PSTR("("), 0x80);
998  for (; len; p++, len--)
999  PrintHex<uint8_t > (*p, 0x80);
1000  Notify(PSTR(")"), 0x80);
1001 }
1002 
1004  Notify(PSTR("("), 0x80);
1005  PrintHex<uint8_t > (data, 0x80);
1006  Notify(PSTR(")"), 0x80);
1007 }
1008 
1010  switch (prefix & (TYPE_MASK | TAG_MASK)) {
1011  case (TYPE_GLOBAL | TAG_GLOBAL_PUSH):
1012  Notify(PSTR("\r\nPush"), 0x80);
1013  break;
1014  case (TYPE_GLOBAL | TAG_GLOBAL_POP):
1015  Notify(PSTR("\r\nPop"), 0x80);
1016  break;
1018  Notify(PSTR("\r\nUsage Page"), 0x80);
1019  break;
1021  Notify(PSTR("\r\nLogical Min"), 0x80);
1022  break;
1024  Notify(PSTR("\r\nLogical Max"), 0x80);
1025  break;
1027  Notify(PSTR("\r\nPhysical Min"), 0x80);
1028  break;
1030  Notify(PSTR("\r\nPhysical Max"), 0x80);
1031  break;
1033  Notify(PSTR("\r\nUnit Exp"), 0x80);
1034  break;
1035  case (TYPE_GLOBAL | TAG_GLOBAL_UNIT):
1036  Notify(PSTR("\r\nUnit"), 0x80);
1037  break;
1039  Notify(PSTR("\r\nReport Size"), 0x80);
1040  break;
1042  Notify(PSTR("\r\nReport Count"), 0x80);
1043  break;
1045  Notify(PSTR("\r\nReport Id"), 0x80);
1046  break;
1047  case (TYPE_LOCAL | TAG_LOCAL_USAGE):
1048  Notify(PSTR("\r\nUsage"), 0x80);
1049  break;
1050  case (TYPE_LOCAL | TAG_LOCAL_USAGEMIN):
1051  Notify(PSTR("\r\nUsage Min"), 0x80);
1052  break;
1053  case (TYPE_LOCAL | TAG_LOCAL_USAGEMAX):
1054  Notify(PSTR("\r\nUsage Max"), 0x80);
1055  break;
1056  case (TYPE_MAIN | TAG_MAIN_COLLECTION):
1057  Notify(PSTR("\r\nCollection"), 0x80);
1058  break;
1060  Notify(PSTR("\r\nEnd Collection"), 0x80);
1061  break;
1062  case (TYPE_MAIN | TAG_MAIN_INPUT):
1063  Notify(PSTR("\r\nInput"), 0x80);
1064  break;
1065  case (TYPE_MAIN | TAG_MAIN_OUTPUT):
1066  Notify(PSTR("\r\nOutput"), 0x80);
1067  break;
1068  case (TYPE_MAIN | TAG_MAIN_FEATURE):
1069  Notify(PSTR("\r\nFeature"), 0x80);
1070  break;
1071  } // switch (**pp & (TYPE_MASK | TAG_MASK))
1072 }
1073 
1074 uint8_t ReportDescParserBase::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
1075  //uint8_t ret = enErrorSuccess;
1076 
1077  switch (itemParseState) {
1078  case 0:
1079  if (**pp == HID_LONG_ITEM_PREFIX)
1080  USBTRACE("\r\nLONG\r\n");
1081  else {
1082  uint8_t size = ((**pp) & DATA_SIZE_MASK);
1083 
1084  itemPrefix = (**pp);
1085  itemSize = 1 + ((size == DATA_SIZE_4) ? 4 : size);
1086 
1088  }
1089  (*pp)++;
1090  (*pcntdn)--;
1091  itemSize--;
1092  itemParseState = 1;
1093 
1094  if (!itemSize)
1095  break;
1096 
1097  if (!pcntdn)
1098  return enErrorIncomplete;
1099  case 1:
1100  //USBTRACE2("\r\niSz:",itemSize);
1101 
1104  itemParseState = 2;
1105  case 2:
1106  if (!valParser.Parse(pp, pcntdn))
1107  return enErrorIncomplete;
1108  itemParseState = 3;
1109  case 3:
1110  {
1111  uint8_t data = *((uint8_t*)varBuffer);
1112 
1113  switch (itemPrefix & (TYPE_MASK | TAG_MASK)) {
1114  case (TYPE_LOCAL | TAG_LOCAL_USAGE):
1115  if (pfUsage) {
1116  if (theBuffer.valueSize > 1)
1117  pfUsage(*((uint16_t*)varBuffer));
1118  else
1119  pfUsage(data);
1120  }
1121  break;
1123  rptSize = data;
1124  PrintByteValue(data);
1125  break;
1127  rptCount = data;
1128  PrintByteValue(data);
1129  break;
1135  case (TYPE_LOCAL | TAG_LOCAL_USAGEMIN):
1136  case (TYPE_LOCAL | TAG_LOCAL_USAGEMAX):
1138  case (TYPE_GLOBAL | TAG_GLOBAL_UNIT):
1140  break;
1141  case (TYPE_GLOBAL | TAG_GLOBAL_PUSH):
1142  case (TYPE_GLOBAL | TAG_GLOBAL_POP):
1143  break;
1145  SetUsagePage(data);
1146  PrintUsagePage(data);
1147  PrintByteValue(data);
1148  break;
1149  case (TYPE_MAIN | TAG_MAIN_COLLECTION):
1151  switch (data) {
1152  case 0x00:
1153  Notify(PSTR(" Physical"), 0x80);
1154  break;
1155  case 0x01:
1156  Notify(PSTR(" Application"), 0x80);
1157  break;
1158  case 0x02:
1159  Notify(PSTR(" Logical"), 0x80);
1160  break;
1161  case 0x03:
1162  Notify(PSTR(" Report"), 0x80);
1163  break;
1164  case 0x04:
1165  Notify(PSTR(" Named Array"), 0x80);
1166  break;
1167  case 0x05:
1168  Notify(PSTR(" Usage Switch"), 0x80);
1169  break;
1170  case 0x06:
1171  Notify(PSTR(" Usage Modifier"), 0x80);
1172  break;
1173  default:
1174  Notify(PSTR(" Vendor Defined("), 0x80);
1175  PrintHex<uint8_t > (data, 0x80);
1176  Notify(PSTR(")"), 0x80);
1177  }
1178  break;
1179  case (TYPE_MAIN | TAG_MAIN_INPUT):
1180  case (TYPE_MAIN | TAG_MAIN_OUTPUT):
1181  case (TYPE_MAIN | TAG_MAIN_FEATURE):
1182  totalSize += (uint16_t)rptSize * (uint16_t)rptCount;
1183  rptSize = 0;
1184  rptCount = 0;
1185  Notify(PSTR("("), 0x80);
1186  PrintBin<uint8_t > (data, 0x80);
1187  Notify(PSTR(")"), 0x80);
1188  break;
1189  } // switch (**pp & (TYPE_MASK | TAG_MASK))
1190  }
1191  } // switch (itemParseState)
1192  itemParseState = 0;
1193  return enErrorSuccess;
1194 }
1195 
1203  NULL, // Keyboard/Keypad
1210  NULL, // Reserved
1211  NULL, // PID
1212  NULL // Unicode
1213 };
1214 
1216  pfUsage = NULL;
1217 
1218  if (page > 0x00 && page < 0x11)
1219  pfUsage = /*(UsagePageFunc)pgm_read_word*/(usagePageFunctions[page - 1]);
1220  //else if (page > 0x7f && page < 0x84)
1221  // Notify(pstrUsagePageMonitor);
1222  //else if (page > 0x83 && page < 0x8c)
1223  // Notify(pstrUsagePagePower);
1224  //else if (page > 0x8b && page < 0x92)
1225  // Notify((char*)pgm_read_word(&usagePageTitles1[page - 0x8c]));
1226  //else if (page > 0xfeff && page <= 0xffff)
1227  // Notify(pstrUsagePageVendorDefined);
1228  else
1229  switch (page) {
1230  case 0x14:
1232  break;
1233  case 0x40:
1235  break;
1236  }
1237 }
1238 
1240  Notify(pstrSpace, 0x80);
1241 
1242  if (page > 0x00 && page < 0x11)
1243  Notify((char*)pgm_read_word(&usagePageTitles0[page - 1]), 0x80);
1244  else if (page > 0x7f && page < 0x84)
1246  else if (page > 0x83 && page < 0x8c)
1247  Notify(pstrUsagePagePower, 0x80);
1248  else if (page > 0x8b && page < 0x92)
1249  Notify((char*)pgm_read_word(&usagePageTitles1[page - 0x8c]), 0x80);
1250  else if (page > 0xfeff && page <= 0xffff)
1252  else
1253  switch (page) {
1254  case 0x14:
1256  break;
1257  case 0x40:
1259  break;
1260  default:
1262  }
1263 }
1264 
1266  Notify(pstrSpace, 0x80);
1267  Notify(PSTR("Btn"), 0x80);
1268  PrintHex<uint16_t > (usage, 0x80);
1269  Notify(PSTR("\r\n"), 0x80);
1270  //Serial.print(usage, HEX);
1271 }
1272 
1274  Notify(pstrSpace, 0x80);
1275  Notify(PSTR("Inst"), 0x80);
1276  // Sorry, HEX for now...
1277  PrintHex<uint16_t > (usage, 0x80);
1278  Notify(PSTR("\r\n"), 0x80);
1279  //Serial.print(usage, DEC);
1280 }
1281 
1283  Notify(pstrSpace, 0x80);
1284 
1285  if (usage > 0x00 && usage < 0x0a)
1286  Notify((char*)pgm_read_word(&genDesktopTitles0[usage - 1]), 0x80);
1287  else if (usage > 0x2f && usage < 0x49)
1288  Notify((char*)pgm_read_word(&genDesktopTitles1[usage - 0x30]), 0x80);
1289  else if (usage > 0x7f && usage < 0x94)
1290  Notify((char*)pgm_read_word(&genDesktopTitles2[usage - 0x80]), 0x80);
1291  else if (usage > 0x9f && usage < 0xa9)
1292  Notify((char*)pgm_read_word(&genDesktopTitles3[usage - 0xa0]), 0x80);
1293  else if (usage > 0xaf && usage < 0xb8)
1294  Notify((char*)pgm_read_word(&genDesktopTitles4[usage - 0xb0]), 0x80);
1295  else
1297 }
1298 
1300  Notify(pstrSpace, 0x80);
1301 
1302  if (usage > 0x00 && usage < 0x0d)
1303  Notify((char*)pgm_read_word(&simuTitles0[usage - 1]), 0x80);
1304  else if (usage > 0x1f && usage < 0x26)
1305  Notify((char*)pgm_read_word(&simuTitles1[usage - 0x20]), 0x80);
1306  else if (usage > 0xaf && usage < 0xd1)
1307  Notify((char*)pgm_read_word(&simuTitles2[usage - 0xb0]), 0x80);
1308  else
1310 }
1311 
1313  Notify(pstrSpace, 0x80);
1314 
1315  if (usage > 0x00 && usage < 0x0b)
1316  Notify((char*)pgm_read_word(&vrTitles0[usage - 1]), 0x80);
1317  else if (usage > 0x1f && usage < 0x22)
1318  Notify((char*)pgm_read_word(&vrTitles1[usage - 0x20]), 0x80);
1319  else
1321 }
1322 
1324  Notify(pstrSpace, 0x80);
1325 
1326  if (usage > 0x00 && usage < 0x05)
1327  Notify((char*)pgm_read_word(&sportsCtrlTitles0[usage - 1]), 0x80);
1328  else if (usage > 0x2f && usage < 0x3a)
1329  Notify((char*)pgm_read_word(&sportsCtrlTitles1[usage - 0x30]), 0x80);
1330  else if (usage > 0x4f && usage < 0x64)
1331  Notify((char*)pgm_read_word(&sportsCtrlTitles2[usage - 0x50]), 0x80);
1332  else
1334 }
1335 
1337  Notify(pstrSpace, 0x80);
1338 
1339  if (usage > 0x00 && usage < 0x04)
1340  Notify((char*)pgm_read_word(&gameTitles0[usage - 1]), 0x80);
1341  else if (usage > 0x1f && usage < 0x3a)
1342  Notify((char*)pgm_read_word(&gameTitles1[usage - 0x20]), 0x80);
1343  else
1345 }
1346 
1348  Notify(pstrSpace, 0x80);
1349 
1350  if (usage > 0x1f && usage < 0x27)
1351  Notify((char*)pgm_read_word(&genDevCtrlTitles[usage - 0x20]), 0x80);
1352  else
1354 }
1355 
1357  Notify(pstrSpace, 0x80);
1358 
1359  if (usage > 0x00 && usage < 0x4e)
1360  Notify((char*)pgm_read_word(&ledTitles[usage - 1]), 0x80);
1361  else
1363 }
1364 
1366  Notify(pstrSpace, 0x80);
1367 
1368  if (usage > 0x00 && usage < 0x08)
1369  Notify((char*)pgm_read_word(&telTitles0[usage - 1]), 0x80);
1370  else if (usage > 0x1f && usage < 0x32)
1371  Notify((char*)pgm_read_word(&telTitles1[usage - 0x1f]), 0x80);
1372  else if (usage > 0x4f && usage < 0x54)
1373  Notify((char*)pgm_read_word(&telTitles2[usage - 0x4f]), 0x80);
1374  else if (usage > 0x6f && usage < 0x75)
1375  Notify((char*)pgm_read_word(&telTitles3[usage - 0x6f]), 0x80);
1376  else if (usage > 0x8f && usage < 0x9f)
1377  Notify((char*)pgm_read_word(&telTitles4[usage - 0x8f]), 0x80);
1378  else if (usage > 0xaf && usage < 0xc0)
1379  Notify((char*)pgm_read_word(&telTitles5[usage - 0xaf]), 0x80);
1380  else
1382 }
1383 
1385  Notify(pstrSpace, 0x80);
1386 
1387  if (usage > 0x00 && usage < 0x07)
1388  Notify((char*)pgm_read_word(&consTitles0[usage - 1]), 0x80);
1389  else if (usage > 0x1f && usage < 0x23)
1390  Notify((char*)pgm_read_word(&consTitles1[usage - 0x1f]), 0x80);
1391  else if (usage > 0x2f && usage < 0x37)
1392  Notify((char*)pgm_read_word(&consTitles2[usage - 0x2f]), 0x80);
1393  else if (usage > 0x3f && usage < 0x49)
1394  Notify((char*)pgm_read_word(&consTitles3[usage - 0x3f]), 0x80);
1395  else if (usage > 0x5f && usage < 0x67)
1396  Notify((char*)pgm_read_word(&consTitles4[usage - 0x5f]), 0x80);
1397  else if (usage > 0x7f && usage < 0xa5)
1398  Notify((char*)pgm_read_word(&consTitles5[usage - 0x7f]), 0x80);
1399  else if (usage > 0xaf && usage < 0xcf)
1400  Notify((char*)pgm_read_word(&consTitles6[usage - 0xaf]), 0x80);
1401  else if (usage > 0xdf && usage < 0xeb)
1402  Notify((char*)pgm_read_word(&consTitles7[usage - 0xdf]), 0x80);
1403  else if (usage > 0xef && usage < 0xf6)
1404  Notify((char*)pgm_read_word(&consTitles8[usage - 0xef]), 0x80);
1405  else if (usage > 0xff && usage < 0x10e)
1406  Notify((char*)pgm_read_word(&consTitles9[usage - 0xff]), 0x80);
1407  else if (usage > 0x14f && usage < 0x156)
1408  Notify((char*)pgm_read_word(&consTitlesA[usage - 0x14f]), 0x80);
1409  else if (usage > 0x15f && usage < 0x16b)
1410  Notify((char*)pgm_read_word(&consTitlesB[usage - 0x15f]), 0x80);
1411  else if (usage > 0x16f && usage < 0x175)
1412  Notify((char*)pgm_read_word(&consTitlesC[usage - 0x16f]), 0x80);
1413  else if (usage > 0x17f && usage < 0x1c8)
1414  Notify((char*)pgm_read_word(&consTitlesD[usage - 0x17f]), 0x80);
1415  else if (usage > 0x1ff && usage < 0x29d)
1416  Notify((char*)pgm_read_word(&consTitlesE[usage - 0x1ff]), 0x80);
1417  else
1419 }
1420 
1422  Notify(pstrSpace, 0x80);
1423 
1424  if (usage > 0x00 && usage < 0x0e)
1425  Notify((char*)pgm_read_word(&digitTitles0[usage - 1]), 0x80);
1426  else if (usage > 0x1f && usage < 0x23)
1427  Notify((char*)pgm_read_word(&digitTitles1[usage - 0x1f]), 0x80);
1428  else if (usage > 0x2f && usage < 0x47)
1429  Notify((char*)pgm_read_word(&digitTitles2[usage - 0x2f]), 0x80);
1430  else
1432 }
1433 
1435  Notify(pstrSpace, 0x80);
1436 
1437  if (usage > 0x00 && usage < 0x03)
1438  Notify((char*)pgm_read_word(&aplphanumTitles0[usage - 1]), 0x80);
1439  else if (usage > 0x1f && usage < 0x4e)
1440  Notify((char*)pgm_read_word(&aplphanumTitles1[usage - 0x1f]), 0x80);
1441  else if (usage > 0x7f && usage < 0x96)
1442  Notify((char*)pgm_read_word(&digitTitles2[usage - 0x80]), 0x80);
1443  else
1445 }
1446 
1448  Notify(pstrSpace, 0x80);
1449 
1450  if (usage == 1)
1452  else if (usage > 0x1f && usage < 0x28)
1453  Notify((char*)pgm_read_word(&medInstrTitles0[usage - 0x1f]), 0x80);
1454  else if (usage > 0x3f && usage < 0x45)
1455  Notify((char*)pgm_read_word(&medInstrTitles1[usage - 0x40]), 0x80);
1456  else if (usage > 0x5f && usage < 0x62)
1457  Notify((char*)pgm_read_word(&medInstrTitles2[usage - 0x60]), 0x80);
1458  else if (usage == 0x70)
1460  else if (usage > 0x7f && usage < 0x8a)
1461  Notify((char*)pgm_read_word(&medInstrTitles3[usage - 0x80]), 0x80);
1462  else if (usage > 0x9f && usage < 0xa2)
1463  Notify((char*)pgm_read_word(&medInstrTitles4[usage - 0xa0]), 0x80);
1464  else
1466 }
1467 
1468 uint8_t ReportDescParser2::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
1469  //uint8_t ret = enErrorSuccess;
1470 
1471  switch (itemParseState) {
1472  case 0:
1473  if (**pp == HID_LONG_ITEM_PREFIX)
1474  USBTRACE("\r\nLONG\r\n");
1475  else {
1476  uint8_t size = ((**pp) & DATA_SIZE_MASK);
1477  itemPrefix = (**pp);
1478  itemSize = 1 + ((size == DATA_SIZE_4) ? 4 : size);
1479  }
1480  (*pp)++;
1481  (*pcntdn)--;
1482  itemSize--;
1483  itemParseState = 1;
1484 
1485  if (!itemSize)
1486  break;
1487 
1488  if (!pcntdn)
1489  return enErrorIncomplete;
1490  case 1:
1493  itemParseState = 2;
1494  case 2:
1495  if (!valParser.Parse(pp, pcntdn))
1496  return enErrorIncomplete;
1497  itemParseState = 3;
1498  case 3:
1499  {
1500  uint8_t data = *((uint8_t*)varBuffer);
1501 
1502  switch (itemPrefix & (TYPE_MASK | TAG_MASK)) {
1503  case (TYPE_LOCAL | TAG_LOCAL_USAGE):
1504  if (pfUsage) {
1505  if (theBuffer.valueSize > 1)
1506  pfUsage(*((uint16_t*)varBuffer));
1507  else
1508  pfUsage(data);
1509  }
1510  break;
1512  rptSize = data;
1513  break;
1515  rptCount = data;
1516  break;
1518  rptId = data;
1519  break;
1520  case (TYPE_LOCAL | TAG_LOCAL_USAGEMIN):
1521  useMin = data;
1522  break;
1523  case (TYPE_LOCAL | TAG_LOCAL_USAGEMAX):
1524  useMax = data;
1525  break;
1527  SetUsagePage(data);
1528  break;
1529  case (TYPE_MAIN | TAG_MAIN_OUTPUT):
1530  case (TYPE_MAIN | TAG_MAIN_FEATURE):
1531  rptSize = 0;
1532  rptCount = 0;
1533  useMin = 0;
1534  useMax = 0;
1535  break;
1536  case (TYPE_MAIN | TAG_MAIN_INPUT):
1537  OnInputItem(data);
1538 
1539  totalSize += (uint16_t)rptSize * (uint16_t)rptCount;
1540 
1541  rptSize = 0;
1542  rptCount = 0;
1543  useMin = 0;
1544  useMax = 0;
1545  break;
1546  } // switch (**pp & (TYPE_MASK | TAG_MASK))
1547  }
1548  } // switch (itemParseState)
1549  itemParseState = 0;
1550  return enErrorSuccess;
1551 }
1552 
1553 void ReportDescParser2::OnInputItem(uint8_t itm) {
1554  uint8_t byte_offset = (totalSize >> 3); // calculate offset to the next unhandled byte i = (int)(totalCount / 8);
1555  uint32_t tmp = (byte_offset << 3);
1556  uint8_t bit_offset = totalSize - tmp; // number of bits in the current byte already handled
1557  uint8_t *p = pBuf + byte_offset; // current byte pointer
1558 
1559  if (bit_offset)
1560  *p >>= bit_offset;
1561 
1562  uint8_t usage = useMin;
1563 
1564  bool print_usemin_usemax = ((useMin < useMax) && ((itm & 3) == 2) && pfUsage) ? true : false;
1565 
1566  uint8_t bits_of_byte = 8;
1567 
1568  // for each field in field array defined by rptCount
1569  for (uint8_t field = 0; field < rptCount; field++, usage++) {
1570 
1571  union {
1572  uint8_t bResult[4];
1573  uint16_t wResult[2];
1574  uint32_t dwResult;
1575  } result;
1576 
1577  result.dwResult = 0;
1578  uint8_t mask = 0;
1579 
1580  if (print_usemin_usemax)
1581  pfUsage(usage);
1582 
1583  // bits_left - number of bits in the field(array of fields, depending on Report Count) left to process
1584  // bits_of_byte - number of bits in current byte left to process
1585  // bits_to_copy - number of bits to copy to result buffer
1586 
1587  // for each bit in a field
1588  for (uint8_t bits_left = rptSize, bits_to_copy = 0; bits_left;
1589  bits_left -= bits_to_copy) {
1590  bits_to_copy = (bits_left > bits_of_byte) ? bits_of_byte : bits_left;
1591 
1592  result.dwResult <<= bits_to_copy; // Result buffer is shifted by the number of bits to be copied into it
1593 
1594  uint8_t val = *p;
1595 
1596  val >>= (8 - bits_of_byte); // Shift by the number of bits already processed
1597 
1598  mask = 0;
1599 
1600  for (uint8_t j = bits_to_copy; j; j--) {
1601  mask <<= 1;
1602  mask |= 1;
1603  }
1604 
1605  result.bResult[0] = (result.bResult[0] | (val & mask));
1606 
1607  bits_of_byte -= bits_to_copy;
1608 
1609  if (bits_of_byte < 1) {
1610  bits_of_byte = 8;
1611  p++;
1612  }
1613  }
1614  PrintByteValue(result.dwResult);
1615  }
1616  Notify(PSTR("\r\n"), 0x80);
1617 }
1618 
1619 void UniversalReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
1620  ReportDescParser2 prs(len, buf);
1621 
1622  uint8_t ret = hid->GetReportDescr(0, &prs);
1623 
1624  if (ret)
1625  ErrorMessage<uint8_t > (PSTR("GetReportDescr-2"), ret);
1626 }