Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

hardware_info.c 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. /* 硬盘温度 */
  2. // #include <unistd.h>
  3. // #include <stdio.h>
  4. // #include <string.h>
  5. #include <getopt.h>
  6. // #include <unistd.h>
  7. // #include <stdlib.h>
  8. #include <sys/ioctl.h>
  9. #include <linux/hdreg.h>
  10. #include <scsi/scsi.h>
  11. #include <scsi/sg.h>
  12. #include <scsi/scsi_ioctl.h>
  13. #include <fcntl.h>
  14. #define DEF(X) 1
  15. static int debug;
  16. #define CPU_TEMP_FILE1 "/sys/class/hwmon/hwmon1/temp3_input"
  17. #define CPU_TEMP_FILE2 "/sys/class/therma/temp"
  18. int get_cpu_temp(int file_type)
  19. {
  20. int cpu_temp;
  21. /* cpu温度获取 */
  22. FILE *fp = fopen(file_type ? CPU_TEMP_FILE1 : CPU_TEMP_FILE2, "r");
  23. if (NULL == fp)
  24. {
  25. printf("open file failed,%s\n", strerror(errno));
  26. }
  27. else
  28. {
  29. // rewind(fp);
  30. fscanf(fp, "%d", &cpu_temp);
  31. fclose(fp);
  32. }
  33. return cpu_temp / 1000;
  34. }
  35. #if DEF(ATA)
  36. typedef unsigned short u16;
  37. #define swapb(x) \
  38. ({ \
  39. u16 __x = (x); \
  40. (x) = ((u16)( \
  41. (((u16)(__x) & (u16)0x00ffU) << 8) | \
  42. (((u16)(__x) & (u16)0xff00U) >> 8) )); \
  43. })
  44. #define GBUF_SIZE 65535
  45. #define DEFAULT_ATTRIBUTE_ID 194
  46. #define DEFAULT_ATTRIBUTE_ID2 190
  47. #define SBUFF_SIZE 512
  48. static char sbuff[SBUFF_SIZE];
  49. static int ata_probe(int device)
  50. {
  51. if (device == -1 || ioctl(device, HDIO_GET_IDENTITY, sbuff))
  52. {
  53. return 0;
  54. }
  55. else
  56. {
  57. return 1;
  58. }
  59. }
  60. int ata_enable_smart(int device)
  61. {
  62. unsigned char cmd[4] = {WIN_SMART, 0, SMART_ENABLE, 0};
  63. return ioctl(device, HDIO_DRIVE_CMD, cmd);
  64. }
  65. int ata_get_smart_values(int device, unsigned char *buff)
  66. {
  67. unsigned char cmd[516] = {WIN_SMART, 0, SMART_READ_VALUES, 1};
  68. int ret;
  69. ret = ioctl(device, HDIO_DRIVE_CMD, cmd);
  70. if (ret)
  71. {
  72. return ret;
  73. }
  74. memcpy(buff, cmd + 4, 512);
  75. return 0;
  76. }
  77. static char *ata_model(int device)
  78. {
  79. if (device == -1 || ioctl(device, HDIO_GET_IDENTITY, sbuff))
  80. {
  81. return strdup("unknown");
  82. }
  83. else
  84. {
  85. return strdup((char *)((u16 *)sbuff + 27));
  86. }
  87. }
  88. unsigned char *ata_search_temperature(const unsigned char *smart_data, int attribute_id)
  89. {
  90. int i, n;
  91. n = 3;
  92. i = 0;
  93. if (debug)
  94. {
  95. printf("============ ata ============\n");
  96. }
  97. while ((debug || *(smart_data + n) != attribute_id) && i < 30)
  98. {
  99. if (debug && *(smart_data + n))
  100. printf("field(%d)\t = %d\t(0x%02x)\n",
  101. (int)*(smart_data + n),
  102. (int)*(smart_data + n + 3),
  103. *(smart_data + n + 3));
  104. n += 12;
  105. i++;
  106. }
  107. if (i >= 30)
  108. {
  109. return NULL;
  110. }
  111. else
  112. {
  113. return (unsigned char *)(smart_data + n);
  114. }
  115. }
  116. int ata_get_temperature(int fd)
  117. {
  118. unsigned char values[512]/*, thresholds[512]*/;
  119. unsigned char *field;
  120. int i;
  121. unsigned short *p;
  122. if (ata_enable_smart(fd) != 0)
  123. {
  124. printf("ATA S.M.A.R.T. not available!\n");
  125. return -1;
  126. }
  127. if (ata_get_smart_values(fd, values))
  128. {
  129. printf("ATA Enable S.M.A.R.T. err!\n");
  130. return -1;
  131. }
  132. p = (u16 *)values;
  133. for (i = 0; i < 256; i++)
  134. {
  135. swapb(*(p + i));
  136. }
  137. /* get SMART threshold values */
  138. /*
  139. if(get_smart_threshold_values(fd, thresholds)) {
  140. perror("ioctl");
  141. exit(3);
  142. }
  143. p = (u16*)thresholds;
  144. for(i = 0; i < 256; i++) {
  145. swapb(*(p+i));
  146. }
  147. */
  148. /* temperature */
  149. field = ata_search_temperature(values, DEFAULT_ATTRIBUTE_ID);
  150. if (!field)
  151. {
  152. field = ata_search_temperature(values, DEFAULT_ATTRIBUTE_ID2);
  153. }
  154. if (field)
  155. {
  156. return *(field + 3);
  157. }
  158. else
  159. {
  160. return -1;
  161. }
  162. }
  163. #endif
  164. #if DEF(SCSI)
  165. #define TEMPERATURE_PAGE 0x0d
  166. #define CDB_12_HDR_SIZE 14
  167. #define CDB_12_MAX_DATA_SIZE 0xffffffff
  168. #define CDB_6_HDR_SIZE 14
  169. #define CDB_6_MAX_DATA_SIZE 0xff
  170. #define DEXCPT_DISABLE 0xf7
  171. #define DEXCPT_ENABLE 0x08
  172. #define EWASC_ENABLE 0x10
  173. #define EWASC_DISABLE 0xef
  174. #define GBUF_SIZE 65535
  175. #define MODE_DATA_HDR_SIZE 12
  176. #define SMART_SUPPORT 0x00
  177. struct cdb10hdr
  178. {
  179. unsigned int inbufsize;
  180. unsigned int outbufsize;
  181. unsigned int cdb[10];
  182. };
  183. struct cdb6hdr
  184. {
  185. unsigned int inbufsize;
  186. unsigned int outbufsize;
  187. unsigned char cdb[6];
  188. };
  189. static void scsi_fixstring(unsigned char *s, int bytecount)
  190. {
  191. unsigned char *p;
  192. unsigned char *end;
  193. p = s;
  194. end = s + bytecount;
  195. /* strip leading blanks */
  196. while (s != end && *s == ' ')
  197. {
  198. ++s;
  199. }
  200. /* compress internal blanks and strip trailing blanks */
  201. while (s != end && *s)
  202. {
  203. if (*s++ != ' ' || (s != end && *s && *s != ' '))
  204. {
  205. *p++ = *(s - 1);
  206. }
  207. }
  208. /* wipe out trailing garbage */
  209. while (p != end)
  210. {
  211. *p++ = '\0';
  212. }
  213. }
  214. int scsi_SG_IO(int device, unsigned char *cdb, int cdb_len, unsigned char *buffer, int buffer_len, unsigned char *sense,
  215. unsigned char sense_len, int dxfer_direction)
  216. {
  217. struct sg_io_hdr io_hdr;
  218. memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
  219. io_hdr.interface_id = 'S';
  220. io_hdr.cmdp = cdb;
  221. io_hdr.cmd_len = cdb_len;
  222. io_hdr.dxfer_len = buffer_len;
  223. io_hdr.dxferp = buffer;
  224. io_hdr.mx_sb_len = sense_len;
  225. io_hdr.sbp = sense;
  226. io_hdr.dxfer_direction = dxfer_direction;
  227. io_hdr.timeout = 3000; /* 3 seconds should be ample */
  228. return ioctl(device, SG_IO, &io_hdr);
  229. }
  230. int scsi_SEND_COMMAND(int device, unsigned char *cdb, int cdb_len, unsigned char *buffer, int buffer_len,
  231. int dxfer_direction)
  232. {
  233. unsigned char buf[2048];
  234. unsigned int inbufsize, outbufsize, ret;
  235. switch (dxfer_direction)
  236. {
  237. case SG_DXFER_FROM_DEV:
  238. inbufsize = 0;
  239. outbufsize = buffer_len;
  240. break;
  241. case SG_DXFER_TO_DEV:
  242. inbufsize = buffer_len;
  243. outbufsize = 0;
  244. break;
  245. default:
  246. inbufsize = 0;
  247. outbufsize = 0;
  248. break;
  249. }
  250. memcpy(buf, &inbufsize, sizeof(inbufsize));
  251. memcpy(buf + sizeof(inbufsize), &outbufsize, sizeof(outbufsize));
  252. memcpy(buf + sizeof(inbufsize) + sizeof(outbufsize), cdb, cdb_len);
  253. memcpy(buf + sizeof(inbufsize) + sizeof(outbufsize) + cdb_len, buffer, buffer_len);
  254. ret = ioctl(device, SCSI_IOCTL_SEND_COMMAND, buf);
  255. memcpy(buffer, buf + sizeof(inbufsize) + sizeof(outbufsize), buffer_len);
  256. return ret;
  257. }
  258. int scsi_command(int device, unsigned char *cdb, int cdb_len, unsigned char *buffer, int buffer_len,
  259. int dxfer_direction)
  260. {
  261. static int SG_IO_supported = -1;
  262. int ret;
  263. if (SG_IO_supported == 1)
  264. {
  265. return scsi_SG_IO(device, cdb, cdb_len, buffer, buffer_len, NULL, 0, dxfer_direction);
  266. }
  267. else if (SG_IO_supported == 0)
  268. {
  269. return scsi_SEND_COMMAND(device, cdb, cdb_len, buffer, buffer_len, dxfer_direction);
  270. }
  271. else
  272. {
  273. ret = scsi_SG_IO(device, cdb, cdb_len, buffer, buffer_len, NULL, 0, dxfer_direction);
  274. if (ret == 0)
  275. {
  276. SG_IO_supported = 1;
  277. return ret;
  278. }
  279. else
  280. {
  281. SG_IO_supported = 0;
  282. return scsi_SEND_COMMAND(device, cdb, cdb_len, buffer, buffer_len, dxfer_direction);
  283. }
  284. }
  285. }
  286. int scsi_inquiry(int device, unsigned char *buffer)
  287. {
  288. unsigned char cdb[6];
  289. memset(cdb, 0, sizeof(cdb));
  290. cdb[0] = INQUIRY;
  291. cdb[4] = 36; /* should be 36 for unsafe devices (like USB mass storage stuff)
  292. * otherwise they can lock up! SPC sections 7.4 and 8.6 */
  293. if (scsi_command(device, cdb, sizeof(cdb), buffer, cdb[4], SG_DXFER_FROM_DEV) != 0)
  294. {
  295. return 1;
  296. }
  297. else
  298. {
  299. scsi_fixstring(buffer + 8, 24);
  300. return 0;
  301. }
  302. }
  303. unsigned char modesense(int device, unsigned char pagenum, unsigned char *pBuf)
  304. {
  305. unsigned char tBuf[CDB_6_MAX_DATA_SIZE + CDB_6_HDR_SIZE];
  306. struct cdb6hdr *ioctlhdr;
  307. unsigned char status;
  308. memset(&tBuf, 0, CDB_6_MAX_DATA_SIZE + CDB_6_HDR_SIZE);
  309. ioctlhdr = (struct cdb6hdr *)&tBuf;
  310. ioctlhdr->inbufsize = 0;
  311. ioctlhdr->outbufsize = 0xff;
  312. ioctlhdr->cdb[0] = MODE_SENSE;
  313. ioctlhdr->cdb[1] = 0x00;
  314. ioctlhdr->cdb[2] = pagenum;
  315. ioctlhdr->cdb[3] = 0x00;
  316. ioctlhdr->cdb[4] = CDB_6_MAX_DATA_SIZE;
  317. ioctlhdr->cdb[5] = 0x00;
  318. status = ioctl(device, 1, &tBuf);
  319. memcpy(pBuf, &tBuf[8], 256);
  320. return status;
  321. }
  322. unsigned char modeselect(int device, unsigned char pagenum, unsigned char *pBuf)
  323. {
  324. struct cdb6hdr *ioctlhdr;
  325. unsigned char tBuf[CDB_6_MAX_DATA_SIZE + CDB_6_HDR_SIZE];
  326. unsigned char status;
  327. memset(&tBuf, 0, CDB_6_MAX_DATA_SIZE + CDB_6_HDR_SIZE);
  328. ioctlhdr = (struct cdb6hdr *)&tBuf;
  329. ioctlhdr->inbufsize = pBuf[0] + 1;
  330. ioctlhdr->outbufsize = 0;
  331. ioctlhdr->cdb[0] = MODE_SELECT;
  332. ioctlhdr->cdb[1] = 0x11;
  333. ioctlhdr->cdb[2] = 0x00;
  334. ioctlhdr->cdb[3] = 0x00;
  335. ioctlhdr->cdb[4] = pBuf[0] + 1;
  336. ioctlhdr->cdb[5] = 0x00;
  337. tBuf[CDB_6_HDR_SIZE + 3] = 0x08;
  338. tBuf[CDB_6_HDR_SIZE + 10] = 0x02;
  339. memcpy(&tBuf[CDB_6_HDR_SIZE + MODE_DATA_HDR_SIZE],
  340. pBuf + MODE_DATA_HDR_SIZE,
  341. pBuf[0] - MODE_DATA_HDR_SIZE + 1);
  342. tBuf[26] &= 0x3f;
  343. status = ioctl(device, 1, &tBuf);
  344. return status;
  345. }
  346. unsigned char scsi_smart_mode_page1c_handler(int device, unsigned char setting, unsigned char *retval)
  347. {
  348. char tBuf[CDB_6_MAX_DATA_SIZE];
  349. if (modesense(device, 0x1c, (unsigned char *)&tBuf) != 0)
  350. {
  351. return 1;
  352. }
  353. switch (setting)
  354. {
  355. case DEXCPT_DISABLE:
  356. tBuf[14] &= 0xf7;
  357. tBuf[15] = 0x04;
  358. break;
  359. case DEXCPT_ENABLE:
  360. tBuf[14] |= 0x08;
  361. break;
  362. case EWASC_ENABLE:
  363. tBuf[14] |= 0x10;
  364. break;
  365. case EWASC_DISABLE:
  366. tBuf[14] &= 0xef;
  367. break;
  368. case SMART_SUPPORT:
  369. *retval = tBuf[14] & 0x08;
  370. return 0;
  371. break;
  372. default:
  373. return 1;
  374. }
  375. if (modeselect(device, 0x1c, (unsigned char *)&tBuf) != 0)
  376. {
  377. return 1;
  378. }
  379. return 0;
  380. }
  381. unsigned char log_sense(int device, unsigned char pagenum, unsigned char *pBuf)
  382. {
  383. struct cdb10hdr *ioctlhdr;
  384. unsigned char tBuf[1024 + CDB_12_HDR_SIZE];
  385. unsigned char status;
  386. memset(&tBuf, 0, 255);
  387. ioctlhdr = (struct cdb10hdr *)tBuf;
  388. ioctlhdr->inbufsize = 0;
  389. ioctlhdr->outbufsize = 1024;
  390. ioctlhdr->cdb[0] = LOG_SENSE;
  391. ioctlhdr->cdb[1] = 0x00;
  392. ioctlhdr->cdb[2] = 0x40 | pagenum;
  393. ioctlhdr->cdb[3] = 0x00;
  394. ioctlhdr->cdb[4] = 0x00;
  395. ioctlhdr->cdb[5] = 0x00;
  396. ioctlhdr->cdb[6] = 0x00;
  397. ioctlhdr->cdb[7] = 0x04;
  398. ioctlhdr->cdb[8] = 0x00;
  399. ioctlhdr->cdb[9] = 0x00;
  400. status = ioctl(device, 1, &tBuf);
  401. memcpy(pBuf, &tBuf[8], 1024);
  402. return status;
  403. }
  404. static int scsi_probe(int device)
  405. {
  406. int bus_num;
  407. if (ioctl(device, SCSI_IOCTL_GET_BUS_NUMBER, &bus_num))
  408. {
  409. return 0;
  410. }
  411. else
  412. {
  413. return 1;
  414. }
  415. }
  416. static char *scsi_model(int device)
  417. {
  418. unsigned char buf[36];
  419. if (scsi_inquiry(device, buf) != 0)
  420. {
  421. return strdup("unknown");
  422. }
  423. else
  424. {
  425. return strdup(buf + 8);
  426. }
  427. }
  428. int scsi_get_temperature(int fd)
  429. {
  430. unsigned char buf[1024];
  431. unsigned char smartsupport;
  432. char gBuf[GBUF_SIZE];
  433. if (0 != scsi_smart_mode_page1c_handler(fd, SMART_SUPPORT, &smartsupport))
  434. {
  435. printf("SCSI S.M.A.R.T. not available!\n");
  436. return -1;
  437. }
  438. if (0 != scsi_smart_mode_page1c_handler(fd, DEXCPT_DISABLE, NULL))
  439. {
  440. printf("SCSI Enable S.M.A.R.T. err!\n");
  441. return -1;
  442. }
  443. if (log_sense(fd, TEMPERATURE_PAGE, buf) != 0)
  444. {
  445. printf("SCSI read err!\n");
  446. return -1;
  447. }
  448. return buf[9];
  449. }
  450. #endif
  451. #if DEF(SATA)
  452. #ifndef ATA_16
  453. /* Values for T10/04-262r7 */
  454. #define ATA_16 0x85 /* 16-byte pass-thru */
  455. #endif
  456. int sata_pass_thru(int device, unsigned char *cmd, unsigned char *buffer)
  457. {
  458. unsigned char cdb[16];
  459. unsigned char sense[32];
  460. int dxfer_direction;
  461. int ret;
  462. memset(cdb, 0, sizeof(cdb));
  463. cdb[0] = ATA_16;
  464. if (cmd[3])
  465. {
  466. cdb[1] = (4 << 1); /* PIO Data-in */
  467. cdb[2] = 0x2e; /* no off.line, cc, read from dev, lock count in sector count field */
  468. dxfer_direction = SG_DXFER_FROM_DEV;
  469. }
  470. else
  471. {
  472. cdb[1] = (3 << 1); /* Non-data */
  473. cdb[2] = 0x20; /* cc */
  474. dxfer_direction = SG_DXFER_NONE;
  475. }
  476. cdb[4] = cmd[2];
  477. if (cmd[0] == WIN_SMART)
  478. {
  479. cdb[6] = cmd[3];
  480. cdb[8] = cmd[1];
  481. cdb[10] = 0x4f;
  482. cdb[12] = 0xc2;
  483. }
  484. else
  485. {
  486. cdb[6] = cmd[1];
  487. }
  488. cdb[14] = cmd[0];
  489. ret = scsi_SG_IO(device, cdb, sizeof(cdb), buffer, cmd[3] * 512, sense, sizeof(sense), dxfer_direction);
  490. /* Verify SATA magics */
  491. if (sense[0] != 0x72)
  492. {
  493. return 1;
  494. }
  495. else
  496. {
  497. return ret;
  498. }
  499. }
  500. void sata_fixstring(unsigned char *s, int bytecount)
  501. {
  502. unsigned char *p;
  503. unsigned char *end;
  504. p = s;
  505. end = &s[bytecount & ~1]; /* bytecount must be even */
  506. /* convert from big-endian to host byte order */
  507. for (p = end; p != s;)
  508. {
  509. unsigned short *pp = (unsigned short *)(p -= 2);
  510. *pp = ntohs(*pp);
  511. }
  512. /* strip leading blanks */
  513. while (s != end && *s == ' ')
  514. {
  515. ++s;
  516. }
  517. /* compress internal blanks and strip trailing blanks */
  518. while (s != end && *s)
  519. {
  520. if (*s++ != ' ' || (s != end && *s && *s != ' '))
  521. {
  522. *p++ = *(s - 1);
  523. }
  524. }
  525. /* wipe out trailing garbage */
  526. while (p != end)
  527. {
  528. *p++ = '\0';
  529. }
  530. }
  531. static int sata_probe(int device)
  532. {
  533. int bus_num;
  534. unsigned char cmd[4] = {WIN_IDENTIFY, 0, 0, 1};
  535. unsigned char identify[512];
  536. char buf[36]; /* should be 36 for unsafe devices (like USB mass storage stuff)
  537. otherwise they can lock up! SPC sections 7.4 and 8.6 */
  538. /* SATA disks are difficult to detect as they answer to both ATA and SCSI
  539. commands */
  540. /* First check that the device is accessible through SCSI */
  541. if (ioctl(device, SCSI_IOCTL_GET_BUS_NUMBER, &bus_num))
  542. {
  543. return 0;
  544. }
  545. /* Get SCSI name and verify it starts with "ATA " */
  546. if (scsi_inquiry(device, buf))
  547. {
  548. return 0;
  549. }
  550. else if (strncmp(buf + 8, "ATA ", 4))
  551. {
  552. return 0;
  553. }
  554. /* Verify that it supports ATA pass thru */
  555. if (sata_pass_thru(device, cmd, identify) != 0)
  556. {
  557. return 0;
  558. }
  559. else
  560. {
  561. return 1;
  562. }
  563. }
  564. int sata_enable_smart(int device)
  565. {
  566. unsigned char cmd[4] = {WIN_SMART, 0, SMART_ENABLE, 0};
  567. return sata_pass_thru(device, cmd, NULL);
  568. }
  569. int sata_get_smart_values(int device, unsigned char *buff)
  570. {
  571. unsigned char cmd[4] = {WIN_SMART, 0, SMART_READ_VALUES, 1};
  572. return sata_pass_thru(device, cmd, buff);
  573. }
  574. static char *sata_model(int device)
  575. {
  576. unsigned char cmd[4] = {WIN_IDENTIFY, 0, 0, 1};
  577. unsigned char identify[512];
  578. if (device == -1 || sata_pass_thru(device, cmd, identify))
  579. {
  580. return strdup("unknown");
  581. }
  582. else
  583. {
  584. sata_fixstring(identify + 54, 40);
  585. return strdup(identify + 54);
  586. }
  587. }
  588. static unsigned char *sata_search_temperature(const unsigned char *smart_data, int attribute_id)
  589. {
  590. int i, n;
  591. n = 3;
  592. i = 0;
  593. if (debug)
  594. {
  595. printf("============ sata ============\n");
  596. }
  597. while ((debug || *(smart_data + n) != attribute_id) && i < 30)
  598. {
  599. if (debug && *(smart_data + n))
  600. {
  601. printf("field(%d)\t = %d\t(0x%02x)\n", *(smart_data + n), *(smart_data + n + 3), *(smart_data + n + 3));
  602. }
  603. n += 12;
  604. i++;
  605. }
  606. if (i >= 30)
  607. {
  608. return NULL;
  609. }
  610. else
  611. {
  612. return (unsigned char *)(smart_data + n);
  613. }
  614. }
  615. int sata_get_temperature(int fd)
  616. {
  617. unsigned char values[512];
  618. unsigned char *field;
  619. int i;
  620. u16 *p;
  621. /* get SMART values */
  622. if (sata_enable_smart(fd) != 0)
  623. {
  624. printf("SATA S.M.A.R.T. not available!\n");
  625. return -1;
  626. }
  627. if (sata_get_smart_values(fd, values))
  628. {
  629. printf("SATA Enable S.M.A.R.T. err!\n");
  630. return -1;
  631. }
  632. p = (u16 *)values;
  633. for (i = 0; i < 256; i++)
  634. {
  635. swapb(*(p + i));
  636. }
  637. /* temperature */
  638. field = sata_search_temperature(values, DEFAULT_ATTRIBUTE_ID);
  639. if (!field)
  640. {
  641. field = sata_search_temperature(values, DEFAULT_ATTRIBUTE_ID2);
  642. }
  643. if (field)
  644. {
  645. return *(field + 3);
  646. }
  647. else
  648. {
  649. return -1;
  650. }
  651. }
  652. #endif
  653. /* 获取硬盘温度 */
  654. int get_sata_hddtemp(char *device, int *value)
  655. {
  656. int fd = 0;
  657. fd = open(device, O_RDONLY | O_NONBLOCK);
  658. if (fd < 0)
  659. {
  660. printf("open hdd device err!\n");
  661. return (-1);
  662. }
  663. if (sata_probe(fd))
  664. {
  665. *value = sata_get_temperature(fd);
  666. }
  667. else if (ata_probe(fd))
  668. {
  669. *value = ata_get_temperature(fd);
  670. }
  671. else if (scsi_probe(fd))
  672. {
  673. *value = scsi_get_temperature(fd);
  674. }
  675. if (*value < 0)
  676. {
  677. return -1;
  678. }
  679. close(fd);
  680. return 0;
  681. }
  682. /* 获取cpu使用率 */
  683. typedef struct cpu_occupy_ //定义一个cpu occupy的结构体
  684. {
  685. char name[20]; //定义一个char类型的数组名name有20个元素
  686. unsigned int user; //定义一个无符号的int类型的user
  687. unsigned int nice; //定义一个无符号的int类型的nice
  688. unsigned int system; //定义一个无符号的int类型的system
  689. unsigned int idle; //定义一个无符号的int类型的idle
  690. unsigned int iowait;
  691. unsigned int irq;
  692. unsigned int softirq;
  693. }cpu_occupy_t;
  694. double cal_cpuoccupy(cpu_occupy_t *o, cpu_occupy_t *n)
  695. {
  696. double od, nd;
  697. double id, sd;
  698. double cpu_use;
  699. od = (double)(o->user + o->nice + o->system + o->idle + o->softirq + o->iowait + o->irq); //第一次(用户+优先级+系统+空闲)的时间再赋给od
  700. nd = (double)(n->user + n->nice + n->system + n->idle + n->softirq + n->iowait + n->irq); //第二次(用户+优先级+系统+空闲)的时间再赋给od
  701. id = (double)(n->idle); //用户第一次和第二次的时间之差再赋给id
  702. sd = (double)(o->idle); //系统第一次和第二次的时间之差再赋给sd
  703. if ((nd - od) != 0)
  704. cpu_use = 100.0 - ((id - sd)) / (nd - od) * 100.00; //((用户+系统)乖100)除(第一次和第二次的时间差)再赋给g_cpu_used
  705. else
  706. cpu_use = 0;
  707. return cpu_use;
  708. }
  709. void get_cpuoccupy(cpu_occupy_t *cpust)
  710. {
  711. FILE *fd;
  712. int n;
  713. char buff[256];
  714. cpu_occupy_t *cpu_occupy;
  715. cpu_occupy = cpust;
  716. fd = fopen("/proc/stat", "r");
  717. if (fd == NULL)
  718. {
  719. perror("fopen:");
  720. exit(0);
  721. }
  722. fgets(buff, sizeof(buff), fd);
  723. sscanf(buff, "%s %u %u %u %u %u %u %u", cpu_occupy->name, &cpu_occupy->user, &cpu_occupy->nice, &cpu_occupy->system,
  724. &cpu_occupy->idle, &cpu_occupy->iowait, &cpu_occupy->irq, &cpu_occupy->softirq);
  725. fclose(fd);
  726. }
  727. double get_sysCpuUsage(void)
  728. {
  729. cpu_occupy_t cpu_stat1;
  730. cpu_occupy_t cpu_stat2;
  731. double cpu;
  732. get_cpuoccupy((cpu_occupy_t *)&cpu_stat1);
  733. sleep(1);
  734. //第二次获取cpu使用情况
  735. get_cpuoccupy((cpu_occupy_t *)&cpu_stat2);
  736. //计算cpu使用率
  737. cpu = cal_cpuoccupy((cpu_occupy_t *)&cpu_stat1, (cpu_occupy_t *)&cpu_stat2);
  738. return cpu;
  739. }
  740. /* 获取内存使用率 */
  741. struct MEM_INFO
  742. {
  743. unsigned int total;
  744. unsigned int free;
  745. unsigned int buffers;
  746. unsigned int cached;
  747. unsigned int swap_cached;
  748. unsigned int swap_total;
  749. unsigned int swap_free;
  750. unsigned int available;
  751. };
  752. typedef struct MEM_INFO Mem_info;
  753. void get_mem_occupy(Mem_info *o)
  754. {
  755. FILE *fpMemInfo = fopen("/proc/meminfo", "r");
  756. if (NULL == fpMemInfo)
  757. {
  758. return;
  759. }
  760. int i = 0;
  761. int value;
  762. char name[1024];
  763. char line[1024];
  764. int nFiledNumber = 2;
  765. int nMemberNumber = 5;
  766. while (fgets(line, sizeof(line) - 1, fpMemInfo))
  767. {
  768. if (sscanf(line, "%s%u", name, &value) != nFiledNumber)
  769. {
  770. continue;
  771. }
  772. if (0 == strcmp(name, "MemTotal:"))
  773. {
  774. ++i;
  775. o->total = value;
  776. }
  777. else if (0 == strcmp(name, "MemFree:"))
  778. {
  779. ++i;
  780. o->free = value;
  781. }
  782. else if (0 == strcmp(name, "MemAvailable:"))
  783. {
  784. ++i;
  785. o->available = value;
  786. }
  787. else if (0 == strcmp(name, "Buffers:"))
  788. {
  789. ++i;
  790. o->buffers = value;
  791. }
  792. else if (0 == strcmp(name, "Cached:"))
  793. {
  794. ++i;
  795. o->cached = value;
  796. }
  797. if (i == nMemberNumber)
  798. {
  799. break;
  800. }
  801. }
  802. // system("free");
  803. // system("cat /proc/meminfo");
  804. // printf("MemTotal : %d\n",o->total);
  805. // printf("MemFree : %d\n",o->free);
  806. // printf("MemAvailable : %d\n",o->available);
  807. // printf("MemBuffers : %d\n",o->buffers);
  808. // printf("MemCached : %d\n",o->cached);
  809. // printf("MemSwapCached : %d\n",o->swap_cached);
  810. // printf("MemSwapTotal : %d\n",o->swap_total);
  811. // printf("MemSwapFree : %d\n",o->swap_free);
  812. fclose(fpMemInfo);
  813. }
  814. float cal_mem_occupy(void)
  815. {
  816. Mem_info omem;
  817. get_mem_occupy(&omem);
  818. return (100.0 * (omem.total - omem.available) / omem.total);
  819. }