Don't wanna be here? Send us removal request.
Text
MQTT for the C64
We are lucky!
Thanks to the work of Stephen Robinson there is already an implementation of MQTT for Contiki Link
So the integration is quite straight forward.
We have to include the new mqtt-msg.c and mqtt-sevrice.c to our Makefile by adding:
override webserver_src = webserver-nogui.c httpd.c http-strings.c psock.c memb.c \ httpd-fs.c httpd-cgi.c uip.c mqtt-msg.c mqtt-service.c
to our Makefile.
And of course we have to add some code to our webserver-example.c
First we have to include the mqtt-service.h
#include "mqtt-service.h"
Then we have to extend our PROCESS_THREAD with some mqtt "glue":
PROCESS_THREAD(get_temp_process, ev, data) { static struct etimer timer; static uip_ipaddr_t server_address; // Allocate buffer space for the MQTT client static uint8_t in_buffer[64]; static uint8_t out_buffer[64]; static uint8_t message[64]; // Setup an mqtt_connect_info_t structure to describe // how the connection should behave static mqtt_connect_info_t connect_info; connect_info.client_id = "c64contiki"; connect_info.username =NULL; connect_info.password = NULL; connect_info.will_topic = NULL; connect_info.will_message = NULL; connect_info.keepalive = 60; connect_info.will_qos = 0; connect_info.will_retain = 0; connect_info.clean_session = 1; PROCESS_BEGIN(); // Set the server address uip_ipaddr(&server_address, 192,168,1,43); // Initialise the MQTT client mqtt_init(in_buffer, sizeof(in_buffer), out_buffer, sizeof(out_buffer)); // Ask the client to connect to the server // and wait for it to complete. mqtt_connect(&server_address, UIP_HTONS(1883), 1, &connect_info); PROCESS_WAIT_EVENT_UNTIL(ev == mqtt_event); httpd_cgi_add(&MyTemp); // Set the server address etimer_set(&timer, 5*CLOCK_SECOND); while(1) { PROCESS_WAIT_EVENT(); if (ev == PROCESS_EVENT_TIMER) { //printf("Timer Event\n"); etimer_reset(&timer); gettemp(); // Send some MQTT stuff if (mqtt_ready()){ sprintf(message,"%d.%d",nMyTemperatur,nMyTemperaturDecimal); mqtt_publish("c64temp", message, 0, 1); } } } mqtt_disconnect(); PROCESS_END(); }
The command uip_ipaddr sets the IP address of our MQTT broker (e.g. a mosquitto). With mqtt_init(..) we initialize the MQTT process and with mqtt_connect(..) we connect to the broker.
If we now check our temperature every 5 seconds or so we can send out the value with mqtt_publish(...).
The mqtt topic is set in this example to "c64temp". You will receive this as "C64TEMP" in your broker.
One important thing is left. We have to tell Contiki to start the new MQTT process:
AUTOSTART_PROCESSES(&webserver_nogui_process,&get_temp_process, &mqtt_process);
We have to change to little things in the code of Stephen Robinson before we can compile this all:
We have to move the statement "PROCESS_NAME(mqtt_process);" from the mqtt-service.c to the mqtt-service.h file.
Now after a recompile of everything we have a web server and a MQTT client running on a Commodore 64.
0 notes
Text
C64 as MQTT Client? Never!.... or is it?
Since I now have a running web server with a temperature sensor, I was wondering if it is possible to connect this sensor to the rest of my home automation.
Unfortunately my complete home automation setup is build on the MQTT protocol. But can a C64 be a MQTT Client?
If you believe the "OASIS Message Queuing Telemetry Transport Technical Committee" the MQTT protocol was designed to work in small sensors (or even in big ones).
I'm not sure if they had the C64 in mind, but believe it or not: It is possible!
But first things first.
All you need is the capability to use TCP/IP communication. A MQTT communication (from client to server (broker)) starts with a TCP/IP connection to port 1883 of your MQTT broker host.
The protocol itself is very simple and very straight forward. Because we do not need the complete protocol, we can focus on the "CONNECT" and "PUBLISH" commands (see MQTT V3).
So implement the protocol from scratch?
1 note
·
View note
Text
CSS and WOFF
The C64.css was inspired by many different files I found online. I'm not sure where I get this: @font-face {
/** * http://style64.org/c64-truetype * see license.txt in font directory for details. */ font-family: "C64 User Mono"; src: url("c64.woff") format('woff'); }
html { background: #473EAC; }
body { width: auto; margin: 50px auto; font-size: 30px; font-weight: bold; line-height: 10px; -webkit-font-smoothing: antialiased; }
a:link { color: #8980E2; }
/* visited link */ a:visited { color: #8980E2; }
/* mouse over link */ a:hover { color: #000000; }
/* selected link */ a:active { color: #8980E2; }
.text { padding-top: 20px; }
h1 { color: #8980E2; text-align: center; font-family: 'C64 User Mono'; font-size: 26px; margin-left: 58px; letter-spacing: 0px; line-height: 26px; }
.ready { color:#8980E2; font-family: 'C64 User Mono'; font-size: 26px; margin-left: 58px; letter-spacing: 0px; line-height: 26px; text-decoration: none; }
#typed-cursor { font-weight: 100; font-size: 26px; color: #8980E2; margin-left: 58px; line-height: 26px; }
#typed-cursor.blinking { -webkit-animation: 1s blink step-end infinite; -moz-animation: 1s blink step-end infinite; -ms-animation: 1s blink step-end infinite; -o-animation: 1s blink step-end infinite; animation: 1s blink step-end infinite; }
@keyframes "blink" { from,to { color: transparent; }
50% { color: #8980E2; }
}
@-moz-keyframes blink { from,to { color: transparent; }
50% { color: #8980E2; } }
@-webkit-keyframes "blink" { from,to { color: transparent; }
50% { color: #8980E2; }
}
@-ms-keyframes "blink" {
from,to {
color: transparent;
}
50% {
color: #8980E2;
}
}
@-o-keyframes "blink" {
from,to {
color: transparent;
}
50% {
color: #8980E2;
}
}
The need font file c65.woff can be found here https://style64.org/c64-truetype
1 note
·
View note
Text
Her we go again - HTML
To build this "Commodore Style" web page you need a few things:
index.htm
404.html
temp.js
temp.shtml
c64.css
c64.woff
index.htm is the main page:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"/> <title>Commodore 64</title> <link rel="stylesheet" href="c64.css"> <style> #top, #bottom, #left, #right { background: #8880E0; } #left, #right { position: fixed; top: 0; bottom: 0; width: 55px; } #left { left: 0; } #right { right: 0; } #top, #bottom { position: fixed; left: 0; right: 0; height: 55px; } #top { top: 0; } #bottom { bottom: 0; } @media /* Fairly small screens including iphones */ only screen and (max-width: 500px), /* iPads */ only screen and (min-device-width: 768px) and (max-device-width: 1024px) { #top, #bottom, #left, #right { display: none; } } </style> <script type="text/javascript" src="/temp.js"></script> </head> <body> <div class="text"> <!h1> <br></h1> <h1>**** COMMODORE 64 BASIC V2 ****</h1> <!h1> <br></h1> <h1>64K RAM SYSTEM 38911 BASIC BYTES FREE</h1> <!h1> <br></h1> </div> <div class="ready">READY.</div> <div class="ready">LOAD "WEBSERVER",8</div> <div class="ready"> </div> <div class="ready">SEARCHING FOR WEBSERVER</div> <div class="ready">LOADING</div> <div class="ready">READY.</div> <div class="ready">LIST</div> <div class="ready"> </div> <div class="ready">10 PRINT "THIS IS A REAL COMMODORE 64"</div> <div class="ready">20 PRINT "RUNNING A WEBSERVER WITH <a href="http://contiki-os.org">CONTIKI</a>"</div> <div class="ready">30 PRINT "JUST FOR FUN."</div> <div class="ready">READY. </div> <div class="ready"> </div> <div class="ready">CURRENT TEMPERATURE: <span id="displayCelsius">24,7</span> ° C</div> <span id="typed-cursor" class="blinking">█</span> <pre> <div id="left"></div> <div id="right"></div> <div id="top"></div> <div id="bottom"></div> </pre> </body> </html>
The 404.html page is the default page for unknown subpages:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <html> <head> <title>404 - file not found</title> </head> <body bgcolor="white"> <h1 align="center">404 - file not found</h1> <h3 align="center">Go <a href="/">here</a> instead.</h3> </body> </html>
The temp.js is the JavaScript to get the temperature data:
var requestpending; var killswitch = 0; var datacounter = 0; var timer; var xmlhttp; var url= "/temp.shtml"; function xmlrequeststatechange() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { try { var s = xmlhttp.responseText; document.getElementById("displayCelsius").innerHTML=s; }equestpending; var killswitch = 0; var datacounter = 0; var timer; var xmlhttp; var url= "/temp.shtml"; function xmlrequeststatechange() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { try { var s = xmlhttp.responseText; document.getElementById("displayCelsius").innerHTML=s;
var requestpending; var killswitch = 0; var datacounter = 0; var timer; var xmlhttp; var url= "/temp.shtml"; function xmlrequeststatechange() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { try { var s = xmlhttp.responseText; document.getElementById("displayCelsius").innerHTML=s; } catch(err) { } requestpending=false; } }
function xmlrequesttimeout() { requestpending=false; }
function dattding() { if (requestpending) { killswitch++; if (killswitch<20) { return; } else { xmlhttp.abort(); } }
xmlhttp=new XMLHttpRequest(); xmlhttp.onreadystatechange=xmlrequeststatechange; xmlhttp.ontimeout=xmlrequesttimeout; xmlhttp.open("GET",url,true); xmlhttp.timeout = 10000; xmlhttp.send(); requestpending=true; }
function bstopp() { clearInterval(timer); }
function bstart() { clearInterval(timer); timer=setInterval(dattding, 5000); }
window.onload=bstart;
The file temp.shtml is the server sides include to return: %! temp
About the c64.css and c4.woff in the next post.
0 notes
Text
A new Website in Commodore Style
After the first steps into this shiny new world now here a suggestion for the webpage:

1 note
·
View note
Text
Last but not Least
Now we want to see the temperature in our web page.
For this we need to a a new file temperature.shtml into our httpd-fs folder looking like this:
%!: /header.html <h4>System temperature</h4> %! temp ° Celsius %!: /footer.html
Than we need to edit the files index.html and header.html in order to add the following row in both files:
<a href="temperature.shtml">System temperature</a><br>
And of course if we change anything inside the httpd-fs folder we have to run our PERL script again
perl ..\..\tools\makefsdata -d httpd-fs
We have to compile everything again with
make disk TARGET=c64
and start our system with the new files again.
It should now looks like this

And if you click on “System temperature” you will get

So the rest is p to you. Good look and have fun with your C64 web server!
p.s.: you can find all files for MyWebserver here:
https://drive.google.com/open?id=0B4C4ElgdZbjdLXRsOGdFdjhVM2c
0 notes
Text
Adding some CGI
To get the temperature in HTTP we need some CGI_CALL added to the HTTP server.
To do this we need to add some CGI_CALL macro:
HTTPD_CGI_CALL(MyTemp, MyTemp_name, MyTemp_thread);
With this we define the CGI_CALL MyTemp with its name MyTemp_name and the corresponding thread MyTemp_thread, which is called by the CGI engine inside the web server. Out course, the MyTemp_name has to be defined:
/* "temp" */ const char MyTemp_name[5] = {0x74, 0x65, 0x6d, 0x70, };
The thread looks like that
static PT_THREAD(MyTemp_thread(struct httpd_state *s, char *ptr)) { PSOCK_BEGIN(&s->sout); PSOCK_GENERATOR_SEND(&s->sout, make_temp, s->u.ptr); PSOCK_END(&s->sout); }
The PSOCK macros helps to setup and generate HTTP responses. Inside the macro PSOCK_GENERATOR_SEND the function “make_temp” is called.
static unsigned short make_temp(void *p) { uint16_t numprinted; numprinted=snprintf( (char *)uip_appdata, uip_mss(),"%d.%d",nMyTemperatur,nMyTemperaturDecimal); return numprinted; }
To enable the CGI_CALL we have to add some more things. Inside the function PROCESS_THREAD(get_temp_process, ev, data) we have to add just behind PROCESS_BEGIN();
httpd_cgi_add(&MyTemp);
to add the HTTP CGI handler to the web server.
0 notes
Text
Getting the Temperature
To get the temperature we have to transform the BASIC program to C. of course we write it new ;-)
We already have our temperature array tempvalues.h which we have to include.
#include "tempvalues.h"
Than we have to setup to variables. One for the temperature digits before the decimal point and one for the temperature digits after the decimal point. Why that? We have now floating point operation. So we have to store them separately.
int nMyTemperatur=20; int nMyTemperaturDecimal=0;
And now the code itself:
void gettemp() { int* DDRB=(int*) 56579; int* CRA=(int*) 56590; int* PRB=(int*)56577; int* SDR=(int*)56588; int* ICR=(int*) 56589; int* KEY=(int*)198; int nValue=0;// read value from SDR register int nTemp=0; int xPos=0; //First init all CIA registers *DDRB=255;//all lines are output lines *CRA=8+64;*CRA=8;//first clear SDR and then set it to input *PRB=0;*SDR=0;//empty buffer *ICR=127;//Set Interrupt flag // toggle eight times the clock line for eight bits
for (xPos=0;xPos<8;xPos++){ *PRB=0; *PRB=1; }
//Wait until interrupt is set while (*ICR!=0){} // getting the byte value from the CIA nValue=*SDR; // Getting the temperature from the array. nTemp=arrTemp[nValue];
//Calculate temperature *PRB=2; //reset TLC549 // calculate the digits before and after the decimal point and store it separately nMyTemperatur=nTemp/10; nMyTemperaturDecimal=abs(nTemp%10); }
Because we are using the math function abs and for debug output printf we need also to add
#include <stdlib.h> #include <stdio.h>
before we are able to compile.
If you compile and start it again you will get like this:

0 notes
Text
Our own web server
Now we have to extend our own web server.
First we need a new process to handle the TLC584 handling.
To add a new process we have to define it with the macro
PROCESS(get_temp_process,"get temperature process");
“get_temp_process” is the name of the function of the process. The second parameter is just a remark.
The function declaration looks like that:
void gettemp() { // comes later
}
PROCESS_THREAD(get_temp_process, ev, data) { static struct etimer timer; static int nCount=0; PROCESS_BEGIN(); log_message("Temperature process running ...", ""); etimer_set(&timer, 1*CLOCK_SECOND);
while(1) {
PROCESS_WAIT_EVENT(); if (ev == PROCESS_EVENT_TIMER) { gettemp(); etimer_reset(&timer); log_message("Timer 1 seconds...”,”“);
} }
PROCESS_END(); }
The thread creates a time which fires after one second. Then inside the while loop the thread wait for the timer signal and calls a “gettemp” function (which I explain later). To use the log_message method we have to add #include "sys/log.h" in the begining.
After that the timer is reset and the loop starts again.
But before the process could work, it must be started. This is done by the AUTOSTART_PROCESS macro.
AUTOSTART_PROCESSES(&webserver_nogui_process,&get_temp_process);
If you compile (make disk TARGET=c64) it and start it, I will look like this:

0 notes
Text
A Floating Problem
If you think:”Man that’s easy, just write the program in C and everything works!” than I have to disappointing you. The CC65 compiler don’t support floating point calculation. Of course you can try this in integer, good luck.
But there is a simpler solution. The TLC548 will deliver only 256 different values. So precalculate the values and put them into an array.
void main(){ int x; int y=0; printf("const int arrTemp[256]={"); for(x=0;x<255;x++){ float M=5.0-x/255.0*5.0; float RN=47000.0*M/(5.01-M); float T0=25+273.15; float H=3988.0+(T0*log(RN/10000.0)); float T=(T0*3988.0/H)-273.15; int t=T*10; printf("%d,",t); y++; if (y==8) { y=0; printf(" \\\n"); } }
printf("0};\n"); }
Save the file into printarray.c
Compile it with the gcc: gcc -o printarray.exe printarray.c
i
Start the program as followed:
printarray.exe >> tempvalues.h
The output looks like this
const int arrTemp[256]={-844,-742,-690,-654,-626,-603,-583,-566, \ -551,-537,-524,-513,-502,-492,-482,-473, \ -465,-456,-449,-441,-434,-427,-421,-414, \ -408,-402,-396,-390,-385,-379,-374,-369, \ -364,-359,-354,-350,-345,-341,-336,-332, \ -328,-323,-319,-315,-311,-307,-303,-299, \ -295,-292,-288,-284,-281,-277,-274,-270, \ -267,-263,-260,-256,-253,-250,-246,-243, \ -240,-237,-233,-230,-227,-224,-221,-218, \ -215,-212,-209,-206,-203,-200,-197,-194, \ -191,-188,-185,-182,-179,-176,-173,-171, \ -168,-165,-162,-159,-156,-154,-151,-148, \ -145,-142,-140,-137,-134,-131,-129,-126, \ -123,-120,-117,-115,-112,-109,-106,-104, \ -101,-98,-95,-93,-90,-87,-84,-82, \ -79,-76,-73,-71,-68,-65,-62,-59, \ -57,-54,-51,-48,-45,-42,-40,-37, \ -34,-31,-28,-25,-22,-19,-16,-14, \ -11,-8,-5,-2,0,3,6,9, \ 13,16,19,22,25,28,31,34, \ 38,41,44,47,51,54,57,61, \ 64,68,71,75,78,82,85,89, \ 92,96,100,104,107,111,115,119, \ 123,127,131,135,139,144,148,152, \ 157,161,165,170,175,179,184,189, \ 194,199,204,209,215,220,225,231, \ 237,243,248,255,261,267,274,280, \ 287,294,301,309,316,324,332,340, \ 349,358,367,377,387,397,408,419, \ 431,443,456,469,484,499,515,532, \ 551,571,592,616,641,670,702,738, \ 780,830,890,967,1070,1224,1518,0};
Each value represent the temperature in degree Celsius times 10. So 175 is 17,5°C.
0 notes
Text
Basic TLC548
To get the data from the TLC548 is very easy. We use the shift register of the CIA 2. If you take a look to the schematics you can see, that the DATA OUT pin of the TLC548 is connected to the shit register of CIA 2.
The I/O CLOCK pin is connected to CNT2 and PB0. That’s a very clever trick. Every time PB0 (which is the input/ouput port 0 of CIA 2) goes from 0 to 1, the TLC 548 will send the next bit of its 8-bit data value and the CIA 2 becomes the same signal of new data on CNT2 (counter of the shift register).
PB1 of CIA 2 is connected to the CS pin of TLC 548. If this signal is 0 the TLC 548 starts to work.
Because the clock signal is not strictly given by any other rules, we can use either BASIC or assembler to get the data from the TLC548.
In Basic it looks like this (Example from the book “Electronic projects for your Commodore 64 and 128″ by John Iovine with some extensions) :
1 REM SERIAL A/D FOR C-128 AND C-64 10 POKE 56579,255 15 POKE 56577,0: POKE 56590,64: POKE 56590,0 20 POKE 56589,127 25 FOR X = 0 TO 7 30 POKE 56577,0:POKE56577,1 35 NEXT X 40 IF (PEEK(56589) AND 8) = 0 THEN 40 45 X=PEEK(56588) 50 PRINT X; 55 POKE 56577,2 60 GOTO 25
(Rmeark: Compared to the original code, I added the commands POKE 56590,64: POKE 56590,0 in Line 15 (reset the shift register of CIA 2).
If you run this program you get this.

I warmed the NTC a little bit with my fingers. So first we get values about 217 and later it rises up to 220. But these are not temperatures in Celsius or Fahrenheit. These values have to be converted by a really complicated formula.
T(R) = T_N * B / (B + T_N * log(R / R_N))
so what does this mean? (remark: log is the natural log!)
R: resistor value of the NTC in Ohm T: temperature at R (our measured temperature in Kelvin!) T_N: nominal temperature for B (in Kelvin!) B: material constant of the NTC R_N: nominal resistor value of the NTC You can find the values for T_N, B and R_N in your data sheet of your NTC. I use a NTC B57703M from EPCOS with:
R_N=10000 Ohm T_N= 25 Celsius or 298.13 Kelvin B= 3988
OK, now we can calculate the temperature. But we didn’t measure R. So we have to find a formula for R.
We want to know the value of R2 in this diagram. Our TLC 548 measures voltage from 0V to 5V in 255 steps because we put REF- to 0V and REF+ to 5V. We know from school that in a resistor network like this R2/R1 = U2/U1. And we know U=U1+U2.
So we get R2/R1=(U-U1)/U1 or R2=(U-U1)/U1*R1.
So we know R2, because we know U (5V), we know R1 (4.7kOhm) and we know U1. U1=X*U/255 And X is our measure value from the TLC 548 which we get from the CIA.
The complete formula is a little bit confusing, but would like this:
T= T_N * B / (B + T_N * log( (U-U1)/U1*R1 / R_N))) or
T= T_N * B / (B + T_N * log( (255/X -1)*R1 / R_N))) or in our case
T=298.13*3988/(3988 + 298.13*(log( (255/x-1)*47000/10000)))
As you can imagine, that we will have to problems with this formula. If X = 0, than we have a “divide by 0″ error. And if X=255 than we try to get a value for ln(0) which is not defined.
But of course we can avoid this with some if statements in our basic code.
1 REM SERIAL A/D FOR C-128 AND C-64 5 T=0.0:Z=0.0:X=0: 10 POKE 56579,255 15 POKE 56577,0 : POKE 56590,64: POKE 56590,0 20 POKE 56589,127 25 FOR X = 0 TO 7 30 POKE 56577,0:POKE56577,1 35 NEXT X 40 IF (PEEK(56589) AND 8) = 0 THEN 40 45 X=PEEK(56588) 46 GOSUB 100 50 PRINT X;T: 55 POKE 56577,2 60 GOTO 25 100 Z=X 110 if X = 0 THEN Z=0.00001 115 IF X = 2555 THEN Z=254.9999 120 T=298.13*3988.0/(3988.0+298.13*(LOG((255.0/Z-1.0)*47000.0/10000.0)))-273.13 125 RETURN
If you run this program you get this:

Now you can see the value of the TLC 548 and the temperature in degree Celsius. Isn’t this great?
0 notes
Text
Dynamic web sites
Just a static web site is boring. So I decided to do something useful with the C64. Internet of Things (IoT) is one of the major buzzwords at the moment.
So why not to build a IoT devices with our C64 web server?
But first we have to decide what kind of dynamic data we want to provide. In this case we use the room temperature. But how do we measure temperature with a C64?
I found an old book from the 80s called “Electronic projects for your Commodore 64 and 128″ by John Iovine. It could be found as PDF here on archive.org.
To get the room temperature we use a NTC (Thermistor) and a simple analog to digital converter from Texas Instrument (TLC548).
The schematic looks like this:
The tricky part to connect all wires to the user port correctly. So be careful.
My setup looks like this:



So why this setup and why TLC548?
The easy answer: it’s very easy to read the digital 8-bit data serial from the TLC548 using the shift register of the CIA (6526). There is no complicated timing or protocol (like in I2C). In the next entry I will show you to read data from the TLC548 with BASIC!
0 notes
Text
First Live Test
To get your Contiki web server running on a real C64 is easy:
Get your empty SD card and copy the following files from D:\projects\contiki-2.5\examples\MyWebserver> to it:
(all file names must be lower cases!)
webserver-example.c64 as contiki cs8900a.eth as cs8900a.eth lan91c96.eth as lan91c96.eth
and from D:\projects\contiki-2.5\tools\c64>
sample.cfg as contiki.cfg
Plugin the rr-net (be careful which side is up!!!) and the sd2iec and start your C64:




0 notes
Text
Lets get real
Until now we only used the VICE to emulate the Commodore 64. but we want more, we want it real.
It ordered a RR-Net at Individual Computers . You get an RR-NET MK3 for about 65€.


As C64 main board I used first an old 250407 board. But I had trouble with the RR-Net on this board and I switched to an 250425. It should be better to use the newer boards like 250469. But I haven’t one so the 250425 must work ;-)

Of course: Before we build our breadbox version, we can use our normal C64 for the next steps. I use my C64 II Kickstarter special edition:

An at last I bought a SD2IEC mini at eBay.

But you can also buy a complete version:

1 note
·
View note
Text
Supported content types
In HTTP/HTML it is important that the content type ist set correctly in the HTTP answer of the web server.
At the moment our web server supports the following file types (you can find it in the http-strings definition):
http_content_type_plain "Content-type: text/plain\r\n\r\n" http_content_type_html "Content-type: text/html\r\n\r\n" http_content_type_css "Content-type: text/css\r\n\r\n" http_content_type_js "Content-type: application/javascript\r\n\r\n" http_content_type_text "Content-type: text/text\r\n\r\n" http_content_type_png "Content-type: image/png\r\n\r\n" http_content_type_gif "Content-type: image/gif\r\n\r\n" http_content_type_jpg "Content-type: image/jpeg\r\n\r\n" http_content_type_binary "Content-type: application/octet-stream\r\n\r\n" http_html ".html" http_shtml ".shtml" http_htm ".htm" http_css ".css" http_png ".png" http_gif ".gif" http_jpg ".jpg" http_text ".text" http_txt ".txt"
Unknown file types will be returned as http_content_type_plain, so as text/plain. That could be a problem if you want to use Javascript. But we will extent this later in the web server itself.
0 notes
Text
Build our own web server
Before we start to change so things, we should setup a own copy of the example web server (so we couldn’t destroy anything).
Please copy the folder D:\projects\contiki-2.5\examples\webserver to the new folder D:\projects\contiki-2.5\examples\MyWebserver. We will continue to develop our own web server in this folder.
Now copy the folder D:\projects\contiki-2.5\apps\webserver\httpd-fs to D:\projects\contiki-2.5\examples\MyWebserver\httpd-fs.
In this folder we can now change the website content. But how do we get these files into our web server binary?
The Contiki enviroment provides an easy way to do it. Inside the tools folder you can find the Perl script “makefsdata”. This command transforms ASCII files into C code.
For example:
We only have the file 404.html in our httpd-fs folder:
<html> <body bgcolor="white"> <center> <h1>404 - file not found</h1> <h3>Go <a href="/">here</a> instead.</h3> </center> </body> </html>
We start the makefsdata command inside our MyWebserver folder:
D:\projects\contiki-2.5\examples\MyWebserver>perl ..\..\tools\makefsdata -d httpd-fs
We get:
Processing directory httpd-fs as root of packed httpd-fs file system Writing to D:\projects\contiki-2.5\examples\MyWebserver\httpd-fsdata.c Adding /404.html All done, files occupy 171 bytes
And the new file httpd-fsdata.c in our folder:
/*********Generated by contiki/tools/makefsdata on 2017-07-19*********/
const char data_404_html[171] = { /* /404.html */ 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x00, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33, 0x3e, 0x47, 0x6f, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x68, 0x65, 0x72, 0x65, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, 0x61, 0x64, 0x2e, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x0a, 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x00};
/* Structure of linked list (all offsets relative to start of section): struct httpd_fsdata_file { const struct httpd_fsdata_file *next; //actual flash address of next link const char *name; //offset to coffee file name const char *data; //offset to coffee file data const int len; //length of file data #if HTTPD_FS_STATISTICS == 1 //not enabled since list is in PROGMEM u16_t count; //storage for file statistics #endif } */ const struct httpd_fsdata_file file_404_html[] ={{ NULL, data_404_html , data_404_html +10, sizeof(data_404_html) -10}};
#define HTTPD_FS_ROOT file_404_html #define HTTPD_FS_NUMFILES 1 #define HTTPD_FS_SIZE 171
So the ASCII file is now converted into C code.
make TARGET=c64 disk
Now the new web server knows only this file.
Of course you can add now any content you wish, even JPG or PNG. But there are some restrictions. See next entry :-)
0 notes
Text
Additional software needed: Welcome PERL
Before we go on, we need to install another software. PERL
So download PERL from http://strawberryperl.com/download/5.26.0.1/strawberry-perl-5.26.0.1-64bit.msi and installed it in D:\Strawberry\

(Remarks: you have to start you command shell again to get the correct PATH settings!)
0 notes