AppleTV.mm example

An other small example in GCC, it to get detailed info from your Apple TV2.
This code will be compiled directly on your Apple TV with GCC.
Here’s how:

Follow these steps:

apt-get update
apt-get install wget zip unzip tar nano
wget http://apt.saurik.com/debs/libgcc_4.2-20080410-1-6_iphoneos-arm.deb
dpkg -i libgcc_4.2-20080410-1-6_iphoneos-arm.deb
apt-get install iphone-gcc ldid make

Download sys32.tgz, and copy it to Apple TV2 path /var/mobile/

Install the 3.2 SDK header file (this is huge)

mkdir -p /var/toolchain/
cd /var/toolchain/
tar -xzvf /var/mobile/sys32.tgz

Create a test file with nano : ‘AppleTV.mm’ (without quotes)

Selec All Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <IOKit/IOKitLib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
 
int main(int argc, char *argv[]) {
 
    const char *Machine_ = NULL;
    const NSString *System_ = NULL;
    const NSString *SerialNumber_ = nil;
    const NSString *ChipID_ = nil;
    const NSString *UniqueID_ = nil;
    const NSString *Build_ = nil;
    const NSString *Product_ = nil;
    const NSString *ATV_ = nil;
 
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
 
    /* System Information {{{ */
    size_t size;
 
    int maxproc;
    size = sizeof(maxproc);
    if (sysctlbyname("kern.maxproc", &maxproc, &size, NULL, 0) == -1)
        perror("sysctlbyname(\"kern.maxproc\", ?)");
    else if (maxproc < 64) {
        maxproc = 64;
        if (sysctlbyname("kern.maxproc", NULL, NULL, &maxproc,
sizeof(maxproc)) == -1)
            perror("sysctlbyname(\"kern.maxproc\", #)");
    }
 
    sysctlbyname("kern.osversion", NULL, &size, NULL, 0);
    char *osversion = new char[size];
    if (sysctlbyname("kern.osversion", osversion, &size, NULL, 0) == -1)
        perror("sysctlbyname(\"kern.osversion\", ?)");
    else {
        System_ = [NSString stringWithUTF8String:osversion];
        printf("System is %s\n", osversion);
    }
 
    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
    char *machine = new char[size];
    if (sysctlbyname("hw.machine", machine, &size, NULL, 0) == -1)
        perror("sysctlbyname(\"hw.machine\", ?)");
    else {
        Machine_ = machine;
        printf("Machine is %s\n", machine);
    }
 
    if (CFMutableDictionaryRef dict =
IOServiceMatching("IOPlatformExpertDevice")) {
        if (io_service_t service =
IOServiceGetMatchingService(kIOMasterPortDefault, dict)) {
            if (CFTypeRef serial =
IORegistryEntryCreateCFProperty(service,
CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0)) {
                SerialNumber_ = [NSString stringWithString:(NSString
*)serial];
                printf("SerialNumber is %s\n",[SerialNumber_
UTF8String]);
                CFRelease(serial);
            }
 
            if (CFTypeRef ecid =
IORegistryEntrySearchCFProperty(service, kIODeviceTreePlane,
CFSTR("unique-chip-id"), kCFAllocatorDefault,
kIORegistryIterateRecursively)) {
                NSData *data((NSData *) ecid);
                size_t length([data length]);
                uint8_t bytes[length];
                [data getBytes:bytes];
                char string[length * 2 + 1];
                for (size_t i(0); i != length; ++i)
                    sprintf(string + i * 2, "%.2X", bytes[length - i -
1]);
                ChipID_ = [NSString stringWithUTF8String:string];
                printf("Chip ID is %s\n",[ChipID_ UTF8String]);
                CFRelease(ecid);
            }
 
            IOObjectRelease(service);
        }
    }
 
    UniqueID_ = [[UIDevice currentDevice] uniqueIdentifier];
    printf("UniqueID is %s\n",[UniqueID_ UTF8String]);
 
    if (NSDictionary *system = [NSDictionary
dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"])
{
        Build_ = [system objectForKey:@"ProductBuildVersion"];
        printf("Build is %s\n",[Build_ UTF8String]);
    }
    if (NSDictionary *info = [NSDictionary
dictionaryWithContentsOfFile:@"/Applications/AppleTV.app/Info.plist"])
{
        Product_ = [info objectForKey:@"MinimumOSVersion"];
        printf("AppleTV OS is %s\n",[Product_ UTF8String]);
        ATV_ = [info objectForKey:@"CFBundleVersion"];
        printf("AppleTV OS version is %s\n",[ATV_ UTF8String]);
    }
    /* }}} */
    [pool release];
    return 0;
}

Now compile the code with :

Selec All Code:
1
arm-apple-darwin9-g++ -fobjc-exceptions -fobjc-call-cxx-cdtors -mthumb -Wall -o AppleTV AppleTV.mm -framework UIKit -framework IOKit -framework Foundation -framework CoreFoundation -lobjc -I"/var/toolchain/sys32/usr/include" -g0 -O2 -Diphoneos_version_min=3.0 -Wno-attributes -Wno-trigraphs -Wreturn-type -Wunused-variable  -I"/var/toolchain/sys32/usr/include/c++/4.2.1" -I"/var/toolchain/sys32/usr/include/c++/4.2.1/armv7-apple-darwin10"  -L"/var/toolchain/sys32/usr/lib" -F"/var/toolchain/sys32/System/Library/Frameworks" -F"/var/toolchain/sys32/System/Library/PrivateFrameworks" -bind_at_load -multiply_defined suppress -march=armv6 -mcpu=arm1176jzf-s

Sign it and run it

Selec All Code:
1
2
AppleTV:/var/toolchain root# ldid -S AppleTV
AppleTV:/var/toolchain root# ./AppleTV

result :

Selec All Code:
1
2
3
4
5
6
7
8
9
AppleTV:/var/toolchain root# ./AppleTV
System is 8F305
Machine is AppleTV2,1
SerialNumber is DCYF****DDR5
Chip ID is 000003FE2914A58F
UniqueID is a0d2de3649fcca3474168f6bb6052573bad9667d
Build is 8F305
AppleTV OS is 4.3
AppleTV OS version is 4.2.2

This tasts like more… Let’s see if I can get this output displayed on the TV screen.. (In my next post I hope)