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