Skip to content

Commit

Permalink
Merge pull request #164 from emkey1/B502
Browse files Browse the repository at this point in the history
B502
  • Loading branch information
emkey1 authored Nov 26, 2023
2 parents 94b374f + 72accec commit d573330
Show file tree
Hide file tree
Showing 12 changed files with 232 additions and 43 deletions.
38 changes: 37 additions & 1 deletion app/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "fs/dyndev.h"
#include "fs/devices.h"
#include "fs/path.h"
#include "app/RTCDevice.h"

#if ISH_LINUX
#import "LinuxInterop.h"
Expand Down Expand Up @@ -69,6 +70,21 @@ static void ios_handle_exit(struct task *task, int code) {
});
}

const char* getCurrentTimestamp(void);

const char* getCurrentTimestamp(void) {
NSDate *currentDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd_HH:mm:ss"];
NSString *timestamp = [dateFormatter stringFromDate:currentDate];

// Prepending "/tmp/" to the timestamp
NSString *prefixedTimestamp = [NSString stringWithFormat:@"/tmp/%@", timestamp];

// Convert to const char* and return
return [prefixedTimestamp UTF8String];
}

// Put the abort message in the thread name so it gets included in the crash dump
static void ios_handle_die(const char *msg) {
char name[17];
Expand All @@ -89,6 +105,7 @@ @implementation AppDelegate

- (intptr_t)boot {
#if !ISH_LINUX

NSURL *root = [Roots.instance rootUrl:Roots.instance.defaultRoot];

intptr_t err = mount_root(&fakefs, [root URLByAppendingPathComponent:@"data"].fileSystemRepresentation);
Expand Down Expand Up @@ -131,6 +148,21 @@ - (intptr_t)boot {
// Permissions on / have been broken for a while, let's fix them
generic_setattrat(AT_PWD, "/", (struct attr) {.type = attr_mode, .mode = 0755}, false);

// Create a unique directory in /tmp and link to /var/run
const char *timestamp = getCurrentTimestamp();
generic_mkdirat(AT_PWD, timestamp, 0755);
generic_unlinkat(AT_PWD, "/var/run");
generic_symlinkat(timestamp, AT_PWD, "/var/run");

// Create directories/links to simulate /sys stuff for battery monitoring
generic_mkdirat(AT_PWD, "/sys/class", 0755);
generic_mkdirat(AT_PWD, "/sys/class/power_supply", 0755);
generic_mkdirat(AT_PWD, "/sys/class/power_supply/BAT0", 0755);
generic_symlinkat("/proc/ish/BAT0_capacity", AT_PWD, "/sys/class/power_supply/BAT0/capacity");
generic_symlinkat("/proc/ish/BAT0_status", AT_PWD, "/sys/class/power_supply/BAT0/status");



// Register clipboard device driver and create device node for it
err = dyn_dev_register(&clipboard_dev, DEV_CHAR, DYN_DEV_MAJOR, DEV_CLIPBOARD_MINOR);
if (err != 0) {
Expand All @@ -142,7 +174,11 @@ - (intptr_t)boot {
if (err != 0)
return err;
generic_mknodat(AT_PWD, "/dev/location", S_IFCHR|0666, dev_make(DYN_DEV_MAJOR, DEV_LOCATION_MINOR));
// The following does nothing for now. Placeholder

// Emulate a RTC, read time only
err = dyn_dev_register(&rtc_dev, DEV_CHAR, DEV_RTC_MAJOR, DEV_RTC_MINOR);
if (err != 0)
return err;
generic_mknodat(AT_PWD, "/dev/rtc0", S_IFCHR|0666, dev_make(DEV_RTC_MAJOR, DEV_RTC_MINOR));
generic_symlinkat("/dev/rtc0", AT_PWD, "/dev/rtc");

Expand Down
8 changes: 8 additions & 0 deletions app/RTCDevice.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//
// RTCDevice.h
// iSH-AOK
//
// Created by Michael Miller on 11/24/23.
//

extern struct dev_ops rtc_dev;
116 changes: 116 additions & 0 deletions app/RTCDevice.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
//
// RTCDevice.m
// iSH-AOK
//
// Created by Michael Miller on 11/24/23.
//

#import <Foundation/Foundation.h>
#include "fs/poll.h"
#include "fs/dyndev.h"
#include "kernel/errno.h"
#include "debug.h"
#include "fs/devices.h"

// Real Time Clock file descriptor structure
typedef struct fd rtc_fd;

// Need to define this, as we are running on iOS, which doesn't have/give access to the RTC
typedef struct rtc_time {
int tm_sec; // seconds
int tm_min; // minutes
int tm_hour; // hours
int tm_mday; // day of the month
int tm_mon; // month
int tm_year; // year
} rtc_time;

// Get the time, put it in the appropriate structure
static rtc_time *get_current_time(rtc_fd *fd, size_t *len) {
// Obtain the current date
NSDate *currentDate = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];

// Define the desired date components
NSDateComponents *components = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond)
fromDate:currentDate];

// Allocate and populate the rtc_time structure
rtc_time *timeStruct = malloc(sizeof(rtc_time));
if (!timeStruct) {
// Handle memory allocation failure
*len = 0;
return NULL;
}

// Populate the structure
// Note: tm_mon is 0-based (0 for January) and tm_year is years since 1900
timeStruct->tm_sec = (int)[components second];
timeStruct->tm_min = (int)[components minute];
timeStruct->tm_hour = (int)[components hour];
timeStruct->tm_mday = (int)[components day];
timeStruct->tm_mon = (int)[components month] - 1; // Adjust for tm_mon
timeStruct->tm_year = (int)[components year] - 1900; // Adjust for tm_year

// Update the size
*len = sizeof(rtc_time);

return timeStruct;
}

static ssize_t rtc_read(rtc_fd *fd, void *buf, size_t bufsize) {
return 0;
}

static int rtc_poll(rtc_fd *fd) {
return 0;
}

static int rtc_open(int major, int minor, rtc_fd *fd) {
return 0;
}

static int rtc_close(rtc_fd *fd) {
return 0;
}

#define RTC_RD_TIME 0x80247009 // Example definition, adjust as necessary

static ssize_t rtc_ioctl_size(int cmd) {
switch (cmd) {
case RTC_RD_TIME:
return sizeof(rtc_time);
}
return -1;
}

// Function to handle ioctl operations
static int rtc_ioctl(struct fd *fd, int cmd, void *arg) {
@autoreleasepool {
switch (cmd) {
case RTC_RD_TIME: { // On a real Linux, there are a number of other possible ioctl()'s. We don't really need them
size_t length = 0;
rtc_time *data = get_current_time(fd, &length);

if (arg == NULL) {
return _EFAULT; // Null pointer argument
}

*(rtc_time *) arg = *data; // This is the magic that gets the value back to the "kernel"

return 0; // Success
}
default:
return _EFAULT; // Oops
}
}
}

struct dev_ops rtc_dev = {
.open = rtc_open,
.fd.read = rtc_read,
.fd.poll = rtc_poll,
.fd.close = rtc_close,
.fd.ioctl = rtc_ioctl,
.fd.ioctl_size = rtc_ioctl_size, // Do NOT FORGET THIS if you want to implement ioctl(s) for your device. They will not work without it.
};
3 changes: 2 additions & 1 deletion fs/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "fs/tty.h"
#include "fs/dyndev.h"
#include "fs/devices.h"
#include "app/RTCDevice.h"

struct dev_ops *block_devs[256] = {
// no block devices yet
Expand All @@ -15,7 +16,7 @@ struct dev_ops *char_devs[256] = {
[TTY_ALTERNATE_MAJOR] = &tty_dev,
[TTY_PSEUDO_MASTER_MAJOR] = &tty_dev,
[TTY_PSEUDO_SLAVE_MAJOR] = &tty_dev,
// [DEV_RTC_MAJOR] = &rtc_dev_char,
[DEV_RTC_MAJOR] = &rtc_dev,
[DYN_DEV_MAJOR] = &dyn_dev_char,
};

Expand Down
6 changes: 0 additions & 6 deletions fs/dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,6 @@ static inline dev_t_ dev_fake_from_real(dev_t dev) {
#define DEV_BLOCK 0
#define DEV_CHAR 1

struct dev_rtc {
intptr_t (*open)(int major, int minor, struct fd *fd);
int (*close)(int major, int minor, struct fd *fd);
ssize_t (*read)(void *buf, size_t count);
};

struct dev_ops {
intptr_t (*open)(int major, int minor, struct fd *fd);
struct fd_ops fd;
Expand Down
2 changes: 1 addition & 1 deletion fs/devices.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#define DYN_DEV_MAJOR 240
// /dev/rtc
#define DEV_RTC_MAJOR 252
#define DEV_RTC_MINOR 0
#define DEV_RTC_MINOR 2


// /dev/clipboard
Expand Down
2 changes: 1 addition & 1 deletion fs/dyndev.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ int dyn_dev_register(struct dev_ops *ops, int type, int major, int minor) {
if (minor < 0 || minor > MAX_MINOR) {
return _EINVAL;
}
if (major != DYN_DEV_MAJOR) {
if ((major != DYN_DEV_MAJOR) && (major != DEV_RTC_MAJOR)) {
return _EINVAL;
}
if (ops == NULL) {
Expand Down
16 changes: 14 additions & 2 deletions fs/proc/ish.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,20 @@ static int proc_ish_show_version(struct proc_entry *UNUSED(entry), struct proc_d
return 0;
}

extern char* printBatteryStatus(void);
extern char* printBatteryStatus(int type);

static int proc_ish_show_battery(struct proc_entry *UNUSED(entry), struct proc_data *buf) {
proc_printf(buf, "%s", printBatteryStatus());
proc_printf(buf, "%s", printBatteryStatus(3));
return 0;
}

static int proc_ish_show_battery_capacity(struct proc_entry *UNUSED(entry), struct proc_data *buf) {
proc_printf(buf, "%s", printBatteryStatus(2));
return 0;
}

static int proc_ish_show_battery_status(struct proc_entry *UNUSED(entry), struct proc_data *buf) {
proc_printf(buf, "%s", printBatteryStatus(1));
return 0;
}

Expand All @@ -289,6 +299,8 @@ static int proc_ish_show_uidevice(struct proc_entry *UNUSED(entry), struct proc_

struct proc_children proc_ish_children = PROC_CHILDREN({
{"BAT0", .show = proc_ish_show_battery},
{"BAT0_capacity", .show = proc_ish_show_battery_capacity},
{"BAT0_status", .show = proc_ish_show_battery_status},
{"UIDevice", .show = proc_ish_show_uidevice},
{"colors", .show = proc_ish_show_colors},
{".defaults", S_IFDIR, .readdir = proc_ish_underlying_defaults_readdir},
Expand Down
Loading

0 comments on commit d573330

Please sign in to comment.