Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added API to set Access to DD

Different kinds of GOAL extension modules can be divided:

  • libraries for communication profiles provided by port GmbH

  • more complex function blocks

Device Detection (DD)

The Device Detection represents a public interface to read and write CM-variables by other external components or remote devices. It is projected only for development and initial configuration purposes. During normal operation the Device Detection shall be disabled. The source code is located in the directory …\goal\protos\dd.
The Device Manager tool provides a graphical user interface to read and write CM-variables by a host computer using the Device Detection. This chapter describes a GOAL device used as counterpart to the Device Manager tool.
The Device Detection works according to the producer/consumer model, i.e. a DD-request of the DD-producer is received by one or more DD-consumers and each DD-consumer transmits a DD-response. Each DD-request must be answered by one or more DD-responses.

The data transfer between the DD-producer and DD-consumers is realized via a TCP/IP connection using the UDP protocol. All UDP datagrams are transmitted as broadcast packets to be independent on the IP configuration.

The data in the UDP datagram contains a DD-packet, which is coded according to the Device Detection protocol. The Device Detection protocol allows:

  • to build groups of devices via a DD-customer-ID,

  • to assign DD-requests and DD-responses to unique devices via the MAC address and

  • to assign DD-requests to DD-responses.

Each DD-consumer can be assigned to a group by a DD-customer-ID. The DD-packet involves the DD-customer-ID of the group, which shall receive the DD-packet. The DD-customer-ID allows a filtering of the received DD-packets. The DD-customer-ID can be configured about the CM-variable DD_CM_VAR_CUSTOMERID. On the local device the CM-variable DD_CM_VAR_CUSTOMERID can be set by function goal_ddCfgCustomerID().

The DD-customer-ID 0 disables the filtering of the received DD-packets. A DD-consumer with the DD-customer-ID 0 accepts all DD-packets. A DD-packet with the DD-customer-ID 0 is received from all DD-consumers.

A symbolic name can be assigned to each device usable for graphical user interfaces. The remote device can set the symbolic name by the CM-Variable DD_CM_VAR_MODULENAME. On the local device the CM-variable DD_CM_VAR_MODULENAME can be set by function goal_ddCfgModuleName().

GOAL initializes the Device Detection automatically in the state GOAL_FSA_INIT if the Device Detection is enabled by the compiler-define GOAL_DD.

Configuration

Compiler-defines

The following compiler-defines are available to configure the Device Detection:

  • GOAL_DD:

    • 0: Device Detection is disabled (default)

    • 1: Device Detection is enabled

CM-variables

The following CM-variables are available to configure the Device Detection:

Table: DD_CM_VAR_MODULENAME

CM-Module-ID

DD_CM_MOD_ID

CM-variable-ID

0

CM-variable name

DD_CM_VAR_MODULENAME

Description

name of the local device, usable by tools for symbolic names This CM-variable can be set by function goal_ddCfgModuleName().

CM data type

GOAL_CM_STRING

Size

20 bytes

Default value

from NVS or 0

Table: DD_CM_VAR_CUSTOMERID

CM-Module-ID

DD_CM_MOD_ID

CM-variable-ID

1

CM-variable name

DD_CM_VAR_CUSTOMERID

Description

DD-customer-ID of the local device This CM-variable can be set by function goal_ddCfgCustomerID().

CM data type

GOAL_CM_UINT32

Size

4 bytes

Default value

from NVS or 0

Implementation guide

Initial disabling of features by the application

With the call of goal_ddNew() from appl_setup() a bitmask can be passed with bits representing single functions of DD. Please refer to the API documentation of DD for possible values. If all bits are set, all features (hello, get, set, get_list, wink) are enabled.

The described mechanism can also be set before application start by setting the corrensponding CM variable FEATURE_DISABLE. Each request processed by the device detection module will utilize the value of this variable to determine, if the request is allowed to be processed.

Please note, that any call of goal_ddNew will overwrite the value of this variable, if a different initialization value is passed.

Temporary enable features of the device detection

This property is applied at an arbitraty time, for example when configured using a web site provided by the AC application.

Code Block
languagec
GOAL_STATUS_T goal_ddSessionFeatureActivate(
      GOAL_DD_T *pHdlDd,                          /*< dd handle */
      uint32_t bitmaskFeatures                    /*< bitmask with feature enable bits set */  
);  
  • The parameter bitmask contains bits representing features being enabled

  • Those bits overwrite the disable bits from CM for the current session

Filtering and access rights

This property is applied at starup of the AC application.

Using filters it is possible to limit access to CM variables by groups (module ids) and variables (variable ids). Currently some filters are predefined for usage. These can be enabled using following function:

Code Block
languagec
GOAL_STATUS_T goal_ddFilterAdd(
      GOAL_DD_T *pHdlDd,                          /*< dd handle */
      GOAL_DD_ACCESS_FILTER_SET_T setId           /*< set id */
);

This function works on a created instance of DD, thus requires passing of a valid DD handle. The setId can be used with following values:

Set Id

Description

GOAL_DD_ACCESS_FILTER_SET_ALL

Complete access to all variables

GOAL_DD_ACCESS_FILTER_SET_BASIC

Filter for minimal
function of the management tool

GOAL_DD_ACCESS_FILTER_SET_HIDDEN

Filter for hiding critial information

Configure the local device

The local device shall support the Device Detection, therewith the Device Manager tool can set and get CM-variables.

  1. GOAL initializes the Device Detection automatically in the state GOAL_FSA_INIT if the Device Detection is enabled by the compiler-define GOAL_DD.

  2. Set the DD-customer-ID to 1:

    Code Block
    languagec
    goal_ddCfgCustomerID(1);

  3. Set the device name:

    Code Block
    languagec
    uint8_t str[] = “myDev”;
    goal_ddCfgModuleName(str);
  4. Now the Device Manager tool can read and write CM-variables on the device “myDev”.

Command line interface (CLI)

GOAL provides a command line interface, which is used by GOAL core modules and other GOAL extension modules. The available commands for the command line interface are described in the appropriate chapters. But it is also possible to integrate a command line interface for the own application, see Chapter: Command structure. The source code of the GOAL command line interface is located in the directory …\goal\protos\cli.
The command line interface supports the auto-completion of commands and provides a command history. The size of the command history is configurable during compilation.
The data exchange about the command line interface is realized

  • via a UART connection

For further medias please contact port.
The command line interface provides an interface for debugging, see Chapter: Command line interface for debugging.

  • example:

    • …\goal\appl\00410_goal\cli*

Configuration


The following compiler-defines are available to configure the command line interface:

  • GOAL_CONFIG_CLI:

    • 0: command line interface is disabled (default)

    • 1: command line interface is enabled

  • GOAL_CONFIG_CLI_HISTORY:

    • 0: history of the command line interface is disabled (default)

    • 1: history of the command line interface is enabled

  • GOAL_CONFIG_CLI_HISTORY_SIZE:

    • number of history entries

  • GOAL_CONFIG_CLI_UART:

    • 0: command line interface is not connected via UART (default)

    • 1: command line interface is connected via UART

  • GOAL_CONFIG_CLI_DBG:

    • 0: debug interface of the command line interface is disabled (default)

    • 1: debug interface of the command line interface is enabled

Platform API

UART connection

Table: goal_tgtCharGet()

Prototype

GOAL_STATUS_T goal_tgtCharGet(char *pBuf)

Description

This indication function receives a single char from the UART connection.

Parameters

pBuf

buffer for a single received char from UART

Return values

GOAL return status, see Chapter: GOAL status

Category

mandatory for GOAL command line interface via UART

Condition

none


Table: goal_tgtCharPut()

Prototype

GOAL_STATUS_T goal_tgtCharPut(char c)

Description

This indication function transmits a single char via the UART connection.

Parameters

c

single char to send via UART

Return values

GOAL return status, see Chapter: GOAL status

Category

mandatory for GOAL command line interface via UART

Condition

none

Command structure


Each CLI command is composed of:

  • a main-command,

  • one or more sub-commands,

  • an action and

  • one or more optional parameters.

Main-command


port recommends to use "appl" as main-command for application-specific commands to separate these commands from the existing commands in the GOAL system.

Sub-command


The sub-command is any specific name.

Action


Table 12 provides an overview about binding action names for standard actions. Not all actions must be implemented by a specific command.

Table: command line standard action

Action

Description

add

adding a value to a set of values, e.g. an entry to a table

help

put out a help string for the main-/sub-command

set

set the value of a specified parameter

show

put out the value of a specified parameter

rem

removing a value from a set of values, e.g. remove an entry from a table

Parameters

Integer values

Integer values are currently only accepted with a base of 10 and may optionally contain a sign.
Example: The following command sets the port membership of port 1 to VLAN 1024:

Code Block
$ eth vlan port add 1 1024

Strings

Strings are started and ended with a "-character.
Example: The following command sets the value of config variable 0-1 to value "example"

Code Block
$ cm set 0 1 "example"

Port numbers

Ports are entered as integer values starting with 0 up to max. port number + 1. Max. port number +1 represents the management port. A 5 port switch provides ports 0 – 3 (external ports) and port 4 as management port.
Example: The following commands set the default VLAN tag for port 1 to 1024 with prio 7:

Code Block
languagec
$ eth vlan default set 1 1024 7

MAC addresses

MAC addresses are given in the format xx:xx:xx:xx:xx:xx where xx stands for a two char hex number.
Example: The following command adds port 3 to MAC address 00:11:22:33:44:55

Code Block
$ eth mactab mac add 00:11:22:33:44:55 3

IP addresses

IP addresses are given in the format xxx.xxx.xxx.xxx where xxx stands for a one- to three-digit decimal number.
Example: The following command sets the IP address, netmask and gateway for the TCP/IP stack:

Code Block
languagec
$ net ip set 192.168.1.133 255.255.255.0 0.0.0.0

Creating application-specific commands


The following steps are necessary to implement application-specific commands for the command line interface:

  1. Create commands, see Chapter: Command structure.

  2. Implement the initialization of the application-specific command line interface.

  3. Implement command handlers for main- and sub-commands.

  4. Register commands to the command line interface by function goal_cliCmdReg() and make the command handlers of the own commands known.

  5. The commands are processed loop-controlled in the state GOAL_FSA_OPERATION. It is possible to return a response by function goal_cliPrintf().


Chapter 7.2.6.1 shows an example.

Command line interface for debugging


The following commands are available for the debug interface:

Table: dbg memb show

Command

dbg memb show <address> [count]

Description

Shows the byte memory value (8 bit) at the given address. If count is given, up to count values will be shown starting at the given address.

Parameter


<address>

The memory address where the reading begins in hex format (0xXXXXXXXX).

[count]

Specifies the number of values to be read starting at the given memory address.


Table: dbg memw show

Command

dbg memw show <address> [count]

Description

Shows the word memory value (16 bit) at the given address. If count is given, up to count values will be shown starting at the given address.

Parameter


<address>

The memory address where the reading begins in hex format (0xXXXXXXXX).

[count]

Specifies the number of values to be read starting at the given memory address.


Table: dbg memd show

Command

dbg memd show <address> [count]

Description

Shows the double word memory value (32 bit) at the given address. If count is given, up to count values will be shown starting at the given address.

Parameter


<address>

The memory address where the reading begins in hex format (0xXXXXXXXX).

[count]

Specifies the number of values to be read starting at the given memory address.

Implementation guidelines


Create application-specific commands


This example assumes that the command line interface is implemented in an own C module, e.g. appl_cli.c.

  1. Digital outputs shall be set via the command line interface. The given value is bit-coded. Each bit relates to a specific DOUT channel. The relevance of the bits in the value can be managed by a bit mask. According to chapter 7.2.3 the command name is:

    Code Block
    languagec
    appl dout set <value> <mask> 

  2. Define the string variable in the source code:

    Code Block
    languagec
    const char strAppl[] = “appl”;      /* main-command */
    const char strApplDout[] = “dout”;  /* sub-command */
    const char strApplSet[] = “set”;    /* action */

  3. Implement the initialization function to register the commands and to make the handler applCmdHandler() for all commands known:

    Code Block
    languagec
    GOAL_STATUS_T applInitCli(void) {
        GOAL_STATUS_T res;              /* GOAL return value */
        GOAL_CLI_CMD_T *pApplCliHdl;    /* handle to main-command */
        GOAL_CLI_CMD_T *pApplCliSubHdl; /* handle to sub-commands */
    
        /* register main-command */
        res = goal_cliCmdReg(strAppl, NULL, applCmdHandler, NULL,
              pApplCliHdl);
              
        /* register sub-command */
        if (GOAL_RES_OK(res)) {
            res = goal_cliCmdReg(strApplDout, NULL, NULL, pApplCliHdl,
                  &pApplCliSubHdl);
        }
    
        /* register action */
        if (GOAL_RES_OK(res)) {
            res = goal_cliCmdReg(strApplSet, NULL, NULL, pApplCliSubHdl, 
                  NULL);
        }
        
        return res;
    }

  4. Implement the command handler applCmdHandler():

    Code Block
    languagec
      void applCmdHandler(
        GOAL_CLI_DATA_T *pData   /* [in] complete received command */
    )
    {
        GOAL_STATUS_T res;        /* GOAL return value */
        const char *pStr = NULL;  /* string argument from the received command */
        unsigned int len = 0;     /* length of the argument in byte(s) */
        uint8_t cmdFound = 0; /* flag to check the existence of the command */
    
        /* The main-command is already analyzed by the GOAL command line
            interface and this command handler was called. */
    
        /* eliminate sub-command from the received command */
        res = goal_cliParamGet(pData, 1, &pStr, &len);
        if (GOAL_RES_OK(res)) {
            /* check sub-command */
            if (strApplDout == pStr) {
                /* eliminate action */
                res = goal_cliParamGet(pData, 2, &pStr, &len);
                if (GOAL_RES_OK(res)) {
                    /* check support of action */
                    if (strApplSet == pStr) {
                        /* execute application-specific action */
                        applDoutSet();
                        cmdFound = 1;
                    }
                }
            }
        }
        /* print a response */
        if ((GOAL_RES_OK(res)) && (1 == cmdFound)) {
            goal_cliPrintf(“command executed\n”);
        }
        else {
            goal_cliPrintf(“unknown command\n”);
        }
        return res;
    }

  5. Implement the application-specific function applDoutSet() to handle the DOUTs.

  6. Register the initialization of the application-specific command line interface. The initialization shall be executed in stage GOAL_STAGE_CLI in state GOAL_FSA_INIT_GOAL.

    Code Block
    languagec
    GOAL_STAGE_HANDLER_T stageApplCli;
    
    goal_mainStageReg(GOAL_STAGE_CLI, &stageApplCli, GOAL_STAGE_INIT, applInitCli);

Web-server


GOAL provides a smart web-server for embedded systems. The web-server was designed:

  • for file downloads and

  • to get information about the current device state and properties.


The web-server supports the following properties:

transfer protocols:

  • HTTP

  • HTTPS

request methods:

  • GET

  • POST


One or more web-pages can be assigned to one instance of the web-server. The web-pages are part of the application and must be made available by the application. The web-server provides a callback function for this purpose, see cbHttpReqFunc() in Chapter: Callback functions.
The current device state and properties can be read from CM-variables and application-specific variables. The application-specific variables can be organized as simple variables or as a one-dimensional list.
It is possible to store templates for web-pages with placeholders for current values of application-specific variables. The text substitutions are described in Chapter: Web-templates. Web-templates make the dynamic management of web-pages possible.
The access to the web-server can be limited by user levels. The application can specify, which user levels shall be supported by the device and which rights the user levels shall have. The authentication data consisting of user name and the password for each user level are configurable by CM-variables. The GOAL web-server provides up to 4 user levels.
The user levels can be applied by all instances of the web-server. For each instance of the web-server the valid user level can be specified during registration. Web-requests are only transferred to the application after a successful authentication, i.e. the callback function cbHttpReqFunc() in Chapter: Callback functions. is only called after a successful login. The transfer of the user name and the password via a web-server instance using the HTTP transfer protocol is unsafe. port recommends using the HTTPS transfer protocol.
HTTPS is activated by the compiler-define GOAL_CONFIG_HTTPS. HTTPS uses the TLS media interface for encoding and authentication. This allows to use different TLS software, like Mbed TLS and WolfSSL, see Chapter: TLS. TLS for HTTPS is initialized and opened by function goal_httpsNew().
About the CM-variables for HTTPS it is possible to install a private key and an own X509-certificate for. If no own certificate is stored, the web-server takes a default certificate provided by port.


example:

  • …\goal\appl\goal_http\01_get*:

    • for upload of a web-page

  • …\goal\appl\goal_http\05_template_cm*:

    • for upload of a web-template with CM-variables and application-specific variables

  • …\goal\appl\goal_http\06_template_list*:

    • for upload of a web-template with lists

  • …\goal\appl\goal_http\04_auth*:

    • for authentication about user levels

  • …\goal\appl\goal_http\02_post*:

    • for file download

Configuration

Compiler-defines


The following compiler-defines are available to configure the webserver:

  • GOAL_CONFIG_HTTP:

    • 0: transfer protocol HTTP is not used (default)

    • 1: transfer protocol HTTP is used

  • GOAL_CONFIG_HTTPS:

    • 0: transfer protocol HTTPS is not used (default)

    • 1: transfer protocol HTTPS is used

CM-variables


The following CM-variables are available to configure the web-server:

Table: HTTPD_CM_VAR_HTTPD_CHANNELS_MAX

CM-Module-ID

GOAL_ID_HTTPD

CM-variable-ID

0

CM-variable name

HTTPD_CM_VAR_HTTPD_CHANNELS_MAX

Description

maximal number of connections available for the HTTP transfer protocol

CM data type

GOAL_CM_UINT16

Size

2 bytes

Default value

from NVS or 0


Table: HTTPD_CM_VAR_HTTPS_CHANNELS_MAX

CM-Module-ID

GOAL_ID_HTTPD

CM-variable-ID

1

CM-variable name

HTTPD_CM_VAR_HTTPS_CHANNELS_MAX

Description

maximal number of connections available for the HTTPS transfer protocol

CM data type

GOAL_CM_UINT16

Size

2 bytes

Default value

from NVS or 0


Table: HTTPD_CM_VAR_USERLEVEL0

CM-Module-ID

GOAL_ID_HTTPD

CM-variable-ID

2

CM-variable name

HTTPD_CM_VAR_USERLEVEL0

Description

authentication data for level 0

CM data type

GOAL_CM_STRING

Size

32 bytes

Default value

from NVS or an empty string

Table: HTTPD_CM_VAR_USERLEVEL1

CM-Module-ID

GOAL_ID_HTTPD

CM-variable-ID

3

CM-variable name

HTTPD_CM_VAR_USERLEVEL1

Description

authentication data for level 1

CM data type

GOAL_CM_STRING

Size

32 bytes

Default value

from NVS or an empty string

Table: HTTPD_CM_VAR_USERLEVEL2

CM-Module-ID

GOAL_ID_HTTPD

CM-variable-ID

4

CM-variable name

HTTPD_CM_VAR_USERLEVEL2

Description

authentication data for level 2

CM data type

GOAL_CM_STRING

Size

32 bytes

Default value

from NVS or an empty string

Table: HTTPD_CM_VAR_USERLEVEL3

CM-Module-ID

GOAL_ID_HTTPD

CM-variable-ID

5

CM-variable name

HTTPD_CM_VAR_USERLEVEL3

Description

authentication data for level 3

CM data type

GOAL_CM_STRING

Size

32 bytes

Default value

from NVS or an empty string

The following CM-variables allow to configure the TLS layer used by HTTPS:

Table: HTTPS_CM_VAR_TLS_SERVER_CERTIFICATE

CM-Module-ID

GOAL_ID_HTTPS

CM-variable-ID

0

CM-variable name

HTTPS_CM_VAR_TLS_SERVER_CERTIFICATE

Description

certificate of the web-server

CM data type

GOAL_CM_GENERIC

Size

1024 bytes

Default value

from NVS or certificate from port


Table: HTTPS_CM_VAR_TLS_PRIVATE_KEY

CM-Module-ID

GOAL_ID_HTTPS

CM-variable-ID

1

CM-variable name

HTTPS_CM_VAR_TLS_PRIVATE_KEY

Description

private key of the web-server

CM data type

GOAL_CM_GENERIC

Size

1024 bytes

Default value

from NVS or an empty entry


Table: HTTPS_CM_VAR_TLS_SRV_CERT_CA_CN

CM-Module-ID

GOAL_ID_HTTPS

CM-variable-ID

2

CM-variable name

HTTPS_CM_VAR_TLS_SRV_CERT_CA_CN

Description

common name of the server of the certification authority

CM data type

GOAL_CM_STRING

Size

128 bytes

Default value

from NVS or an empty string


Table: HTTPS_CM_VAR_TLS_SRV_CERT_CA_O

CM-Module-ID

GOAL_ID_HTTPS

CM-variable-ID

3

CM-variable name

HTTPS_CM_VAR_TLS_SRV_CERT_CA_O

Description

name of the certification authority organization, e.g. the company name

CM data type

GOAL_CM_STRING

Size

128 bytes

Default value

from NVS or an empty string


Table: HTTPS_CM_VAR_TLS_SRV_CERT_CA_C

CM-Module-ID

GOAL_ID_HTTPS

CM-variable-ID

4

CM-variable name

HTTPS_CM_VAR_TLS_SRV_CERT_CA_C

Description

country, in which the certification authority organization is located

CM data type

GOAL_CM_STRING

Size

8 bytes

Default value

from NVS or an empty string


Table: HTTPS_CM_VAR_TLS_SRV_CERT_CN

CM-Module-ID

GOAL_ID_HTTPS

CM-variable-ID

5

CM-variable name

HTTPS_CM_VAR_TLS_SRV_CERT_CN

Description

common name of the web-server

CM data type

GOAL_CM_STRING

Size

128 bytes

Default value

from NVS or an empty string


Table: HTTPS_CM_VAR_TLS_SRV_CERT_O

CM-Module-ID

GOAL_ID_HTTPS

CM-variable-ID

6

CM-variable name

HTTPS_CM_VAR_TLS_SRV_CERT_O

Description

name of the organization provided the web-server

CM data type

GOAL_CM_STRING

Size

128 bytes

Default value

from NVS or an empty string


Table: HTTPS_CM_VAR_TLS_SRV_CERT_C

CM-Module-ID

GOAL_ID_HTTPS

CM-variable-ID

7

CM-variable name

HTTPS_CM_VAR_TLS_SRV_CERT_C

Description

country, in which the organization provided the web-server is located

CM data type

GOAL_CM_STRING

Size

8 bytes

Default value

from NVS or an empty string


Table: HTTPS_CM_VAR_TLS_SRV_CERT_NOT_BEFORE

CM-Module-ID

GOAL_ID_HTTPS

CM-variable-ID

8

CM-variable name

HTTPS_CM_VAR_TLS_SRV_CERT_NOT_BEFORE

Description

from what date and time the certificate is valid

CM data type

GOAL_CM_STRING

Size

20 bytes

Default value

from NVS or an empty string


Table: HTTPS_CM_VAR_TLS_SRV_CERT_NOT_AFTER

CM-Module-ID

GOAL_ID_HTTPS

CM-variable-ID

9

CM-variable name

HTTPS_CM_VAR_TLS_SRV_CERT_NOT_AFTER

Description

from what date and time the certificate is invalid

CM data type

GOAL_CM_STRING

Size

20 bytes

Default value

from NVS or an empty string

Web-templates


The GOAL web-server allows to implement templates for web-pages with placeholders for current information. The placeholders are substituted by the current values by the web-server during the upload process. The web-server provides placeholders for

  • CM-variables,

  • application-specific variables and

  • lists.

CM-variables


The placeholder for CM-variables contains the CM-module-ID and the CM-variable-ID. The web-server executes the substitution of the placeholder by the CM-variable automatically.

  • syntax:

    • [CM:<modNum>, <cmVarNum>]

  • example:

    • [CM:0, 2]

Application-specific variables


The placeholder for application-specific variables contains the name of the variable in the application. The web-server requires the current value of the variable from the application by calling a callback function, see Chapter: Callback functions cbHttpTemplateFunc(), and substitutes the placeholder in the web-page.

  • syntax:

    • [VAR:<applVarName>]

  • example:

    • [VAR:applVar]

Lists


The web-server provides an effective method to generate lists in HTML text. The HTML text for a single list entry can be enclosed in the placeholders FOREACH and /FOREACH in the web-template. FOREACH marks a one-dimensional list and the HTML text between the placeholders FOREACH and /FOREACH is execute for each list element. The place for the list entry is marked in the HTML text by the placeholder VAR with the desired variable name. After the substitution of the placeholder VAR the web-server changes to the next list entry automatically, i.e. it is not possible to substitute the same list entry twice. Therewith it is only necessary to describe the first list entry in the web-template.
The web-server only gets the ID and the name of the list and the number of list elements during the registration. The content of the list elements is managed by the application. The web-server calls a callback function to get the content of the next list element, see Chapter: Callback functions cpHttpTemplateFunc().
Nested lists are allowed. The maximal supported nesting depth is 4.

  • syntax:

    • [FOREACH:<listName>] … [/FOREACH]

  • example for HTML listing:

    Code Block
    languagehtml
    <ul>
        [FOREACH:mainList]
        <li> main: [VAR:mainName] </li>
        <li> sub-lists:
            <ul>
                [FOREACH]
                <li> sub: [VAR:subName] </li>
                [/FOREACH]
            </ul>
        </li>
        [/FOREACH]
    </ul> 


Example …\goal\appl\goal_http\06_template_list* generates a HTML listing. The indication in the web-browser is shown:

Figure: web-page of example 06_template_list

The placeholder [FOREACH] … [\FOREACH] can also be integrated in other HTML formatting like tables.

Characters


square brackets: If the HTML text shall show square brackets, the square brackets must be written double, because placeholders in web-templates are bordered by square brackets.
example:

  • An array instruction shall be shown on a web-page.

    • HTML text: applArray[[5]]

    • Web-browser view: applArray[5]

double quotes: Double quotes in the HTML-text must be protected by a backslash, because strings in the C code are enclosed by double quotes.
example:

Code Block
languagehtml
uint8_t webPage[] = "<html><meta charset = \"utf-8\"> … </html>"; 


The rules for HTML text are valid for all other characters.

Callback functions

Table: cbHttpReqFunc()

Prototype

GOAL_STATUS_T cbHttpReqFunc(GOAL_HTTP_APPLCB_DATA_T *applData)

Description

The received and valid web-request is passed to the application. The application has to process the web-request and to produce a web-response.

Parameters

applData

contains data for the application and data returned by the application

Return values

GOAL return status, see Chapter: GOAL status

Category

optional

Registration

during runtime about function goal_httpdResReg()

Table: cbHttpReqFunc()

Prototype

GOAL_STATUS_T cbHttpTemplateFunc(GOAL_HTTP_APPLCB_TEMPL_T *pWebTemplate)

Description

About this callback function the application provides the current information for the specified placeholder. This callback function is called for each placeholder in the web-template. There are multiple placeholders for the same information, this callback function is called for each placeholder.

Parameters

pWebTemplate

Contains the information to specify a variable or list and the current return value of the specified variable.

Return values

GOAL return status, see Chapter: GOAL status

Category

optional

Registration

during runtime about function

Implementation guideline

Upload a web-page


The web-page "device.html" shall be uploaded from the device to the web-browser. The content of the web-page is stored in variable webPage[] as string. No text substitutions on the web-page are necessary.

  1. Initialize the web-server in state GOAL_FSA_INIT_APPL or GOAL_FSA_INIT_GOAL:

    Code Block
    languagec
    goal_httpInit();

  2. Open 1 instance of the web-server using the TCP port 8080 in state GOAL_FSA_INIT_SETUP:

    Code Block
    languagec
    GOAL_HTTP_T *pWebInstanceHdl; /* handle for the web-server instance */
    goal_httpNew(&pWebInstanceHdl, 8080, 1);

  3. Register the callback-functions and allowed methods for the opened web-server in state GOAL_FSA_INIT_SETUP: No callback function for text substitution is registered.

    Code Block
    languagec
    GOAL_HTTP_HDL_T webResourceHdl;
    goal_httpResReg(pWebInstanceHdl, (uint8_t *) „/device.html", 
    GOAL_HTTP_METHOD_ALLW_GET, applWebReqCb, NULL, &webResourceHdl);

  4. Provide the web-page as string variable:

    Code Block
    languagec
    const uint8_t webPage[] = "<html><head><meta charset = \"utf-8\">\
    <title> Device </title></head> \r\n{color}<body><h1>Device</h1> \r\n\
    <p>The device implementation bases on the GOAL middleware of port.
    </p> \r\n\
    </body></html>"

  5. Implement a callback function to process web-requests:

    Code Block
    languagec
    GOAL_STATUS_T applWebReqCb (GOAL_HTTP_APPLCB_DATA_T *pWebData) {
          GOAL_STATUS_T res;  /* GOAL return value */
          res = GOAL_ERROR;   /* no valid web-handle or
                               * request method not supported */
      
        if (webResourceHdl == pWebData->hdlRes) {
            if (GOAL_HTTP_FW_GET == pWebData->reqType) {
                GOAL_HTTP_GET_RETURN_HTML(pWebData, webPage,
                    GOAL_STRLEN((const char*) webPage));
                res = GOAL_OK;
            }
        }
        return res;
    } 

  6. The callback function applWebReqCb() is called by the web-server after the receipt of the web-request.

Read a CM-variable


The web-page "device.html" shall be uploaded from the device to the web-browser. The web-page bases on the template webPage[]. The template includes a placeholder for the CM-Variable DD_CM_VAR_MODULENAME with the CM-module-ID 34 and the CM-variable-ID 0. The web-server substitutes the placeholder by the current value of the CM-variable automatically. No text substitutions on the web-page are necessary.

  1. Initialize the web-server in state GOAL_FSA_INIT_APPL or GOAL_FSA_INIT_GOAL:

    Code Block
    languagec
    goal_httpInit();

  2. Open 1 instance of the web-server using the TCP port 8080 in state GOAL_FSA_INIT_SETUP:

    Code Block
    languagec
    GOAL_HTTP_T *pWebInstanceHdl; /* handle for the web-server instance */
    goal_httpNew(&pWebInstanceHdl, 8080, 1);

  3. Register the callback-functions and allowed methods for the opened web-server in state GOAL_FSA_INIT_SETUP: No callback function for text substitution is registered.

    Code Block
    languagec
    GOAL_HTTP_HDL_T webResourceHdl;
    
    goal_httpResReg(pWebInstanceHdl, (uint8_t *) „/device.html“, 
    GOAL_HTTP_METHOD_ALLW_GET, applWebReqCb, NULL, &webResourceHdl);

  4. Provide a template for the web-page as string variable with placeholder for the CM-variable:

    Code Block
    languagec
    const uint8_t webPage[] = “<html><head><meta charset = \”utf-8\”>\
    <title> Device </title></head> \r\n\
    <body><h1>Device</h1> \r\n\
    <p>The device with the name [CM:34, 0] bases on the GOAL middleware of port.</p> \r\n\
    </body></html>” 

  5. Implement a callback function to process web-requests:

    Code Block
    languagec
    GOAL_STATUS_T applWebReqCb (GOAL_HTTP_APPLCB_DATA_T *pWebData) {
        GOAL_STATUS_T res;  /* GOAL return value */
        res = GOAL_ERROR;   /* no valid web-handle or
                             * request method not supported */
      
        if (webResourceHdl == pWebData->hdlRes) {
            if (GOAL_HTTP_FW_GET == pWebData->reqType) {
                GOAL_HTTP_GET_RETURN_HTML(pWebData, webPage,
                  GOAL_STRLEN((const char*) webPage));
                res = GOAL_OK;
            }
        }
        return res;
    }

  6. The callback function applWebReqCb() is called by the web-server after the receipt of the web-request.

Read application-specific variable


The web-page "device.html" shall be uploaded from the device to the web-browser. The web-page bases on the template webPage[]. The template includes a placeholder for the application-specific Variable applVar. The web-server calls the callback function applWebGetValCb() to provide the current value of the application-specific variable for the web-server. The web-server substitutes the placeholder by the current value of the application-specific variable.

  1. Initialize the web-server in state GOAL_FSA_INIT_APPL or GOAL_FSA_INIT_GOAL:

    Code Block
    languagec
    goal_httpInit();

  2. Open 1 instance of the web-server using the TCP port 8080 in state GOAL_FSA_INIT_SETUP:

    Code Block
    languagec
    GOAL_HTTP_T *pWebInstanceHdl; /* handle for the web-server instance */
    goal_httpNew(&pWebInstanceHdl, 8080, 1); 

  3. Register the callback-functions and allowed methods for the opened web-server in state GOAL_FSA_INIT_SETUP:

    Code Block
    languagec
    GOAL_HTTP_HDL_T webResourceHdl;
    goal_httpResReg(pWebInstanceHdl, (uint8_t *) „/device.html“, 
    GOAL_HTTP_METHOD_ALLW_GET, applWebReqCb, applWebGetValCb, &webResourceHdl);

  4. Provide a template for the web-page as string variable with placeholder for the application-specific variable:

    Code Block
    languagec
    const uint8_t webPage[] = “<html><head><meta charset = \”utf-8\”>\
    <title> Device </title></head> \r\n\
    <body><h1>Device</h1> \r\n\
    <p>The device with the name [VAR:applVar] bases on the GOAL middleware of port.</p> \r\n\
    </body></html>” 

  5. Implement a callback function to process web-requests:

    Code Block
    languagec
    GOAL_STATUS_T applWebReqCb (GOAL_HTTP_APPLCB_DATA_T *pWebData) {
        GOAL_STATUS_T res;  /* GOAL return value */
        res = GOAL_ERROR;   /* no valid web-handle or
                             * request method not supported */
      
        if (webResourceHdl == pWebData->hdlRes) {
            if (GOAL_HTTP_FW_GET == pWebData->reqType) {
                GOAL_HTTP_GET_RETURN_HTML(pWebData, webPage,
                  GOAL_STRLEN((const char*) webPage));
                res = GOAL_OK;
            }
        }
        return res;
    }

  6. Implement a callback function to get the current value of the application-specific variable from the application:

    Code Block
    languagec
    uint8_t deviceName[] = “Sample Gadget”;
    GOAL_STATUS_T applWebGetValCb (GOAL_HTTP_APPLCB_TEMPL_T *pWebData) {
        if (0 == GOAL_MEMCMP(pWebData->in.name, “applVar”,
        GOAL_STRLEN(“applVar”))) {
      
            /* provide the complete device name */
            if (GOAL_STRLEN(deviceName) <= pWebData->in.retLenMax) {
                GOAL_MEMCPY(pWebData->out.strReturn, deviceName,
                  GOAL_STRLEN(deviceName));
            }
            /* the device name is too long, cut the device name down
            * to the maximal allowed length */
            else {
                GOAL_MEMCPY(pWebData->out.strReturn, deviceName,
                  pWebData->in.retLenMax);
            }
        }
      return GOAL_OK;
    }

  7. The callback function applWebReqCb() is called by the web-server after the receipt of the web-request. The desired template for the web-page is made available for the web-server.

  8. The callback function applWebGetValCb() is called for substitution.

Read a list


The web-page "device.html" shall be uploaded from the device to the web-browser. The web-page bases on the template webPage[]. The template includes a placeholder for the list of device components. The web-server calls the callback function applWebGetValCb() to provide the current value of the list entries. The web-server substitutes the placeholder by the current value of the application-specific variable.

  1. Initialize the web-server in state GOAL_FSA_INIT_APPL or GOAL_FSA_INIT_GOAL:

    Code Block
    languagec
    goal_httpInit();

  2. Open 1 instance of the web-server using the TCP port 8080 in state GOAL_FSA_INIT_SETUP:

    Code Block
    languagec
    GOAL_HTTP_T *pWebInstanceHdl; /* handle for the web-server instance */
    goal_httpNew(&pWebInstanceHdl, 8080, 1);

  3. Register the callback-functions and allowed methods for the opened web-server in state GOAL_FSA_INIT_SETUP:

    Code Block
    languagec
    GOAL_HTTP_HDL_T webResourceHdl;
    goal_httpResReg(pWebInstanceHdl, (uint8_t *) „/device.html“, 
    GOAL_HTTP_METHOD_ALLW_GET, applWebReqCb, applWebGetValCb, &webResourceHdl);

  4. Create the list information and register the list information for the web-server. The list information contains a list-ID, a list name and the number of list entries.

    Code Block
    languagec
    GOAL_HTTP_TEMPLATE_LIST_INIT_T webList;
    GOAL_MEMSET(&webList, 0, sizeof(webList));
    webList.listId = 1;
    webList.cntMemb = 4;
    GOAL_MEMCPY(webList.listName, “deviceComponents”,
      sizeof(“devcieComponents”));
    goal_httpTmpMgrNewList(pWebInstanceHdl, &webList);

  5. Provide a template for the web-page as string variable with placeholders for the list and list entries:

    Code Block
    languagec
    const uint8_t webPage[] = “<html><head><meta charset = \”utf-8\”>\
    <title> Device </title></head> \r\n\ 
    <body><h1>Device</h1> \r\n\
    <p> The device contains the following components: \r\n\
        <ul> \r\n\
            [FOREACH:deviceComponents] \r\n\
            <li> [VAR:devComponent] </li> \r\n\
            [/FOREACH]
        </ul> \r\n\
    </p> \r\n\
    </body></html>” 

  6. Implement a callback function to process web-requests:

    Code Block
    languagec
    GOAL_STATUS_T applWebReqCb (GOAL_HTTP_APPLCB_DATA_T *pWebData) {
        GOAL_STATUS_T res;  /* GOAL return value */
        res = GOAL_ERROR;   /* no valid web-handle or
                             * request method not supported */
    
        if (webResourceHdl == pWebData->hdlRes) {
            if (GOAL_HTTP_FW_GET == pWebData->reqType) {
                GOAL_HTTP_GET_RETURN_HTML(pWebData, webPage,
                  GOAL_STRLEN((const char*) webPage));
                res = GOAL_OK;
            }
        }
        return res;
    } 

  7. Implement a callback function to get the current value of the list entries from the application:

    Code Block
    languagec
    GOAL_STATUS_T applWebGetValCb (GOAL_HTTP_APPLCB_TEMPL_T *pWebData) {
        GOAL_STATUS_T res; /* GOAL return value */
        res = GOAL_ERR_NOT_FOUND;
    
        if (NULL != pWebData->in.pPath) {
            if (0 == GOAL_MEMCMP(pWebData->in.name, “deviceComponents”“devComponent”,
            GOAL_STRLEN(“deviceComponents”“devComponent”))) {
                      
                switch ((pWebData->inPath)->path[0].index) {
                    case 0:
                        GOAL_MEMCPY(pWebData->out.strReturn, “I/O module”,
                          GOAL_STRLEN(“I/O module”));
                        res = GOAL_OK;
                        break;
                    case 1:
                        GOAL_MEMCPY(pWebData->out.strReturn, “drive”,
                          GOAL_STRLEN(“drive”));
                        res = GOAL_OK;
                        break;
                    case 2:
                        GOAL_MEMCPY(pWebData->out.strReturn, “encoder”,
                          GOAL_STRLEN(“encoder”));
                        res = GOAL_OK;
                        break;
                    case 3:
                        GOAL_MEMCPY(pWebData->out.strReturn, “power supply”,
                          GOAL_STRLEN(“power supply”));
                        res = GOAL_OK;
                        break;
                    default:
                        break;
                }
            }
        }
        return res;
    }

  8. The callback function applWebReqCb() is called by the web-server after the receipt of the web-request. The desired template for the web-page is made available for the web-server.

  9. The callback function applWebGetValCb() is called for each substitution.

Set a user level


The upload of the web-page "admin.html" shall only allowed for users with the USERLEVEL0. The login data for the USERLEVEL0 are:

  • user name: admin

  • password: a1b2c3:UL

The HTTPS transfer protocol is used.
The web-page "admin.html" does not contain any placeholder. No text substitutions on the web-page are necessary.

  1. Initialize the web-server in state GOAL_FSA_INIT_APPL or GOAL_FSA_INIT_GOAL:

    Code Block
    languagec
    goal_httpInit(); 

  2. Open 1 instance of the web-server using the TCP port 443 in state GOAL_FSA_INIT_SETUP:

    Code Block
    languagec
    GOAL_HTTP_T *pWebInstanceHdl; /* handle for the web-server instance */
    goal_httpsNew(&pWebInstanceHdl, 443, 1); 

  3. Register the callback-functions and allowed methods for the opened web-server in state GOAL_FSA_INIT_SETUP:

    Code Block
    languagec
    GOAL_HTTP_HDL_T webResourceHdl;
    goal_httpResReg(pWebInstanceHdl, (uint8_t *) „/admin.html“, 
    GOAL_HTTP_METHOD_ALLW_GET | GOAL_HTTP_AUTH_USERLEVEL0, applWebReqCb, NULL, &webResourceHdl);

  4. Install the authentication for USERLEVEL0 in state GOAL_FSA_INIT_SETUP: The authentication data are written to the CM-variable USERLEVEL0.

    Code Block
    languagec
    goal_httpAuthBasSetUserInfo(pWebInstanceHdl, GOAL_HTTP_AUTH_USERLEVEL0,
        “admin”, “a1b2c3:UL”); 

  5. Provide a template for the web-page as string variable:

    Code Block
    languagec
    const uint8_t webPage[] = “<html><head><meta charset = \”utf-8\”>\
                              <title> Administration </title></head> \r\n\
                              <body><h1>Administration</h1> \r\n\
    <p> Internal information: … </p> \r\n\
    </body></html>”

  6. Implement a callback function to process web-requests:

    Code Block
    languagec
    GOAL_STATUS_T applWebReqCb (GOAL_HTTP_APPLCB_DATA_T *pWebData) {
        GOAL_STATUS_T res; /* GOAL return value */
        res = GOAL_ERROR; /* no valid web-handle or
                           * request method not supported */
    
        if (webResourceHdl == pWebData->hdlRes) {
            if (GOAL_HTTP_FW_GET == pWebData->reqType) {
                GOAL_HTTP_GET_RETURN_HTML(pWebData, webPage,
                    GOAL_STRLEN((const char*) webPage));
                res = GOAL_OK;
            }
        }   
        return res;
    } 

  7. The callback function applWebReqCb() is called by the web-server after the receipt web-request. The login for this web-server instance must be successful before.

Download files


The web-server provides a download dialog. The received file is transferred to the application.

  1. Initialize the web-server in state GOAL_FSA_INIT_APPL or GOAL_FSA_INIT_GOAL:

    Code Block
    languagec
    goal_httpInit();

  2. Open 1 instance of the web-server using the TCP port 8080 in state GOAL_FSA_INIT_SETUP:

    Code Block
    languagec
    GOAL_HTTP_T *pWebInstanceHdl; /* handle for the web-server instance */
    goal_httpNew(&pWebInstanceHdl, 8080, 1);

  3. Register the callback-functions and allowed methods for the opened web-server in state GOAL_FSA_INIT_SETUP:

    Code Block
    languagec
    GOAL_HTTP_HDL_T webResourceHdl;
    goal_httpResReg(pWebInstanceHdl, (uint8_t *) „/download.html“,
                    GOAL_HTTP_METHOD_ALLW_GET | GOAL_HTTP_METHOD_ALLW_POST,
                    applWebReqCb, NULL, &webResourceHdl); 

  4. Provide a web-page as string variable:

    Code Block
    languagec
    const uint8_t webPage[] = “<html><head><meta charset = \”utf-8\”>\
                              <title> Download dialog </title></head> \r\n\
                              <body><h1>Download dialog</h1> \r\n\
    <form method = \”post\” enctype = \”multipart/form-data\”> \r\n\
        <input type = \”file\” name = \”file\”> <br> \r\n\
        <input type = \”submit\” value = \”POST\”> \r\n
    </form> \r\n\
    </body></html>”

  5. Implement an application-specific function applDownload() to receive and install the new firmware.

  6. Implement an application-specific function applDownloadFinished() to report the result of the web-request to the application.

  7. Implement a callback function to process web-requests:

    Code Block
    languagec
    GOAL_STATUS_T applWebReqCb (GOAL_HTTP_APPLCB_DATA_T *pWebData) {
        GOAL_STATUS_T res;  /* GOAL return value */
        res = GOAL_ERROR;   /* no valid web-handle or
                             * request method not supported */
    
        if (webResourceHdl == pWebData->hdlRes) {
            switch (pWebData->reqType) {
                case GOAL_HTTP_FW_GET:
                    GOAL_HTTP_GET_RETURN_HTML(pWebData, webPage,
                        GOAL_STRLEN((const char*) webpage));
                    break;
                case GOAL_HTTP_FW_POST_START:
                    res = applDownload(pWebData);
                    GOAL_HTTP_RETURN_OK_204(pWebData);
                    break;
                case GOAL_HTTP_FW_POST_DATA:
                    res = applDownload(pWebData);
                    GOAL_HTTP_RETURN_OK_204(pWebData);
                    break;
                case GOAL_HTTP_FW_POST_END:
                    res = applDownload(pWebData);
                    GOAL_HTTP_RETURN_OK_204(pWebData);
                    break;
                case GOAL_HTTP_FW_REQ_DONE_OK:
                case GOAL_HTTP_FW_REQ_DONE_ERR:
                    res = applDownloadFinished(pWebData);
                    break;
                default:
                    break;
            }
        }
        return res;
    } 

Application Programming Interface

Initialization

goal_httpNewImpl()

Code Block
languagec
GOAL_STATUS_T goal_httpNewImpl ( GOAL_HTTP_T ∗∗ ppInst, uint16_t port, uint16_t cntChn )

Registers the http module for GOAL.

Return values:

GOAL_STATUS_T result

Parameters:

  • ppInst pointer to instance pointer

  • port port to link instance to

  • cntChn channel count

goal_httpResReg()

Code Block
GOAL_STATUS_T goal_httpResReg ( GOAL_HTTP_T ∗ pInst, 
    uint8_t ∗ strUrl, 
    uint32_t allowMeth, 
    GOAL_HTTP_REQCB_T pfnCbData, 
    GOAL_HTTP_TMPCB_T pfnCbTemplate, 
    GOAL_HTTP_HDL_T ∗ pHdl )

Parameters:

  • pInst instance pointer

  • strUrl URL string

  • allowMeth allowed methods for resource

  • pfnCbData application callback

  • pfnCbTemplate template handler callback

  • pHdl resource handle return

Firewall


GOAL provides a basic firewall for ARP, TCP and UDP. After calling goal_fwInit() the firewall is active and working. All frames received in goal_miEthRecv() matching ether type ARP and IPv4 will be passed to and processed by the firewall.

ARP-Firewall


All received Ethernet frames of ether type ARP will be filtered by goal_fwArp(). The firewall will process frames that match the following conditions:

  • EtherType = 0x0806 (Address Resolution Protocol)​

  • Data length must be equal or higher than 96 bytes​

  • ARP hardware type is Ethernet - 0x0001​

  • Opcode is request – 0x01​

  • Protocol type is IPv4 – 0x0800​

Frames that doesn't match these conditions will be passed to the queue. The ARP-firewall drops all frames that are not addressed to the device or have MAC-Address NULL. The firewall reads the IP, Gateway and Netmask settings at initialization and gets updated automatically at any change of these values.

IPv4-Firewall


All received Ethernet frames of ether type IPv4 will be filtered by goal_fwIpv4(). All frames of type ICMP will be passed directly to the queue. For TCP and UDP the firewall:

  • Checks frame length and drops malformed frames

  • Iterates through all channels to check for matching port number on used channels

  • Drops frames with no matching port number

The firewall reads the maximum number of net-channels and the location of the cannel list at initialization.

Table of Contents