/*## (c) SECURITY EXPLORATIONS    2018 poland                                #*/
/*##     http://www.security-explorations.com                                #*/

/* THIS SOFTWARE IS PROTECTED BY DOMESTIC AND INTERNATIONAL COPYRIGHT LAWS    */
/* UNAUTHORISED COPYING OF THIS SOFTWARE IN EITHER SOURCE OR BINARY FORM IS   */
/* EXPRESSLY FORBIDDEN. ANY USE, INCLUDING THE REPRODUCTION, MODIFICATION,    */
/* DISTRIBUTION, TRANSMISSION, RE-PUBLICATION, STORAGE OR DISPLAY OF ANY      */
/* PART OF THE SOFTWARE, FOR COMMERCIAL OR ANY OTHER PURPOSES REQUIRES A      */
/* VALID LICENSE FROM THE COPYRIGHT HOLDER.                                   */

/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS    */
/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,*/
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    */
/* SECURITY EXPLORATIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF  */
/* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE     */
/* SOFTWARE.                                                                  */

import java.lang.*;
import java.util.*;
import java.io.*;
import java.net.*;
import tv.osmosys.tci.device.*;

public class SysInfo {
 public static final int PAD   = 25;

 public static final String NET_CONFIG       = "/flash/standalone.properties";

 public static final int NETCFG_SUBNET_MASK  = 0;
 public static final int NETCFG_IP_ADDR      = 1;
 public static final int NETCFG_DNS1         = 2;
 public static final int NETCFG_DNS2         = 3;
 public static final int NETCFG_GATEWAY      = 4;

 public static final int NETCFG_MAX          = 5;

 public static int hwid;

 private static String hwver;
 private static String swver;
 private static String SN;
 private static String mac;
 private static String dnltime;
 private static String mhpver;

 private static String netcfgkeys[]={
  "ip", "subnetMask", "dns1", "dns2", "gateway"  
 };

 private static String netcfgdata[];

 private static String stb_property(DeviceProxy deviceproxy,String prop) throws NoSuchMethodException {
  int mid=deviceproxy.getMethod("get_property(S)S");
  return (String)deviceproxy.control(mid,prop);
 }

 private static Object cfg_method(DeviceProxy deviceproxy,String method) throws NoSuchMethodException {
  int mid=deviceproxy.getMethod(method);
  return deviceproxy.control(mid,null);
 }

 private static int netcfg_idx(String key) {
  int res=-1;

  for(int i=0;i<netcfgkeys.length;i++) {
   if (netcfgkeys[i].equals(key)) return i;
  }

  return res;
 }

 private static void parse_net_config() {
  netcfgdata=new String[NETCFG_MAX];

  try {
   FileInputStream in=new FileInputStream(NET_CONFIG);
   BufferedReader b=new BufferedReader(new InputStreamReader(in,"utf-8"));

   String line=b.readLine();

   while(line!=null) {
    int pos=line.indexOf('=');

    if (pos>0) {
     String key=line.substring(0,pos);

     int idx=netcfg_idx(key);    

     if (idx>=0) {
      String val=line.substring(pos+1,line.length());
      netcfgdata[idx]=val; 
     }
    }
    
    line=b.readLine();
   }

   b.close();
   in.close();  
  } catch(Throwable t) {}
 }

 static {
  try {
   DeviceProxy deviceproxy=DeviceFactory.openDevice("stbdata");

   if (deviceproxy!=null) {
    String s1=stb_property(deviceproxy,"ldr.img.btr.hw");
    String s2=stb_property(deviceproxy,"ldr.img.btr.cust");

    int i1=Integer.decode(s1).intValue();
    int i2=Integer.decode(s2).intValue();

    hwver=Utils.hex_value(i1,3)+":"+Utils.hex_value(i2,2);
    hwid=i1;

    swver=stb_property(deviceproxy,"ldr.img.app.ver.short");
    SN=stb_property(deviceproxy,"sn");
    mac=stb_property(deviceproxy,"mac.STB.Eth.Ethernet");

    s1=stb_property(deviceproxy,"ldr.img.app.sec");

    if (s1!=null) {
     i1=Integer.decode(s1).intValue();
     Date date=new Date(((long)i1)*1000);
     dnltime=date.toString();
    }

    deviceproxy.close(); 
   } else {

    deviceproxy=DeviceFactory.openDevice("ldrinfo");

    if (deviceproxy!=null) {
     hwver=(String)cfg_method(deviceproxy,"get_hw_version()S");
     swver=(String)cfg_method(deviceproxy,"get_sw_version()S");
     SN=(String)cfg_method(deviceproxy,"get_serial_number()S");
     byte tab[]=(byte[])cfg_method(deviceproxy,"get_mac_address()[B");

     if (tab!=null) {
      String s="";
      for(int i=0;i<tab.length;i++) {
       s+=Utils.hex_value(tab[i]&0xff,2);
       if (i<(tab.length-1)) s+=":";
      }
 
      mac=s;
     }

     int i1=hwver.indexOf('.');
     int i2=hwver.indexOf(':');

     if (i1>0) {
      int v1=Integer.parseInt(hwver.substring(0,i1));

      if (i2>0) {
       int v2=Integer.parseInt(hwver.substring(i1+1,i2));
       hwid=((v1&0xff)<<8)|(v2&0xff);
      }
     } 

     Integer v=(Integer)cfg_method(deviceproxy,"get_download_time()I");

     if (v!=null) {
      Date date=new Date(((long)v.intValue())*1000);
      dnltime=date.toString();
     }
     
     deviceproxy.close(); 
    }
   }

   String s="MHP ";

   String s1=System.getProperty("mhp.eb.version.major");

   if (s1!=null) {
    s+=s1+"."+System.getProperty("mhp.eb.version.minor")+"."+System.getProperty("mhp.eb.version.micro")+" ";
   }

   s+=System.getProperty("tci.build.version");

   mhpver=s;

   parse_net_config();
  } catch(Throwable t) {}

 }

 public static String boxtype() {
  String res="UNKNOWN";

  switch(hwid) {
   case SysInfoDefs.ITI5800S:
    res="ITI5800S (nBox HDTV)";
    break;

   case SysInfoDefs.ITI5800SX:
    res="ITI5800SX (nBox HDTV Recorder)";
    break;

   case SysInfoDefs.ITI2850ST:
    if (Config.BOXTYPE==Config.NBOX_2849ST) {
     res="ITI2849ST (nBox HDTV)";
    } else {
     res="ITI2850ST (nBox HDTV)";
    }
    break;

   case SysInfoDefs.ITI2851S:
    res="ITI2851S (Box+ HDTV)";
    break;
  }

  return res;
 }

 public static String serial_num() {
  return SN;
 }

 public static int get_ip() {
  int ip=0;

  String ip_str=netcfgdata[NETCFG_IP_ADDR]; 

  if (ip_str!=null) {
   try {
    InetAddress ia[]=InetAddress.getAllByName(ip_str);

    if ((ia!=null)&&(ia.length>0)) {
     byte tab[]=ia[0].getAddress();
     ip=((tab[0]&0xff)<<24)|((tab[1]&0xff)<<16)|((tab[2]&0xff)<<8)|(tab[3]&0xff);
    }   
   } catch(Throwable t) {}
  }
  return ip;
 }

 public static void print() throws Throwable {
  Output.text("[system info]");
  String s="- "+Utils.padded_string("boxtype",PAD)+boxtype();
  Output.text(s);

  s="- "+Utils.padded_string("serial #",PAD)+SN;
  Output.text(s);

  s="- "+Utils.padded_string("hw version",PAD)+hwver;
  Output.text(s);

  s="- "+Utils.padded_string("sw version",PAD)+swver;
  Output.text(s);

  if (dnltime!=null) {
   s="- "+Utils.padded_string("sw dnld time",PAD)+dnltime;
   Output.text(s);
  }

  if (mhpver!=null) {
   s="- "+Utils.padded_string("MHP ver",PAD)+mhpver;
   Output.text(s);
  }

  s="- "+Utils.padded_string("mac addr",PAD)+mac;
  Output.text(s);
 }

 public static void print_network() throws Throwable {
  Output.text("[network info]");

  for(int i=0;i<NETCFG_MAX;i++) {
   if (netcfgdata[i]!=null) {
    String s="- "+Utils.padded_string(netcfgkeys[i],PAD)+netcfgdata[i];
    Output.text(s);
   }
  }
 }

 public static String stb_property(String prop) {
  String res=null;

  try {
   DeviceProxy deviceproxy=DeviceFactory.openDevice("stbdata");

   if (deviceproxy!=null) {
    res=stb_property(deviceproxy,prop);
   }
  } catch(Throwable t) {}

  return res;
 }   
}
