71 #define _WIN32_WINNT 0x8000
80 #include "security/oc_spake2plus.h"
82 #ifdef INCLUDE_EXTERNAL
85 #include "external_header.h"
92 static pthread_mutex_t mutex;
93 static pthread_cond_t cv;
94 static struct timespec ts;
100 #define MY_NAME "Actuator (LSAB) 417"
105 STATIC CONDITION_VARIABLE cv;
106 STATIC CRITICAL_SECTION cs;
108 #define GetCurrentDir _getcwd
111 #define GetCurrentDir getcwd
114 #define btoa(x) ((x) ? "true" : "false")
164 #define PASSWORD "LETTUCE"
165 oc_spake_set_password(PASSWORD);
166 PRINT(
" SPAKE password %s\n", PASSWORD);
195 bool error_state =
false;
198 PRINT(
"-- Begin get_dpa_417_61: interface %d\n", interfaces);
211 PRINT(
" Query param: %.*s", (
int)m_len, m);
215 if (device != NULL) {
219 if ((strncmp(m,
"id", m_len) == 0) | (strncmp(m,
"*", m_len) == 0)) {
221 snprintf(mystring, 99,
"urn:knx:sn:%s%s",
227 if ((strncmp(m,
"rt", m_len) == 0) | (strncmp(m,
"*", m_len) == 0)) {
231 if ((strncmp(m,
"if", m_len) == 0) | (strncmp(m,
"*", m_len) == 0)) {
234 if ((strncmp(m,
"dpt", m_len) == 0) | (strncmp(m,
"*", m_len) == 0)) {
238 if ((strncmp(m,
"ga", m_len) == 0) | (strncmp(m,
"*", m_len) == 0)) {
244 if (got_table_entry) {
271 if (error_state ==
false) {
276 PRINT(
"-- End get_dpa_417_61\n");
297 bool error_state =
false;
298 PRINT(
"-- Begin put_dpa_417_61:\n");
303 PRINT(
" S-MODE or /P\n");
306 while (rep != NULL) {
307 if (rep->
type == OC_REP_BOOL) {
308 if (rep->
iname == 1) {
309 PRINT(
" put_dpa_417_61 received : %d\n", rep->
value.boolean);
312 PRINT(
"-- End put_dpa_417_61\n");
320 PRINT(
"-- End put_dpa_417_61\n");
342 PRINT(
"Register Resource with local path \"/p/o_1_1\"\n");
343 PRINT(
"Light Switching actuator 417 (LSAB) : SwitchOnOff \n");
344 PRINT(
"Data point 417.61 (DPT_Switch) \n");
383 PRINT(
"factory_presets_cb: resetting device\n");
396 reset_cb(
size_t device_index,
int reset_value,
void *data)
401 PRINT(
"reset_cb %d\n", reset_value);
416 PRINT(
"-----restart_cb -------\n");
428 hostname_cb(
size_t device_index, oc_string_t host_name,
void *data)
437 send_delayed_response(
void *context)
441 if (response->active) {
444 PRINT(
"Delayed response sent\n");
446 PRINT(
"Delayed response NOT active\n");
466 size_t offset, uint8_t *payload,
size_t len,
void *data)
470 char filename[] =
"./downloaded.bin";
471 PRINT(
" swu_cb %s block=%d size=%d \n", filename, (
int)offset, (
int)len);
473 FILE *write_ptr = fopen(
"downloaded_bin",
"ab");
474 size_t r = fwrite(payload,
sizeof(*payload), len, write_ptr);
497 signal_event_loop(
void)
499 WakeConditionVariable(&cv);
509 signal_event_loop(
void)
511 pthread_mutex_lock(&mutex);
512 pthread_cond_signal(&cv);
513 pthread_mutex_unlock(&mutex);
537 PRINT(
"no arguments : starts the server\n");
538 PRINT(
"-help : this message\n");
539 PRINT(
"reset : does an full reset of the device\n");
554 oc_clock_time_t next_event;
555 char *fname =
"my_software_image";
559 InitializeCriticalSection(&cs);
560 InitializeConditionVariable(&cv);
567 sigfillset(&sa.sa_mask);
571 sigaction(SIGINT, &sa, NULL);
574 for (
int i = 0; i < argc; i++) {
575 PRINT(
"argv[%d] = %s\n", i, argv[i]);
578 if (strcmp(argv[1],
"reset") == 0) {
579 PRINT(
" internal reset\n");
582 if (strcmp(argv[1],
"-help") == 0) {
587 PRINT(
"KNX-IOT Server name : \"%s\"\n",
MY_NAME);
589 char buff[FILENAME_MAX];
591 retbuf = GetCurrentDir(buff, FILENAME_MAX);
592 if (retbuf != NULL) {
593 PRINT(
"Current working dir: %s\n", buff);
601 PRINT(
"\tstorage at './LSAB_minimal_creds' \n");
609 .signal_event_loop = signal_event_loop,
628 PRINT(
"oc_main_init failed %d, exiting.\n", init);
632 PRINT(
"OSCORE - Enabled\n");
634 PRINT(
"OSCORE - Disabled\n");
645 PRINT(
"Server \"%s\" running, waiting on incoming "
653 if (next_event == 0) {
654 SleepConditionVariableCS(&cv, &cs, INFINITE);
657 if (now < next_event) {
658 SleepConditionVariableCS(
659 &cv, &cs, (DWORD)((next_event - now) * 1000 / OC_CLOCK_SECOND));
669 pthread_mutex_lock(&mutex);
670 if (next_event == 0) {
671 pthread_cond_wait(&cv, &mutex);
673 ts.tv_sec = (next_event / OC_CLOCK_SECOND);
674 ts.tv_nsec = (next_event % OC_CLOCK_SECOND) * 1.e09 / OC_CLOCK_SECOND;
675 pthread_cond_timedwait(&cv, &mutex, &ts);
677 pthread_mutex_unlock(&mutex);
void oc_set_delayed_callback(void *cb_data, oc_trigger_t callback, uint16_t seconds)
Schedule a callback to be invoked after a set number of seconds.
bool oc_is_redirected_request(oc_request_t *request)
checks if the request is a redirected request from /k or /p when that happened, extra information can...
void oc_set_separate_response_buffer(oc_separate_response_t *handle)
Set a response buffer for holding the response payload.
void oc_resource_set_discoverable(oc_resource_t *resource, bool state)
Specify if a resource can be found using .well-known/core discover mechanisms.
void oc_init_query_iterator(void)
This resets the query iterator to the start of the URI query parameter.
oc_resource_t * oc_new_resource(const char *name, const char *uri, uint8_t num_resource_types, size_t device)
Allocate and populate a new oc_resource_t.
void oc_resource_bind_content_type(oc_resource_t *resource, oc_content_format_t content_type)
set the content type on the resource
void oc_resource_bind_dpt(oc_resource_t *resource, const char *dpt)
Add a Data Point Type "dpt" property to the resource.
void oc_send_response_no_format(oc_request_t *request, oc_status_t response_code)
Called after the response to a GET, PUT, POST or DELETE call has been prepared completed.
bool oc_add_resource(oc_resource_t *resource)
Add a resource to the stack.
int oc_iterate_query(oc_request_t *request, char **key, size_t *key_len, char **value, size_t *value_len)
Iterate through the URI query parameters and get each key=value pair.
void oc_send_cbor_response(oc_request_t *request, oc_status_t response_code)
Called after the response to a GET, PUT, POST or DELETE call has been prepared completed.
void oc_resource_bind_resource_type(oc_resource_t *resource, const char *type)
Add a Resource Type "rt" property to the resource.
void oc_send_separate_response(oc_separate_response_t *handle, oc_status_t response_code)
Called to send the deferred response to a GET, PUT, POST or DELETE request.
int oc_get_query_value(oc_request_t *request, const char *key, char **value)
Get a pointer to the start of the value in a URL query parameter key=value pair.
void oc_resource_set_periodic_observable(oc_resource_t *resource, uint16_t seconds)
The resource will periodically notify observing clients of is property values.
void oc_resource_bind_resource_interface(oc_resource_t *resource, oc_interface_mask_t iface_mask)
Add the supported interface(s) to the resource.
void oc_resource_set_request_handler(oc_resource_t *resource, oc_method_t method, oc_request_callback_t callback, void *user_data)
Specify a request_callback for GET, PUT, POST, and DELETE methods.
STATIC void put_o_1_1(oc_request_t *request, oc_interface_mask_t interfaces, void *user_data)
Put method for "p/o_1_1" resource.
int main(int argc, char *argv[])
main application.
void initialize_variables(void)
initializes the global variables registers and starts the handler
volatile int quit
stop variable, used by handle_signal
int app_init(void)
function to set up the device.
#define MY_NAME
The name of the application.
void swu_cb(size_t device, oc_separate_response_t *response, size_t binary_size, size_t offset, uint8_t *payload, size_t len, void *data)
software update callback
void reset_cb(size_t device_index, int reset_value, void *data)
application reset
bool g_mystate
the state of the dpa 417.61
STATIC void get_o_1_1(oc_request_t *request, oc_interface_mask_t interfaces, void *user_data)
get method for "p/o_1_1" resource.
bool g_reset
reset the device (from startup)
void factory_presets_cb(size_t device, void *data)
initiate preset for device current implementation: device reset as command line argument
void handle_signal(int signal)
handle Ctrl-C
void print_usage()
print usage and quits
void register_resources(void)
register all the resources to the stack this function registers all application level resources:
void restart_cb(size_t device_index, void *data)
restart the device (application depended)
void hostname_cb(size_t device_index, oc_string_t host_name, void *data)
set the host name on the device (application depended)
Main API of the stack for client and server.
int oc_add_device(const char *name, const char *version, const char *base, const char *serial_number, oc_add_device_cb_t add_device_cb, void *data)
Add an a device to the stack.
void oc_set_reset_cb(oc_reset_cb_t cb, void *data)
Set the reset callback.
void oc_set_restart_cb(oc_restart_cb_t cb, void *data)
Set the restart callback.
void oc_set_factory_presets_cb(oc_factory_presets_cb_t cb, void *data)
Set the factory presets callback.
void oc_main_shutdown(void)
Shutdown and free all stack related resources.
int oc_init_platform(const char *mfg_name, oc_init_platform_cb_t init_platform_cb, void *data)
Initialize the platform.
oc_clock_time_t oc_main_poll(void)
poll to process tasks
int oc_main_init(const oc_handler_t *handler)
Register and call handler functions responsible for controlling the stack.
void oc_set_hostname_cb(oc_hostname_cb_t cb, void *data)
Set the host name callback.
platform abstraction of a real time clock
oc_clock_time_t oc_clock_time(void)
Get the current clock time.
oc_endpoint_t * oc_connectivity_get_endpoints(size_t device)
retrieve list of endpoints for the device
KNX mandatory resources implementation.
int oc_core_set_device_fwv(size_t device_index, int major, int minor, int patch)
set the firmware version
int oc_core_set_device_hwt(size_t device_index, const char *hardware_type)
sets the hardware type (string) input string should not be larger than 6, note that if the input is l...
int oc_core_set_device_model(size_t device_index, const char *model)
sets the model (string)
int oc_core_set_device_mid(size_t device_index, uint32_t mid)
sets the manufacturer id
int oc_core_set_device_hwv(size_t device_index, int major, int minor, int patch)
sets the hardware version number
int oc_core_set_device_ap(size_t device_index, int major, int minor, int patch)
sets the application version number
oc_device_info_t * oc_core_get_device_info(size_t device)
retrieve the device info from the device index
#define oc_string_checked(ocstring)
cast oc_string to string, replace null pointer results with a pointer to "NULL"
#define oc_string(ocstring)
cast oc_string to string
knx /dev resource implementation
void oc_knx_device_storage_reset(size_t device_index, int reset_mode)
clear the persistent storage reset behavior according to the supplied erase code
knx /fp resource implementations
int oc_core_find_group_object_table_url(const char *url)
find (first) index in the group address table via url
oc_group_object_table_t * oc_core_get_group_object_table_entry(int index)
retrieve the group object table entry
void oc_set_swu_cb(oc_swu_cb_t cb, void *data)
Set the software update callback.
#define oc_rep_set_text_string(object, key, value)
Add an string value to the cbor object under the key name Example:
#define oc_rep_i_set_boolean(object, key, value)
Add an boolean value to the cbor object under the integer key name Example:
#define oc_rep_end_root_object()
End the root object.
#define oc_rep_begin_root_object()
Begin the root object.
#define oc_rep_i_set_text_string(object, key, value)
Add an string value to the cbor object under the integer key name Example:
int oc_rep_get_encoded_payload_size(void)
Get the size of the cbor encoded data.
#define oc_rep_set_int_array(object, key, values, length)
Add an integer array with values of length to the cbor object under the key name.
@ OC_STATUS_BAD_REQUEST
Bad Request 4.00.
@ OC_STATUS_CHANGED
Changed 2.04.
@ OC_STATUS_BAD_OPTION
Bad Option 4.02.
bool oc_check_accept_header(oc_request_t *request, oc_content_format_t accept)
checks if the accept header is correct note that if the accept header is not there,...
oc_event_callback_retval_t
callback return values
@ OC_EVENT_DONE
callback done, e.g.
@ APPLICATION_CBOR
application/cbor
int oc_status_code(oc_status_t key)
convert the (internal) status code to coap status as integer
oc_interface_mask_t
interface masks security access scopes defined as interfaces note that scope = 1 is not used.
struct oc_separate_response_s oc_separate_response_t
separate response type
int oc_storage_config(const char *store)
open the storage NOTE: For embedded devices, this function doesn't do anything.
oc_string_t serialnumber
knx serial number
Group Object Table Resource (/fp/g) The payload is an array of objects.
int ga_len
length of the array of ga identifiers
uint32_t * ga
array of group addresses (unsigned integers)
Call back handlers that are invoked in response to oc_main_init()
int(* init)(void)
Device initialization callback that is invoked to initialize the platform and device(s).
parsed entry of a cbor object This represents a link list of response values one can iterate over the...
oc_rep_value_type_t type
type of the data
union oc_rep_s::oc_rep_value value
the value as union
struct oc_rep_s * next
next in list
int iname
integer (identifier) as tag name
request information structure
oc_rep_t * request_payload
request payload structure
const oc_resource_t * resource
resource structure
size_t device
device index
oc_string_t dpt
dpt of the resource
oc_string_t uri
uri of the resource