HTTPdynamic.c

HTTPdynamic.c example details
HTTP Server description

/***************************************************************************//**
@file HTTPdynamic.c
@brief Dynamic HTTP server example
@verbatim
_ _ _
__| | ___(_) ____ _ __ | |_
/ _` | / __| |/ _` | '_ \| __|
| (_| | _ \__ \ | (_| | | | | |_
\__,_|(_) ___/_|\__, |_| |_|\__|
Signalprocessing |___/ Technology
@endverbatim
@author D.SignT GmbH & Co. KG, Claus Hermbusche
@date 2019-06-03
@anchor HTTPDYNAMIC
@details
This program installs a HTTP server (port 80) with either fix IP 192.168.168.200
(configurable in netconfig.c) or DHCP assigned address (e.g. 192.168.168.143,
host name mydemo).
To verify this program, first 'ping' the DSP:
>ping 192.168.168.200
or, if configured for DHCP
>ping mydemo
If the settings and network connections are correct, the pings will be
replied.
To see the web page type in your browser:
>http://192.168.168.200/index.htm
or, if configured for DHCP
>http://mydemo/index.htm
All pages and messages are hard-coded via c-variables into the code, but
can also be loaded from internal flash.
@cond Software License Agreement
Copyright (C) 2001-2019 D.SignT GmbH & Co. KG - http://www.dsignt.de
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the
distribution.
Neither the name of D.SignT GmbH & Co. KG nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
Disclaimer
THIS SOFTWARE IS PROVIDED BY D.SIGNT GMBH & CO. KG "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL D.SIGNT GMBH & CO. KG BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@endcond
*******************************************************************************/
/*******************************************************************************
include stdtypes.h to avoid data type mismatch
*******************************************************************************/
/*******************************************************************************
include Runtime Source
*******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <inttypes.h>
#include <time.h>
#include <string.h>
/*******************************************************************************
network support functions
*******************************************************************************/
#include <Libs/NETlib/net.h> /* D.Module network support */
#include <Libs/NETlib/httplib.h> /* HTTP support */
/*******************************************************************************
board specific functions
*******************************************************************************/
#include <BoardSupport/inc/BoardSpecific.h> /* board support functions */
/*******************************************************************************
common support functions
*******************************************************************************/
#include <Common/Common.h> /* on exit function */
#include <Common/uartio.h> /* UART support */
#include <Common/timer.h> /* timer setting */
#include <Common/CPrintf.h> /* CPrintf defines */
/*******************************************************************************
network configuration
*******************************************************************************/
#include <BoardSupport/config/netconfig.c> /* network configuration */
#include ".\webpage\webpage.c" /* generated webpage */
#ifdef __cplusplus
extern "C" {
#endif /* !__cplusplus */
/*******************************************************************************
local prototypes
*******************************************************************************/
#pragma CODE_SECTION(UpdateLedStates , ".commontext");
void UpdateLedStates (void);
#pragma CODE_SECTION(toggle_led , ".commontext");
void toggle_led (direntry_type *fp, unsigned int led_nr);
#pragma CODE_SECTION(http_interpreter , ".commontext");
#ifdef __cplusplus
} // extern "C"
#endif
/*******************************************************************************
* *
* DEFINES *
* *
*******************************************************************************/
/*******************************************************************************
* *
* GLOBALS *
* *
*******************************************************************************/
/*******************************************************************************
program name
*******************************************************************************/
char *program_name = "dynamic HTTP server";
/*******************************************************************************
direntry_type: used for creating a directory entry:
direntry_type dir1 = { dir, file, length, access, type, flash/ram address };
The maximum dir and file length is 60 characters. Blanks are not allowed.
*******************************************************************************/
direntry_type led1 = {"led1" , "led1.gif" , sizeof(ledoff_gif) , FTP_RW | FTP_RAM, 'B', (uint32_t)ledoff_gif };
direntry_type led2 = {"led2" , "led2.gif" , sizeof(ledoff_gif) , FTP_RW | FTP_RAM, 'B', (uint32_t)ledoff_gif };
direntry_type led3 = {"led3" , "led3.gif" , sizeof(ledoff_gif) , FTP_RW | FTP_RAM, 'B', (uint32_t)ledoff_gif };
direntry_type led4 = {"led4" , "led4.gif" , sizeof(ledoff_gif) , FTP_RW | FTP_RAM, 'B', (uint32_t)ledoff_gif };
#include ".\webpage\webpage.gen" /* generated page list */
/*******************************************************************************
* *
* FUNCTIONS *
* *
*******************************************************************************/
/*******************************************************************************
@brief Update LED states
@return nothing
*******************************************************************************/
void UpdateLedStates (void)
{
/***************************************************************************
locals
***************************************************************************/
uint16_t led_mask = 1, i;
uint16_t leds = LED_state();
CPuts ("\r ");
for ( i=0; i<4; i++ )
{
fp = user[0].dir[led1.index+i];
if ( leds & led_mask )
{
/*******************************************************************
change file to ledon.gif
*******************************************************************/
fp-> offset = (uint32_t)ledon_gif;
fp-> size = sizeof(ledon_gif);
fp-> max_offset = (uint32_t)ledon_gif + fp->size;
" * "
}
else
{
/*******************************************************************
change file to ledoff.gif
*******************************************************************/
fp-> offset = (uint32_t)ledoff_gif;
fp-> size = sizeof(ledoff_gif);
fp-> max_offset = (uint32_t)ledoff_gif + fp-> size;
CPuts (" o ");
}
led_mask <<= 1;
}
}
/*******************************************************************************
@brief Toggle LED
@param fp - file-pointer
@param led_nr - number of led to toggle (0 -3)
@return nothing
*******************************************************************************/
void toggle_led (direntry_type *fp, unsigned int led_nr)
{
/***************************************************************************
locals
***************************************************************************/
uint16_t led_mask = 1 << led_nr;
uint16_t leds = LED_state();
(void)fp;
if ( leds & led_mask )
{
/***********************************************************************
switch LED off
***********************************************************************/
LED_off (led_nr);
}
else
{
/***********************************************************************
switch LED on
***********************************************************************/
LED_on (led_nr);
}
}
/*******************************************************************************
@brief user defined callback function; called each time a web page is
requested or data is received.
@param http_server - current http server connection
@return _HTTP_CLOSE_CONNECTION - close connection
@return _HTTP_KEEP_ALIVE - keep alive
@sa http_send_user_page() - http.lib
@sa http_send_uri() - http.lib
@sa toggle_led() - this file
*******************************************************************************/
{
/***************************************************************************
locals
***************************************************************************/
int i;
/***************************************************************************
Execute specific method
***************************************************************************/
switch (http_server-> method)
{
case _HTTP_GET:
/*******************************************************************
uri is the requested directory index
*******************************************************************/
if ( http_server-> uri == -1 )
{
/***************************************************************
uri not found: send user defined not-found-message
***************************************************************/
http_send_uri (http_server, &e404);
}
else
{
if ( http_server-> uri == index.index)
{
/***************************************************************
If the requested page is the index page, parse form arguments
and toggle leds.
The form command in index.htm cause a request in the form:
GET index.htm?Led1=1&Led2=1&Led3=1&Led4=1 HTTP 1.1 ....
The http_server argument list holds all form parameters
including the requested form:
http_server-> argc = 9;
http_server-> argv[0] = "index.htm";
http_server-> argv[1] = "Led1";
http_server-> argv[2] = "1";
http_server-> argv[3] = "Led2";
http_server-> argv[4] = "1";
.
.
.
***************************************************************/
for ( i = 1; i<http_server-> argc;i++)
{
if ( !strncmp (http_server-> argv[i], "Led1", 4) )
{
toggle_led (&led1, 0);
}
if ( !strncmp (http_server-> argv[i], "Led2", 4) )
{
toggle_led (&led2, 1);
}
if ( !strncmp (http_server-> argv[i], "Led3", 4) )
{
toggle_led (&led3, 2);
}
if ( !strncmp (http_server-> argv[i], "Led4", 4) )
{
toggle_led (&led4, 3);
}
}
/***********************************************************
update led-status
***********************************************************/
} // if
/***************************************************************
send the requested page
***************************************************************/
if ( http_send_user_page (http_server,
http_server-> uri ) <= INT32_C(0))
{
/***********************************************************
page could not be sent immediately, keep connection alive
and try again later
***********************************************************/
}
}
break;
case _HTTP_UNKNOWN : /* unknown method */
/*******************************************************************
method not implemented or syntax error
*******************************************************************/
http_send_uri (http_server, &e501);
break;
}
/***************************************************************************
back to http server
***************************************************************************/
return (ret);
}
/*******************************************************************************
@brief Main application
@param -
@return never
*******************************************************************************/
#pragma CODE_SECTION(main , ".commontext");
int main ( void )
{
/***************************************************************************
locals
***************************************************************************/
int main_loop = 1; /* main loop switch, set to 0 to exit */
volatile int32_t http_serv;
/***************************************************************************
initialize application (e.g. timer clocks, PLL settings, EMIF etc.)
(ref. \Common\Common.c)
***************************************************************************/
/***************************************************************************
select output device for CPrintf (ref. \Common\cprintf.c)
possible settings:
CPRINTF_UART_OUTPUT -> output to UART
CPRINTF_CCS_OUTPUT -> output to CCS
CPRINTF_UART_OUTPUT | CPRINTF_CCS_OUTPUT -> output to UART and CCS
***************************************************************************/
/***************************************************************************
print a start up message
***************************************************************************/
/**************************************************************************/
// CPrintfProgress (" Heap check ");
// at least 0x10000 bytes required for this app
/**************************************************************************/
// CPrintfProgressSuccess();
/**************************************************************************/
CPrintfProgress (" Setup system time ");
// 1 milli seconds resolution
/**************************************************************************/
CPrintf (" *** timer %d mapped to CPU int %d ***\r\n",
/**************************************************************************/
CPrintfProgress (" Enable interrupts ");
/**************************************************************************/
/**************************************************************************/
CPrintfProgress (" Start system timer ");
/**************************************************************************/
CPrintf (" *** timer %d running at %"PRId32" Hz ***\r\n", SystemTimerDev, RES_SECONDS/GetSystemTimerRes());
/**************************************************************************/
CPrintfProgress (" Initialize network ");
/**************************************************************************/
InitializeNetwork ( 64); // 64 bytes for ping
/***************************************************************************
initialize http server; parameter is the specified user list
***************************************************************************/
http_serv = http_server_init ( user, /* specified user list */
NULL, /* mmc not supported */
HTTP_NO_LIMIT); /* max parallel connections */
/* 0 == no limit (heap limit only) */
if ( http_serv == FALSE )
{
prg_exit ("http_server_init() failed"); /* possibly insufficient heap */
}
/***************************************************************************
add some dynamic pages
***************************************************************************/
http_add_page (&led1);
http_add_page (&led2);
http_add_page (&led3);
http_add_page (&led4);
/***************************************************************************
define user callback function
***************************************************************************/
/***************************************************************************
main program loop: set main_loop to 0 to exit loop
***************************************************************************/
while ( main_loop )
{
/***********************************************************************
try to detect IP assignment
if DHCP is used, the assigned IP address may change
***********************************************************************/
{
/*******************************************************************
print leds
*******************************************************************/
CPuts ("\r\n LED1 LED2 LED3 LED4");
CPuts ("\r\n o o o o");
}
/***********************************************************************
call net_isq() and http_server()
***********************************************************************/
net_isq ();
/***********************************************************************
monitor link status
***********************************************************************/
/***********************************************************************
show that the program is running, perform symbol animation
***********************************************************************/
}
/***************************************************************************
exit program, shut down peripherals
***************************************************************************/
return (0);
}