1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Hardware/Mainboard/GigabyteTAMG.cs Thu Jul 07 20:41:09 2011 +0000
1.3 @@ -0,0 +1,174 @@
1.4 +/*
1.5 +
1.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
1.7 +
1.8 + The contents of this file are subject to the Mozilla Public License Version
1.9 + 1.1 (the "License"); you may not use this file except in compliance with
1.10 + the License. You may obtain a copy of the License at
1.11 +
1.12 + http://www.mozilla.org/MPL/
1.13 +
1.14 + Software distributed under the License is distributed on an "AS IS" basis,
1.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1.16 + for the specific language governing rights and limitations under the License.
1.17 +
1.18 + The Original Code is the Open Hardware Monitor code.
1.19 +
1.20 + The Initial Developer of the Original Code is
1.21 + Michael Möller <m.moeller@gmx.ch>.
1.22 + Portions created by the Initial Developer are Copyright (C) 2011
1.23 + the Initial Developer. All Rights Reserved.
1.24 +
1.25 + Contributor(s):
1.26 +
1.27 + Alternatively, the contents of this file may be used under the terms of
1.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
1.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1.30 + in which case the provisions of the GPL or the LGPL are applicable instead
1.31 + of those above. If you wish to allow use of your version of this file only
1.32 + under the terms of either the GPL or the LGPL, and not to allow others to
1.33 + use your version of this file under the terms of the MPL, indicate your
1.34 + decision by deleting the provisions above and replace them with the notice
1.35 + and other provisions required by the GPL or the LGPL. If you do not delete
1.36 + the provisions above, a recipient may use your version of this file under
1.37 + the terms of any one of the MPL, the GPL or the LGPL.
1.38 +
1.39 +*/
1.40 +
1.41 +using System;
1.42 +using System.Collections.Generic;
1.43 +using System.IO;
1.44 +using System.IO.Compression;
1.45 +using System.Runtime.InteropServices;
1.46 +using System.Text;
1.47 +
1.48 +namespace OpenHardwareMonitor.Hardware.Mainboard {
1.49 +
1.50 + internal class GigabyteTAMG {
1.51 + private byte[] table;
1.52 +
1.53 + private Sensor[] sensors;
1.54 +
1.55 + private struct Sensor {
1.56 + public string Name;
1.57 + public SensorType Type;
1.58 + public int Channel;
1.59 + public float Value;
1.60 + }
1.61 +
1.62 + private enum SensorType {
1.63 + Voltage = 1,
1.64 + Temperature = 2,
1.65 + Fan = 4,
1.66 + Case = 8,
1.67 + }
1.68 +
1.69 + public GigabyteTAMG(byte[] table) {
1.70 + if (table == null)
1.71 + throw new ArgumentNullException("table");
1.72 +
1.73 + this.table = table;
1.74 +
1.75 + int index = IndexOf(table, Encoding.ASCII.GetBytes("$HEALTH$"), 0);
1.76 +
1.77 + if (index >= 0) {
1.78 + index += 8;
1.79 + using (MemoryStream m =
1.80 + new MemoryStream(table, index, table.Length - index))
1.81 + using (BinaryReader r = new BinaryReader(m)) {
1.82 + try {
1.83 + r.ReadInt64();
1.84 + int count = r.ReadInt32();
1.85 + r.ReadInt64();
1.86 + r.ReadInt32();
1.87 + sensors = new Sensor[count];
1.88 + for (int i = 0; i < sensors.Length; i++) {
1.89 + sensors[i].Name = new string(r.ReadChars(32)).TrimEnd('\0');
1.90 + sensors[i].Type = (SensorType)r.ReadByte();
1.91 + sensors[i].Channel = r.ReadInt16();
1.92 + sensors[i].Channel |= r.ReadByte() << 24;
1.93 + r.ReadInt64();
1.94 + int value = r.ReadInt32();
1.95 + switch (sensors[i].Type) {
1.96 + case SensorType.Voltage:
1.97 + sensors[i].Value = 1e-3f * value; break;
1.98 + default:
1.99 + sensors[i].Value = value; break;
1.100 + }
1.101 + r.ReadInt64();
1.102 + }
1.103 + } catch (IOException) { sensors = new Sensor[0]; }
1.104 + }
1.105 + } else {
1.106 + sensors = new Sensor[0];
1.107 + }
1.108 + }
1.109 +
1.110 + public static int IndexOf(byte[] array, byte[] pattern, int startIndex) {
1.111 + if (array == null || pattern == null || pattern.Length > array.Length)
1.112 + return -1;
1.113 +
1.114 + for (int i = startIndex; i < array.Length - pattern.Length; i++) {
1.115 + bool found = true;
1.116 + for (int j = 0; j < pattern.Length; j++) {
1.117 + if (array[i + j] != pattern[j]) {
1.118 + found = false;
1.119 + break;
1.120 + }
1.121 + }
1.122 + if (found)
1.123 + return i;
1.124 + }
1.125 + return -1;
1.126 + }
1.127 +
1.128 + private string GetCompressedAndEncodedTable() {
1.129 + string base64;
1.130 + using (MemoryStream m = new MemoryStream()) {
1.131 + using (GZipStream c = new GZipStream(m, CompressionMode.Compress)) {
1.132 + c.Write(table, 0, table.Length);
1.133 + }
1.134 + base64 = Convert.ToBase64String(m.ToArray());
1.135 + }
1.136 +
1.137 + StringBuilder r = new StringBuilder();
1.138 + for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
1.139 + r.Append(" ");
1.140 + for (int j = 0; j < 0x40; j++) {
1.141 + int index = (i << 6) | j;
1.142 + if (index < base64.Length) {
1.143 + r.Append(base64[index]);
1.144 + }
1.145 + }
1.146 + r.AppendLine();
1.147 + }
1.148 +
1.149 + return r.ToString();
1.150 + }
1.151 +
1.152 + public string GetReport() {
1.153 + StringBuilder r = new StringBuilder();
1.154 +
1.155 + if (sensors.Length > 0) {
1.156 + r.AppendLine("Gigabyte TAMG Sensors");
1.157 + r.AppendLine();
1.158 +
1.159 + foreach (Sensor sensor in sensors) {
1.160 + r.AppendFormat(" {0,-10}: {1,8:G6} ({2})", sensor.Name, sensor.Value,
1.161 + sensor.Type);
1.162 + r.AppendLine();
1.163 + }
1.164 + r.AppendLine();
1.165 + }
1.166 +
1.167 + if (table.Length > 0) {
1.168 + r.AppendLine("Gigabyte TAMG Table");
1.169 + r.AppendLine();
1.170 + r.Append(GetCompressedAndEncodedTable());
1.171 + r.AppendLine();
1.172 + }
1.173 +
1.174 + return r.ToString();
1.175 + }
1.176 + }
1.177 +}