Hardware/Mainboard/GigabyteTAMG.cs
author sl
Thu, 01 Jan 2015 23:35:49 +0100
changeset 405 5715aefd2bcc
parent 308 d882720734bf
permissions -rw-r--r--
SharpDisplay: Migrating to new robust client scheme.
     1 /*
     2  
     3   This Source Code Form is subject to the terms of the Mozilla Public
     4   License, v. 2.0. If a copy of the MPL was not distributed with this
     5   file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  
     7   Copyright (C) 2011 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 	
     9 */
    10 
    11 using System;
    12 using System.Collections.Generic;
    13 using System.IO;
    14 using System.IO.Compression;
    15 using System.Runtime.InteropServices;
    16 using System.Text;
    17 
    18 namespace OpenHardwareMonitor.Hardware.Mainboard {
    19   
    20   internal class GigabyteTAMG {
    21     private byte[] table;
    22 
    23     private Sensor[] sensors;
    24 
    25     private struct Sensor {
    26       public string Name;
    27       public SensorType Type;
    28       public int Channel;
    29       public float Value;
    30     }
    31 
    32     private enum SensorType {
    33       Voltage = 1,
    34       Temperature = 2,      
    35       Fan = 4,
    36       Case = 8,
    37     }
    38 
    39     public GigabyteTAMG(byte[] table) {
    40       if (table == null)
    41         throw new ArgumentNullException("table");
    42 
    43       this.table = table;
    44       
    45       int index = IndexOf(table, Encoding.ASCII.GetBytes("$HEALTH$"), 0);
    46 
    47       if (index >= 0) {
    48         index += 8;
    49         using (MemoryStream m =
    50           new MemoryStream(table, index, table.Length - index))
    51         using (BinaryReader r = new BinaryReader(m)) {
    52           try {
    53             r.ReadInt64();
    54             int count = r.ReadInt32();
    55             r.ReadInt64();
    56             r.ReadInt32();
    57             sensors = new Sensor[count];
    58             for (int i = 0; i < sensors.Length; i++) {
    59               sensors[i].Name = new string(r.ReadChars(32)).TrimEnd('\0');
    60               sensors[i].Type = (SensorType)r.ReadByte();
    61               sensors[i].Channel = r.ReadInt16();
    62               sensors[i].Channel |= r.ReadByte() << 24;
    63               r.ReadInt64();
    64               int value = r.ReadInt32();
    65               switch (sensors[i].Type) {
    66                 case SensorType.Voltage:
    67                   sensors[i].Value = 1e-3f * value; break;
    68                 default:
    69                   sensors[i].Value = value; break;
    70               }
    71               r.ReadInt64();
    72             }
    73           } catch (IOException) { sensors = new Sensor[0]; }
    74         }
    75       } else {
    76         sensors = new Sensor[0]; 
    77       }
    78     }
    79 
    80     public static int IndexOf(byte[] array, byte[] pattern, int startIndex) {
    81       if (array == null || pattern == null || pattern.Length > array.Length)
    82         return -1;
    83 
    84       for (int i = startIndex; i < array.Length - pattern.Length; i++) {
    85         bool found = true;
    86         for (int j = 0; j < pattern.Length; j++) {
    87           if (array[i + j] != pattern[j]) {
    88             found = false;
    89             break;
    90           }
    91         }
    92         if (found) 
    93           return i;
    94       }
    95       return -1;
    96     }
    97 
    98     private string GetCompressedAndEncodedTable() {
    99       string base64;
   100       using (MemoryStream m = new MemoryStream()) {
   101         using (GZipStream c = new GZipStream(m, CompressionMode.Compress)) {
   102           c.Write(table, 0, table.Length);          
   103         }
   104         base64 = Convert.ToBase64String(m.ToArray());
   105       }
   106 
   107       StringBuilder r = new StringBuilder();
   108       for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
   109         r.Append(" ");
   110         for (int j = 0; j < 0x40; j++) {
   111           int index = (i << 6) | j;
   112           if (index < base64.Length) {
   113             r.Append(base64[index]);
   114           }
   115         }
   116         r.AppendLine();
   117       }
   118 
   119       return r.ToString();
   120     }
   121 
   122     public string GetReport() {
   123       StringBuilder r = new StringBuilder();
   124 
   125       if (sensors.Length > 0) {
   126         r.AppendLine("Gigabyte TAMG Sensors");
   127         r.AppendLine();
   128 
   129         foreach (Sensor sensor in sensors) {
   130           r.AppendFormat(" {0,-10}: {1,8:G6} ({2})", sensor.Name, sensor.Value,
   131             sensor.Type);
   132           r.AppendLine();
   133         }
   134         r.AppendLine();
   135       }
   136 
   137       if (table.Length > 0) {
   138         r.AppendLine("Gigabyte TAMG Table");
   139         r.AppendLine();
   140         r.Append(GetCompressedAndEncodedTable());
   141         r.AppendLine();
   142       }
   143 
   144       return r.ToString();
   145     }
   146   }
   147 }