Last active
July 12, 2024 23:26
-
-
Save jfmherokiller/53279e9251b5dd0c463ec8028df7192e to your computer and use it in GitHub Desktop.
towel.blinkenlights.nl switch example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Usage: | |
put the telnet.nro and telnet.conf files in the /switch folder |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 3.5) | |
set(CMAKE_C_STANDARD 11) | |
set(CMAKE_CXX_STANDARD 11) | |
add_executable(stelenet stelnet.c) | |
target_link_libraries(stelenet -lnx ) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
SimpleTelnet: a simple telnet client suitable for embedded systems | |
Copyright (C) 2013 [email protected] | |
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 2 of the License, 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; if not, write to the Free Software | |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <arpa/inet.h> | |
#include <sys/socket.h> | |
#include <sys/select.h> | |
//#include <termios.h> | |
#include <fcntl.h> | |
#include <switch.h> | |
#include <netdb.h> | |
#include <limits.h> | |
#define DO 0xfd | |
#define WONT 0xfc | |
#define WILL 0xfb | |
//#define DONT 0xfe | |
#define CMD 0xff | |
//#define CMD_ECHO 1 | |
#define CMD_WINDOW_SIZE 31 | |
char ServerIP[255]; | |
char ServerPort[255]; | |
int sock; | |
void ExitProgram() { | |
close(sock); | |
gfxExit(); | |
socketExit(); | |
} | |
void ReadConfigFile(char *ConfigFileName) { | |
FILE *configfile = fopen(ConfigFileName, "r"); | |
if (configfile == NULL) perror("Error opening file"); | |
//GetServerIP | |
fgets(ServerIP, 255, configfile); | |
//GetServerPort | |
fgets(ServerPort, 255, configfile); | |
//remove the newline chars | |
strtok(ServerIP, "\n\r"); | |
strtok(ServerPort, "\n\r"); | |
fclose(configfile); | |
} | |
//Get Ip of the host and write it to the server | |
void GetHostIp(char *name, struct sockaddr_in *in) { | |
struct hostent *he; | |
struct in_addr **addr_list; | |
// get the host info | |
if ((he = gethostbyname(name)) == NULL) { | |
herror("gethostbyname"); | |
sleep(5); | |
exit(0); | |
} else { | |
// print information about this host: | |
printf("Official name is: %s\n", he->h_name); | |
printf(" IP addresses: "); | |
addr_list = (struct in_addr **) he->h_addr_list; | |
for (int i = 0; addr_list[i] != NULL; i++) { | |
printf("%s ", inet_ntoa(*addr_list[i])); | |
} | |
printf("\n"); | |
memcpy(&(in->sin_addr), he->h_addr_list[0], (size_t) he->h_length); | |
} | |
freehostent(he); | |
} | |
void negotiate(int sock, unsigned char *buf, size_t len) { | |
if (buf[1] == DO && buf[2] == CMD_WINDOW_SIZE) { | |
unsigned char tmp1[10] = {255, 251, 31}; | |
if (send(sock, tmp1, 3, 0) < 0) | |
exit(1); | |
unsigned char tmp2[10] = {255, 250, 31, 0, 80, 0, 24, 255, 240}; | |
if (send(sock, tmp2, 9, 0) < 0) | |
exit(1); | |
return; | |
} | |
for (int i = 0; i < len; i++) { | |
if (buf[i] == DO) | |
buf[i] = WONT; | |
else if (buf[i] == WILL) | |
buf[i] = DO; | |
} | |
if (send(sock, buf, len, 0) < 0) | |
exit(1); | |
} | |
#define BUFLEN 20 | |
int main(int argc, char *argv[]) { | |
atexit(ExitProgram); | |
gfxInitDefault(); | |
//Initialize console. Using NULL as the second argument tells the console library to use the internal console structure as current one. | |
consoleInit(NULL); | |
socketInitializeDefault(); | |
ReadConfigFile("/switch/telnet.conf"); | |
struct sockaddr_in server; | |
bzero(&server, sizeof(server)); | |
unsigned char buf[BUFLEN + 1]; | |
ssize_t len; | |
//Create socket | |
sock = socket(AF_INET, SOCK_STREAM, 0); | |
if (sock == -1) { | |
perror("Could not create socket. Error"); | |
return 0; | |
} | |
//setup server struct with needed addtesss and resolve host | |
server.sin_family = AF_INET; | |
server.sin_port = htons((uint16_t) atoi(ServerPort)); | |
GetHostIp(ServerIP, &server); | |
//Connect to remote server | |
if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) { | |
perror("connect failed. Error"); | |
return 0; | |
} | |
puts("Connected...\n"); | |
// set terminal | |
//terminal_set(); | |
//atexit(terminal_reset); | |
struct timeval ts; | |
ts.tv_sec = 1; // 1 second | |
ts.tv_usec = 0; | |
// select setup | |
fd_set fds; | |
FD_ZERO(&fds); | |
if (sock != 0) { | |
FD_SET(sock, &fds); | |
} | |
//FD_SET(0, &fds); | |
while (appletMainLoop()) { | |
hidScanInput(); | |
// wait for data | |
int nready = select(sock + 1, &fds, 0, 0, &ts); | |
if (nready < 0) { | |
perror("select. Error"); | |
break; | |
} else if (nready == 0) { | |
ts.tv_sec = 1; // 1 second | |
ts.tv_usec = 0; | |
} else if (sock != 0 && FD_ISSET(sock, &fds)) { | |
// start by reading a single byte | |
ssize_t rv; | |
if ((rv = recv(sock, buf, 1, 0)) < 0) | |
break; | |
else if (rv == 0) { | |
printf("Connection closed by the remote end\n\r"); | |
break; | |
} | |
if (buf[0] == CMD) { | |
// read 2 more bytes | |
len = recv(sock, buf + 1, 2, 0); | |
if (len < 0) | |
break; | |
else if (len == 0) { | |
printf("Connection closed by the remote end\n\r"); | |
break; | |
} | |
negotiate(sock, buf, 3); | |
} else { | |
len = 1; | |
buf[len] = '\0'; | |
printf("%s", buf); | |
fflush(0); | |
} | |
//Send Disabled because there is no way to send text input yet | |
} /*else if (FD_ISSET(0, &fds)) { | |
buf[0] = getc(stdin); //fgets(buf, 1, stdin); | |
if (send(sock, buf, 1, 0) < 0) | |
break; | |
if (buf[0] == '\n') // with the terminal in raw mode we need to force a LF | |
putchar('\r'); | |
}*/ | |
//hidKeysDown returns information about which buttons have been just pressed (and they weren't in the previous frame) | |
u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO); | |
if (kDown & KEY_PLUS) break; // break in order to return to hbmenu | |
gfxFlushBuffers(); | |
gfxSwapBuffers(); | |
gfxWaitForVsync(); | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
set(DEVKITPRO "/opt/devkitpro") | |
set(NX 1) | |
set(CMAKE_SYSTEM_NAME "Generic") | |
set(CMAKE_C_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-gcc") | |
set(CMAKE_CXX_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-g++") | |
set(CMAKE_AR "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-gcc-ar" CACHE STRING "") | |
set(CMAKE_RANLIB "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-gcc-ranlib" CACHE STRING "") | |
set(PKG_CONFIG "${DEVKITPRO}/portlibs/bin/aarch64-none-elf-pkg-config" CACHE STRING "") | |
set(CPPFLAGS "-D__SWITCH__ -I${DEVKITPRO}/libnx/include -I${DEVKITPRO}/portlibs/switch/include") | |
set(CMAKE_C_FLAGS "${CPPFLAGS} -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIC -ffunction-sections" CACHE STRING "C flags") | |
set(CMAKE_CXX_FLAGS "${CPPFLAGS} ${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions -std=gnu++11" CACHE STRING "C++ flags") | |
set(CMAKE_FIND_ROOT_PATH ${DEVKITPRO}/devkitA64 ${DEVKITPRO}/libnx ${DEVKITPRO}/portlibs/switch) | |
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) | |
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) | |
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) | |
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) | |
#set(CMAKE_STATIC_LINKER_FLAGS_INIT "-march=armv8-a -mtune=cortex-a57 -mtp=soft -L${DEVKITPRO}/libnx/lib -L${DEVKITPRO}/portlibs/switch/lib") | |
set(CMAKE_EXE_LINKER_FLAGS_INIT "-specs=${DEVKITPRO}/libnx/switch.specs -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE -L${DEVKITPRO}/libnx/lib -L${DEVKITPRO}/portlibs/switch/lib") | |
set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "Shared libs not available") | |
set(CMAKE_INSTALL_PREFIX ${DEVKITPRO}/portlibs/switch) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
towel.blinkenlights.nl | |
23 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment