Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile.pc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ VERSION_TAG := $(shell git describe --abbrev=10 --dirty --always --tags)
PYTHON ?= python3

BIN := websrv.pc
SRCS := src/main.c src/websrv.c src/asset.c src/fs.c src/mime.c
SRCS := src/main.c src/websrv.c src/asset.c src/fs.c src/mime.c src/hwmonitor.c
SRCS += src/pc/sys.c

CFLAGS := -Wall -DVERSION_TAG=\"$(VERSION_TAG)\"
Expand Down
2 changes: 1 addition & 1 deletion Makefile.ps5
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ PYTHON ?= python3

BIN := websrv-ps5.elf

SRCS := src/main.c src/websrv.c src/asset.c src/fs.c src/mime.c
SRCS := src/main.c src/websrv.c src/asset.c src/fs.c src/mime.c src/hwmonitor.c
SRCS += src/mdns.c src/smb.c
SRCS += src/ps5/sys.c src/ps5/pt.c src/ps5/elfldr.c src/ps5/hbldr.c src/ps5/notify.c

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Examples:
- http://ps5:8080/smb?addr=192.168.1.1 - List shares on a remote SMB host (json)
- http://ps5:8080/smb/share?addr=192.168.1.1 - List files and folders shared by a remote SMB host (json)
- http://ps5:8080/smb/share/file?addr=192.168.1.1 - Download a remote SMB file via websrv
- http://ps5:8080/hwmonitor - Monitor CPU and SOC temperatures

## Installing Homebrew
The web server will search for homebrew in /data/homebrew, /mnt/usb%d/homebrew, /mnt/ext%d/homebrew,
Expand Down
128 changes: 128 additions & 0 deletions src/hwmonitor.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/* Copyright (C) 2025 Sunny Qeen
Copyright (C) 2024 John Törnblom

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>. */

#include "hwmonitor.h"
#include "mime.h"
#include "websrv.h"

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DATA_BUFFER_SIZE_MAX 4096
#define SOC_SENSOR_MAX 64

int sys_get_cpu_temperature(int* temperature);
int sys_get_soc_temperature(int index, int* temperature);

enum MHD_Result hwmonitor_request(struct MHD_Connection *conn)
{
const char* mime = "text/html";
const char* fmt;
int size = 0;
bool json = false;
int cpu_temperature = 0, soc_temperature[SOC_SENSOR_MAX] = {0}, soc_index;
enum MHD_Result ret = MHD_NO;
struct MHD_Response *resp;
char data[DATA_BUFFER_SIZE_MAX];
const char* html_header =
"<!DOCTYPE html>\r\n"
"<html>\r\n"
"<meta http-equiv=\"refresh\" content=\"2\">\r\n"
"<head>\r\n"
"<title>HWMonitor</title>\r\n"
"</head>\r\n"
"<body>\r\n"
"<h1>HWMonitor</h1>\r\n";

const char* html_footer =
"</body>\r\n"
"</html>\r\n";

fmt = MHD_lookup_connection_value(conn, MHD_GET_ARGUMENT_KIND, "fmt");
if(fmt && !strcmp(fmt, "json")) {
mime = "application/json";
json = true;
}

sys_get_cpu_temperature(&cpu_temperature);
for(soc_index = 0; soc_index < SOC_SENSOR_MAX; soc_index++) {
if(sys_get_soc_temperature(soc_index, soc_temperature + soc_index)) {
break;
}
}

if(json) {
int n = snprintf(data, DATA_BUFFER_SIZE_MAX, "{");
size += n;

if(cpu_temperature > 0) {
n = snprintf(data + size, DATA_BUFFER_SIZE_MAX - size, "\"cpu_temperature\":%d,", cpu_temperature);
size += n;
}

if(soc_index > 0) {
n = snprintf(data + size, DATA_BUFFER_SIZE_MAX - size, "\"soc_temperature\":[");
size += n;
for(int i = 0; i < soc_index; i++) {
n = snprintf(data + size, DATA_BUFFER_SIZE_MAX - size, "%d,", soc_temperature[i]);
size += n;
}

size--;
n = snprintf(data + size, DATA_BUFFER_SIZE_MAX - size, "],");
size += n;
}

if(size > 1) {
size--;
}
n = snprintf(data + size, DATA_BUFFER_SIZE_MAX - size, "}");
size += n;
} else {
int n = snprintf(data, DATA_BUFFER_SIZE_MAX, "%s", html_header);
size += n;

if(cpu_temperature > 0) {
n = snprintf(data + size, DATA_BUFFER_SIZE_MAX - size, "<p>CPU Temperature: %d&deg;C %d&deg;F</p>\r\n", cpu_temperature, cpu_temperature * 18 / 10 + 32);
size += n;
}

if(soc_index > 0) {
n = snprintf(data + size, DATA_BUFFER_SIZE_MAX - size, "<p>SOC Temperature:</p>\r\n");
size += n;
for(int i = 0; i < soc_index; i++) {
n = snprintf(data + size, DATA_BUFFER_SIZE_MAX - size, "<p>&emsp;[S%02d]: %d&deg;C %d&deg;F</p>\r\n", i + 1, soc_temperature[i], soc_temperature[i] * 18 / 10 + 32);
size += n;
}
}

n = snprintf(data + size, DATA_BUFFER_SIZE_MAX - size, "%s", html_footer);
size += n;
}

if((resp=MHD_create_response_from_buffer(size, data,
MHD_RESPMEM_PERSISTENT))) {
MHD_add_response_header(resp, MHD_HTTP_HEADER_CONTENT_TYPE,
mime);
ret = websrv_queue_response(conn, MHD_HTTP_OK, resp);
MHD_destroy_response(resp);
}

return ret;
}
25 changes: 25 additions & 0 deletions src/hwmonitor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* Copyright (C) 2025 Sunny Qeen
Copyright (C) 2024 John Törnblom

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>. */

#pragma once

#include <microhttpd.h>

/**
* Respond to a hwmonitor request.
**/
enum MHD_Result hwmonitor_request(struct MHD_Connection *conn);
11 changes: 11 additions & 0 deletions src/pc/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,14 @@ sys_launch_payload(const char* cwd, uint8_t* elf, size_t elf_size,
return sys_launch_homebrew(cwd, filename, args, env);
}

int
sys_get_cpu_temperature(int* temperature) {
printf("get cpu temperature");
return -1;
}

int
sys_get_soc_temperature(int index, int* temperature) {
printf("get soc[%02d] temperature", index);
return -1;
}
15 changes: 15 additions & 0 deletions src/ps5/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ int sceSystemServiceKillApp(int app_id, int how, int reason, int core_dump);
int sceSystemServiceLaunchApp(const char* title_id, char** argv,
app_launch_ctx_t* ctx);

int sceKernelGetCpuTemperature(int *);
int sceKernelGetSocSensorTemperature(int, int *);

/**
* Decode an escaped argument.
Expand Down Expand Up @@ -372,6 +374,19 @@ sys_launch_title(const char* title_id, const char* args) {
return err;
}


int
sys_get_cpu_temperature(int* temperature) {
return sceKernelGetCpuTemperature(temperature);
}


int
sys_get_soc_temperature(int index, int* temperature) {
return sceKernelGetSocSensorTemperature(index, temperature);
}


/**
*
**/
Expand Down
4 changes: 4 additions & 0 deletions src/websrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ along with this program; see the file COPYING. If not, see
#include "smb.h"
#include "sys.h"
#include "version.h"
#include "hwmonitor.h"
#include "websrv.h"


Expand Down Expand Up @@ -324,6 +325,9 @@ websrv_on_request(void *cls, struct MHD_Connection *conn,
if(!strcmp("/version", url)) {
return version_request(conn);
}
if(!strcmp("/hwmonitor", url)) {
return hwmonitor_request(conn);
}
if(!strcmp("/", url) || !url[0]) {
return asset_request(conn, "/index.html");
}
Expand Down