RESTful web-services in JSIDPlay2

You can implement your own client to access this emulator. You can access this emulator by using the following service methods to stream music or browse music collection directories. The service methods are available as soon as you click start in the built-in AppServer in JSIDPlay2.

Preparation

Info: All commands showed here have been verified on Ubuntu 18.

General

All the following RESTful service methods of JSIDPlay2 AppServer are using your configured music collections HVSC and CGSC. To make the following examples to work, first configure HVSC and CGSC music collection in JSIDPlay2, properly! If you can browse these music collections in JSIDPlay2 the service methods can browse and stream the contained tune files as well.

Security

Basic authentication is used calling the services with the following credentials:

  • Username: jsidplay2

  • Password: jsidplay2!

You can change the settings of the user or add an administrative user by an external configuration file. The file must be named: "realm.properties" located in your home directory and be readable on startup of the server. The reason why you can add an administrative user is to grant access to additional private music collections for him.

Example:

#
# This file defines users passwords and roles for a HashUserRealm
#
# The format is
#  <username>: <password>[,<rolename> ...]
#
# Passwords may be clear text, obfuscated or checksummed.  The class
# org.eclipse.jetty.util.security.Password should be used to generate obfuscated
# passwords or password checksums
#
# If DIGEST Authentication is used, the password must be in a recoverable
# format, either plain text or OBF:.
#
#jetty: MD5:164c88b302622e17050af52c89945d44,user
#admin: CRYPT:adpexzg3FUZAk,server-administrator,content-administrator,admin,user
#other: OBF:1xmk1w261u9r1w1c1xmq,user
#plain: plain,user
#user: password,user
# This entry is for digest auth.  The credential is a MD5 hash of username:realmname:password
#digest: MD5:6e120743ad67abfbc385bc2bb754e297,user

jsidplay2: jsidplay2!,user
administrator: MD5:0bd6506986ec42e732ffb866d33bb14e,admin

All known roles are user and admin.

Use Self-signed certificate

To create a self-signed certificate you must use the keytool command of the java installation

keytool -genkey -alias sitename -keyalg RSA -keystore /etc/jsidplay2.ks -keysize 2048 (1)
  1. Warning: A self-signed certificate is only a temporary solution, since it creates a warning message in the browser window and is unaccepted by iPhones and mobiles running Android9!

Use trusted certificate

Info: This example is related to Let’s Encrypt and Apache2 installation on Linux.

If your web-server and JSIDPlay2 server is both in the same domain, then you can use HTTPS using the same certificate for both: your web-server and JSIDPlay2 AppServer. This is a step by step instruction of how it works.

First lets make the Apache2 web-server secure, which is very easy with Let’s Encrypt, these days:

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-apache
sudo certbot --apache

For automatic renewal a cron job is created by Let’s Encrypt. Let’s Encrypt already adds the certbot script to renew certificates regularly.

Important: In order to re-use these renewed certificates for JSIDPlay2 we add a cronjob as well (script /usr/bin/jsidplay2cert). Our cronjob creates the Java keystore (/etc/jsidplay2.ks) out of the certificates renewed by Let’s Encrypt.

To configure that cronjob type 'sudo crontab -e' and add the last line containing jsidplay2cert:

#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command
40 3 * * 0 certbot -q renew
@weekly root jsidplay2cert (1)
  1. jsidplay2cert is a script we have to execute in order to create our keystore (/etc/jsidplay2.ks), weekly

Now create the script to be executed by cronjob typing 'sudo vi /usr/bin/jsidplay2cert':

#!/bin/bash

# create one big certificate file PEM
cat /etc/letsencrypt/live/haendel.ddns.net/{cert.pem,chain.pem,fullchain.pem,privkey.pem} \
	> /tmp/fullchain.pem

# convert certificate file PEM to PKCS12 required by keytool
openssl pkcs12 -export -out /tmp/fullchain.pkcs12 -in /tmp/fullchain.pem \
	-password pass:jsidplay2 >> /var/log/jsidplay2cert.log 2>&1
rm /tmp/fullchain.pem >> /var/log/jsidplay2cert.log 2>&1

# Create empty keystore, first we create one, then we remove contents again
rm /etc/jsidplay2.ks >> /var/log/jsidplay2cert.log 2>&1
keytool -genkey -keyalg RSA -alias jsidplay2 -keystore /etc/jsidplay2.ks \
	-storepass jsidplay2 -keypass jsidplay2 \
	-dname 'cn="JSIDPlay2", ou="JSIDPlay2", o="Open Source", l="Berlin", c=DE' \
	>> /var/log/jsidplay2cert.log 2>&1
/usr/bin/keytool -delete -alias jsidplay2 -keystore /etc/jsidplay2.ks -storepass jsidplay2 \
	>> /var/log/jsidplay2cert.log 2>&1

# Import certificate into keystore, first we import the certificates, \
	then we need to change the alias name
keytool -v -importkeystore -srckeystore /tmp/fullchain.pkcs12 \
	-destkeystore /etc/jsidplay2.ks -deststoretype JKS -srcstorepass jsidplay2 \
	-deststorepass jsidplay2 >> /var/log/jsidplay2cert.log 2>&1
rm /tmp/fullchain.pkcs12 >> /var/log/jsidplay2cert.log 2>&1
keytool -keystore /etc/jsidplay2.ks -changealias -alias 1 -destalias jsidplay2 \
	-storepass jsidplay2 >> /var/log/jsidplay2cert.log 2>&1

sudo -i -u ken /home/ken/server.sh >> /var/log/jsidplay2cert.log 2>&1 (1)
  1. At last our server gets restarted with the renewed certificate, please refer to Launch JSIDPlay2 AppServer using HTTPS

Now, grant permission to execute that script by our cronjob:

sudo chmod 755 /usr/bin/jsidplay2cert

As a result we get weekly a fresh new keystore (/etc/jsidplay2.ks). A log file for troubleshooting is placed here (/var/log/jsidplay2cert)

Launch JSIDPlay2 AppServer using HTTP

First lets explain how to start JSIDPlay2 AppServer in general for unencrypted HTTP connections and without the created keystore above:

Info: You can start the built-in AppServer standalone using the following command in a console window, instead of starting the UI version of JSIDPlay2:

To start the JSIPlay2 AppServer without HTTPS, but only HTTP, please use the following command

java -classpath jsidplay2-4.0.jar server.restful.JSIDPlay2Server (1)
  1. Launch the JSIDPlay2 AppServer standalone

For all supported parameters, please type:

java -classpath jsidplay2-4.0.jar server.restful.JSIDPlay2Server --help (1)
  1. Show usage of the JSIDPlay2 AppServer standalone

Launch JSIDPlay2 AppServer using HTTPS

Now lets explain how to start JSIDPlay2 AppServer using encrypted HTTPS connections with the keystore created above:

To start the JSIPlay2 AppServer with HTTPS using the formerly created keystore, you can use the following script, please type 'vi ~/server.sh':

#!/bin/bash -x
cd /home/ken/Downloads/jsidplay2-4.0
pkill -f server.restful.JSIDPlay2Server
java -server -classpath jsidplay2-4.0.jar server.restful.JSIDPlay2Server \
	--appServerKeystore /etc/jsidplay2.ks \
	--appServerManagerPassword jsidplay2 \
	--appServerKeystorePassword jsidplay2 \
	--appServerConnectors HTTPS & (1)
  1. Launch the JSIDPlay2 AppServer using HTTPS standalone

Note: Parameter appServerConnectors controls if we want to support HTTP, HTTPS or both!

Warning: The passwords will always be deleted after exit of JSIDPlay2 to not appear in the configuration file of JSIDPlay2 for security reasons!

Now, grant permission to execute that script:

sudo chmod 755 ~/server.sh

Now, we are finished to launch JSIDPlay2 using HTTP or HTTPS

Autostart JSIDPlay2 AppServer on system startup

To start JSIPlay2 AppServer on system startup, please type 'vi /etc/systemd/jsidplay2.service':

[Unit]
Wants=network-online.target
After=network.target network-online.target

[Service]
ExecStart=/usr/bin/java -server \
	-classpath /home/ken/Downloads/jsidplay2-4.0/jsidplay2-4.0.jar \
	server.restful.JSIDPlay2Server \
	--appServerKeystore /etc/jsidplay2.ks \
	--appServerManagerPassword jsidplay2 \
	--appServerKeystorePassword jsidplay2 \
	--appServerConnectors HTTP_HTTPS
User=ken

[Install]
WantedBy=default.target

Now, grant permission and enable jsidplay2.service to autostart:

chmod 644 /etc/systemd/jsidplay2.service
sudo systemctl daemon-reload
sudo systemctl enable /etc/systemd/jsidplay2.service

Access from the Internet

To use your client from within your private local area network does not require additional preparations, you just need to know and reach the IP address, where JSIDPlay2 is running on.

But, if you want to use a client from any location in the internet, that would require some additional preparations:

  1. You will need a hostname which resolves to the IP-address of your always reachable server, where JSIDPlay2 is running on (e.g. using a provider like https://freeddns.noip.com and configure dynamic DNS inside your router)

  2. You will need to configure your router to redirect requests to that server: port forwarding. You should forward requests using the port, that you configured for the built-in AppServer in JSIDPlay2 (8080 and 8443). This will make it necessary to configure a fixed IP address for your server within your local area network, beforehand. Now you can forward all related traffic to your server where JSIDPlay2 is running on.

Warning: Keep in mind, that opening ports in your firewall will raise the security risk. You will make yourself vulnerable to attacks from hackers.

Note: I will not take responsability for any risks or damages. Do this on your own risk!

JSIDPlay2 AppServer Usage of the RESTful services

Info: Depending on the connection type of JSIDPlay2 AppServer you have to use HTTP or HTTPS as protocol and port 8080 (HTTP) or 8443 (HTTPS). Please refer the command-line parameters appServerConnectors, appServerPort and appServerSecurePort!

Get all SID filter names (required to stream SID as MP3 later)

Note: SID filter names are prefixed with the emulation engine (RESID or RESIDFP) and the SID model (MOS6581 or MOS8580) and appended by their name, e.g. RESID_MOS8580_FilterAverage8580, That way filters can be grouped or sorted on the client side.

Get music collection directory

You can access any sub-directory of your music collection to navigate to the tunes you want to play on the client side. HVSC music collection root path starts with "/C64Music/" and CGSC music collection starts with "/CGSC/". Please append any sub-directory behind that root path to get the desired directory contents. Directory type entries are appended by a slash, whereas file type entries like tunes ends with their file extensions. To each directory contents a parent folder entry will be added appended by "../". Following that directory entry, you can easily navigate back to the parent directory. Additionally you can specify a file extension filter using the parameter filter, e.g. ".*\\.(sid|dat|mus|str|p00|prg|d64|mp3|mp4)$"

You can add more collections by creating an external configuration file located in your home directory. The file must be named: "directoryServlet.properties" and be readable on startup of the server.

Example:

/MP3=/media/nas1/mp3,true (1)
/Demos=/home/ken/.jsidplay2/Demos.zip,false
  1. Syntax is: "<localDirectoryNameInTheRequest>" = "<realDirectoryName>", "<adminRoleRequired>" In the request above simply replace "/jsidplay2service/JSIDPlay2REST/directory/C64Music/…​" by "/jsidplay2service/JSIDPlay2REST/directory/MP3" to access your collection

Get tune infos

Return a list of information of the specified tune file.

Get contents of the first SID favorites tab

Return a list of favorite tune files.

Get composer photo

Return a photo of a well-known tune composer to be displayed on the client side.

Download SID

Download a tune file of your music collection to the client.

Stream SID as MP3

Return a mp3 stream of the specified tune. On the server side the emulator is started and streams the sound output back to the client. All parameters are used to specify emulation settings that should be used. Especially the MP3 parameters control the quality and size of the returned mp3 stream (vbr, cbr and vbrQuality). Using these parameter gives you the control about mobile phone transfer data volume and especially the costs that arise, if you stream over the internet using your specific mobile phone provider contract (as nobody has an unlimited flat rate these days). It is recommended to use less data volume with less precision (lower quality) for connections over the internet and higher data volume with more precision (higher quality) inside your private local network, e.g. WLAN connection. I have implemented an example android app as a client for the built-in AppServer of JSIDPlay2. My android app uses constant bitrate of 64K for the internet and variable bitrate and highest quality for my private WLAN. This is according to my recommendation above.

For a description of all possible parameters please call console player’s usage, because they are exactly the same. But keep in mind you must use the gnu-style parameter syntax and leave away "--":

cd Downloads/jsidplay2-4.0
java -jar jsidplay2_console-4.0.jar --help (1)
  1. Show ConsolePlayer’s usage for a description of all parameters

Stream Demo as MP4

Info: This service method does only work, if directoryServlet had been configured before to grant access to "/Demos"!

For a description of all possible parameters please call console player’s usage, because they are exactly the same. But keep in mind you must use the gnu-style parameter syntax and leave away "--":

cd Downloads/jsidplay2-4.0
java -jar jsidplay2_console-4.0.jar --help (1)
  1. Show ConsolePlayer’s usage for a description of all parameters

Note: I will not take responsability for any costs, that arise from streaming mp3 files from the internet!

Info: All Parameter names match exactly the command line parameter names of the console player in gnu style (prepended by --). For example defaultLength=180 sets the default song length.

Android Client for JSIDPlay2 AppServer

Source code of the example Android app using the RESTful web-service interface can be found here.

Click here to Get the Installer for JSIDPlay2 App.
Please note: Streaming music using your mobile can cause additional costs!