moel@308: /* moel@308: moel@344: This Source Code Form is subject to the terms of the Mozilla Public moel@344: License, v. 2.0. If a copy of the MPL was not distributed with this moel@344: file, You can obtain one at http://mozilla.org/MPL/2.0/. moel@308: moel@344: Copyright (C) 2011 Michael Möller moel@344: moel@308: */ moel@308: moel@308: using System; moel@308: using System.Collections.Generic; moel@308: using System.IO; moel@308: using System.IO.Compression; moel@308: using System.Runtime.InteropServices; moel@308: using System.Text; moel@308: moel@308: namespace OpenHardwareMonitor.Hardware.Mainboard { moel@308: moel@308: internal class GigabyteTAMG { moel@308: private byte[] table; moel@308: moel@308: private Sensor[] sensors; moel@308: moel@308: private struct Sensor { moel@308: public string Name; moel@308: public SensorType Type; moel@308: public int Channel; moel@308: public float Value; moel@308: } moel@308: moel@308: private enum SensorType { moel@308: Voltage = 1, moel@308: Temperature = 2, moel@308: Fan = 4, moel@308: Case = 8, moel@308: } moel@308: moel@308: public GigabyteTAMG(byte[] table) { moel@308: if (table == null) moel@308: throw new ArgumentNullException("table"); moel@308: moel@308: this.table = table; moel@308: moel@308: int index = IndexOf(table, Encoding.ASCII.GetBytes("$HEALTH$"), 0); moel@308: moel@308: if (index >= 0) { moel@308: index += 8; moel@308: using (MemoryStream m = moel@308: new MemoryStream(table, index, table.Length - index)) moel@308: using (BinaryReader r = new BinaryReader(m)) { moel@308: try { moel@308: r.ReadInt64(); moel@308: int count = r.ReadInt32(); moel@308: r.ReadInt64(); moel@308: r.ReadInt32(); moel@308: sensors = new Sensor[count]; moel@308: for (int i = 0; i < sensors.Length; i++) { moel@308: sensors[i].Name = new string(r.ReadChars(32)).TrimEnd('\0'); moel@308: sensors[i].Type = (SensorType)r.ReadByte(); moel@308: sensors[i].Channel = r.ReadInt16(); moel@308: sensors[i].Channel |= r.ReadByte() << 24; moel@308: r.ReadInt64(); moel@308: int value = r.ReadInt32(); moel@308: switch (sensors[i].Type) { moel@308: case SensorType.Voltage: moel@308: sensors[i].Value = 1e-3f * value; break; moel@308: default: moel@308: sensors[i].Value = value; break; moel@308: } moel@308: r.ReadInt64(); moel@308: } moel@308: } catch (IOException) { sensors = new Sensor[0]; } moel@308: } moel@308: } else { moel@308: sensors = new Sensor[0]; moel@308: } moel@308: } moel@308: moel@308: public static int IndexOf(byte[] array, byte[] pattern, int startIndex) { moel@308: if (array == null || pattern == null || pattern.Length > array.Length) moel@308: return -1; moel@308: moel@308: for (int i = startIndex; i < array.Length - pattern.Length; i++) { moel@308: bool found = true; moel@308: for (int j = 0; j < pattern.Length; j++) { moel@308: if (array[i + j] != pattern[j]) { moel@308: found = false; moel@308: break; moel@308: } moel@308: } moel@308: if (found) moel@308: return i; moel@308: } moel@308: return -1; moel@308: } moel@308: moel@308: private string GetCompressedAndEncodedTable() { moel@308: string base64; moel@308: using (MemoryStream m = new MemoryStream()) { moel@308: using (GZipStream c = new GZipStream(m, CompressionMode.Compress)) { moel@308: c.Write(table, 0, table.Length); moel@308: } moel@308: base64 = Convert.ToBase64String(m.ToArray()); moel@308: } moel@308: moel@308: StringBuilder r = new StringBuilder(); moel@308: for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) { moel@308: r.Append(" "); moel@308: for (int j = 0; j < 0x40; j++) { moel@308: int index = (i << 6) | j; moel@308: if (index < base64.Length) { moel@308: r.Append(base64[index]); moel@308: } moel@308: } moel@308: r.AppendLine(); moel@308: } moel@308: moel@308: return r.ToString(); moel@308: } moel@308: moel@308: public string GetReport() { moel@308: StringBuilder r = new StringBuilder(); moel@308: moel@308: if (sensors.Length > 0) { moel@308: r.AppendLine("Gigabyte TAMG Sensors"); moel@308: r.AppendLine(); moel@308: moel@308: foreach (Sensor sensor in sensors) { moel@308: r.AppendFormat(" {0,-10}: {1,8:G6} ({2})", sensor.Name, sensor.Value, moel@308: sensor.Type); moel@308: r.AppendLine(); moel@308: } moel@308: r.AppendLine(); moel@308: } moel@308: moel@308: if (table.Length > 0) { moel@308: r.AppendLine("Gigabyte TAMG Table"); moel@308: r.AppendLine(); moel@308: r.Append(GetCompressedAndEncodedTable()); moel@308: r.AppendLine(); moel@308: } moel@308: moel@308: return r.ToString(); moel@308: } moel@308: } moel@308: }