KNX IoT
KNX IoT Point API stack implementation
lsab_minimal_all.c
Go to the documentation of this file.
1 /*
2 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3  Copyright (c) 2021-2022 Cascoda Ltd
4 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
5  Licensed under the Apache License, Version 2.0 (the "License");
6  you may not use this file except in compliance with the License.
7  You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11  Unless required by applicable law or agreed to in writing, software
12  distributed under the License is distributed on an "AS IS" BASIS,
13  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  See the License for the specific language governing permissions and
15  limitations under the License.
16 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
17 */
18 #ifndef DOXYGEN
19 // Force doxygen to document static inline
20 #define STATIC static
21 #endif
22 
71 #define _WIN32_WINNT 0x8000
72 #include "oc_api.h"
73 #include "oc_core_res.h"
74 #include "api/oc_knx_fp.h"
75 #include "port/oc_clock.h"
76 #include <signal.h>
77 // test purpose only
78 #include "api/oc_knx_dev.h"
79 #ifdef OC_SPAKE
80 #include "security/oc_spake2plus.h"
81 #endif
82 #ifdef INCLUDE_EXTERNAL
83 /* import external definitions from header file*/
84 /* this file should be externally supplied */
85 #include "external_header.h"
86 #endif
87 
88 #ifdef __linux__
90 #include <pthread.h>
91 #ifndef NO_MAIN
92 static pthread_mutex_t mutex;
93 static pthread_cond_t cv;
94 static struct timespec ts;
95 #endif /* NO_MAIN */
96 #endif
97 
98 #include <stdio.h> /* defines FILENAME_MAX */
99 
100 #define MY_NAME "Actuator (LSAB) 417"
102 #ifdef WIN32
104 #include <windows.h>
105 STATIC CONDITION_VARIABLE cv;
106 STATIC CRITICAL_SECTION cs;
107 #include <direct.h>
108 #define GetCurrentDir _getcwd
109 #else
110 #include <unistd.h>
111 #define GetCurrentDir getcwd
112 #endif
113 
114 #define btoa(x) ((x) ? "true" : "false")
115 
116 bool g_mystate = false;
117 volatile int quit = 0;
118 bool g_reset = false;
133 int
134 app_init(void)
135 {
136  /* set the manufacturer name */
137  int ret = oc_init_platform("Cascoda", NULL, NULL);
138 
139  /* set the application name, version, base url, device serial number */
140  ret |= oc_add_device(MY_NAME, "1.0.0", "//", "00FA10010701", NULL, NULL);
141 
143  PRINT("Serial Number: %s\n", oc_string_checked(device->serialnumber));
144 
145  /* set the hardware version 1.0.0 */
146  oc_core_set_device_hwv(0, 1, 0, 0);
147 
148  /* set the firmware version 1.0.0 */
149  oc_core_set_device_fwv(0, 1, 0, 0);
150 
151  /* set the hardware type*/
152  oc_core_set_device_hwt(0, "Pi");
153 
154  /* set the application info*/
155  oc_core_set_device_ap(0, 1, 0, 0);
156 
157  /* set the manufacturer info*/
158  oc_core_set_device_mid(0, 12);
159 
160  /* set the model */
161  oc_core_set_device_model(0, "Cascoda Actuator");
162 
163 #ifdef OC_SPAKE
164 #define PASSWORD "LETTUCE"
165  oc_spake_set_password(PASSWORD);
166  PRINT(" SPAKE password %s\n", PASSWORD);
167 #endif
168 
169  return ret;
170 }
171 
184 STATIC void
186  void *user_data)
187 {
188  (void)user_data; /* variable not used */
189 
190  /* TODO: SENSOR add here the code to talk to the HW if one implements a
191  sensor. the call to the HW needs to fill in the global variable before it
192  returns to this function here. alternative is to have a callback from the
193  hardware that sets the global variables.
194  */
195  bool error_state = false; /* the error state, the generated code */
197 
198  PRINT("-- Begin get_dpa_417_61: interface %d\n", interfaces);
199  /* check if the accept header is CBOR */
200  if (oc_check_accept_header(request, APPLICATION_CBOR) == false) {
202  return;
203  }
204 
205  // check the query parameter m with the various values
206  char *m;
207  char *m_key;
208  size_t m_key_len;
209  size_t m_len = (int)oc_get_query_value(request, "m", &m);
210  if (m_len != -1) {
211  PRINT(" Query param: %.*s", (int)m_len, m);
213  size_t device_index = request->resource->device;
214  oc_device_info_t *device = oc_core_get_device_info(device_index);
215  if (device != NULL) {
217  while (oc_iterate_query(request, &m_key, &m_key_len, &m, &m_len) != -1) {
218  // unique identifier
219  if ((strncmp(m, "id", m_len) == 0) | (strncmp(m, "*", m_len) == 0)) {
220  char mystring[100];
221  snprintf(mystring, 99, "urn:knx:sn:%s%s",
222  oc_string(device->serialnumber),
223  oc_string(request->resource->uri));
224  oc_rep_i_set_text_string(root, 0, mystring);
225  }
226  // resource types
227  if ((strncmp(m, "rt", m_len) == 0) | (strncmp(m, "*", m_len) == 0)) {
228  oc_rep_set_text_string(root, rt, "urn:knx:dpa.417.61");
229  }
230  // interfaces
231  if ((strncmp(m, "if", m_len) == 0) | (strncmp(m, "*", m_len) == 0)) {
232  oc_rep_set_text_string(root, if, "if.s");
233  }
234  if ((strncmp(m, "dpt", m_len) == 0) | (strncmp(m, "*", m_len) == 0)) {
235  oc_rep_set_text_string(root, dpt, oc_string(request->resource->dpt));
236  }
237  // ga
238  if ((strncmp(m, "ga", m_len) == 0) | (strncmp(m, "*", m_len) == 0)) {
240  oc_string(request->resource->uri));
241  if (index > -1) {
242  oc_group_object_table_t *got_table_entry =
244  if (got_table_entry) {
245  oc_rep_set_int_array(root, ga, got_table_entry->ga,
246  got_table_entry->ga_len);
247  }
248  }
249  }
250  } /* query iterator */
252  } else {
253  /* device is NULL */
255  }
257  return;
258  }
259 
260  CborError error;
264  error = g_err;
265 
266  if (error) {
267  oc_status_code = true;
268  }
269  PRINT("CBOR encoder size %d\n", oc_rep_get_encoded_payload_size());
270 
271  if (error_state == false) {
273  } else {
275  }
276  PRINT("-- End get_dpa_417_61\n");
277 }
278 
291 STATIC void
293  void *user_data)
294 {
295  (void)interfaces;
296  (void)user_data;
297  bool error_state = false;
298  PRINT("-- Begin put_dpa_417_61:\n");
299 
300  oc_rep_t *rep = NULL;
301  // handle the different requests
302  if (oc_is_redirected_request(request)) {
303  PRINT(" S-MODE or /P\n");
304  }
305  rep = request->request_payload;
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);
310  g_mystate = rep->value.boolean;
312  PRINT("-- End put_dpa_417_61\n");
313  return;
314  }
315  }
316  rep = rep->next;
317  }
318 
320  PRINT("-- End put_dpa_417_61\n");
321 }
322 
339 void
341 {
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");
345  oc_resource_t *res_light =
346  oc_new_resource("light actuation", "/p/o_1_1", 2, 0);
347  oc_resource_bind_resource_type(res_light, "urn:knx:dpa.417.61");
348  oc_resource_bind_dpt(res_light, "urn:knx:dpt.Switch");
350  oc_resource_bind_resource_interface(res_light, OC_IF_A); /* if.a */
351  oc_resource_set_discoverable(res_light, true);
352  /* periodic observable
353  to be used when one wants to send an event per time slice
354  period is 1 second */
356  /* set observable
357  events are send when oc_notify_observers(oc_resource_t *resource) is
358  called. this function must be called when the value changes, preferable on
359  an interrupt when something is read from the hardware. */
360  // oc_resource_set_observable(res_352, true);
361  // set the GET handler
363  // set the PUT handler
365  // register this resource,
366  // this means that the resource will be listed in /.well-known/core
367  oc_add_resource(res_light);
368 }
369 
376 void
377 factory_presets_cb(size_t device, void *data)
378 {
379  (void)device;
380  (void)data;
381 
382  if (g_reset) {
383  PRINT("factory_presets_cb: resetting device\n");
385  }
386 }
387 
395 void
396 reset_cb(size_t device_index, int reset_value, void *data)
397 {
398  (void)device_index;
399  (void)data;
400 
401  PRINT("reset_cb %d\n", reset_value);
402 }
403 
410 void
411 restart_cb(size_t device_index, void *data)
412 {
413  (void)device_index;
414  (void)data;
415 
416  PRINT("-----restart_cb -------\n");
417  // exit(0);
418 }
419 
427 void
428 hostname_cb(size_t device_index, oc_string_t host_name, void *data)
429 {
430  (void)device_index;
431  (void)data;
432 
433  PRINT("-----host name ------- %s\n", oc_string_checked(host_name));
434 }
435 
437 send_delayed_response(void *context)
438 {
439  oc_separate_response_t *response = (oc_separate_response_t *)context;
440 
441  if (response->active) {
444  PRINT("Delayed response sent\n");
445  } else {
446  PRINT("Delayed response NOT active\n");
447  }
448 
449  return OC_EVENT_DONE;
450 }
451 
464 void
465 swu_cb(size_t device, oc_separate_response_t *response, size_t binary_size,
466  size_t offset, uint8_t *payload, size_t len, void *data)
467 {
468  (void)device;
469  (void)binary_size;
470  char filename[] = "./downloaded.bin";
471  PRINT(" swu_cb %s block=%d size=%d \n", filename, (int)offset, (int)len);
472 
473  FILE *write_ptr = fopen("downloaded_bin", "ab");
474  size_t r = fwrite(payload, sizeof(*payload), len, write_ptr);
475  fclose(write_ptr);
476 
477  oc_set_delayed_callback(response, &send_delayed_response, 0);
478 }
479 
484 void
486 {
487  /* initialize global variables for resources */
488 }
489 
490 #ifndef NO_MAIN
491 #ifdef WIN32
496 STATIC void
497 signal_event_loop(void)
498 {
499  WakeConditionVariable(&cv);
500 }
501 #endif /* WIN32 */
502 
503 #ifdef __linux__
508 STATIC void
509 signal_event_loop(void)
510 {
511  pthread_mutex_lock(&mutex);
512  pthread_cond_signal(&cv);
513  pthread_mutex_unlock(&mutex);
514 }
515 #endif /* __linux__ */
516 
521 void
522 handle_signal(int signal)
523 {
524  (void)signal;
525  signal_event_loop();
526  quit = 1;
527 }
528 
533 void
535 {
536  PRINT("Usage:\n");
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");
540  exit(0);
541 }
542 
550 int
551 main(int argc, char *argv[])
552 {
553  int init;
554  oc_clock_time_t next_event;
555  char *fname = "my_software_image";
556 
557 #ifdef WIN32
558  /* windows specific */
559  InitializeCriticalSection(&cs);
560  InitializeConditionVariable(&cv);
561  /* install Ctrl-C */
562  signal(SIGINT, handle_signal);
563 #endif
564 #ifdef __linux__
565  /* Linux specific */
566  struct sigaction sa;
567  sigfillset(&sa.sa_mask);
568  sa.sa_flags = 0;
569  sa.sa_handler = handle_signal;
570  /* install Ctrl-C */
571  sigaction(SIGINT, &sa, NULL);
572 #endif
573 
574  for (int i = 0; i < argc; i++) {
575  PRINT("argv[%d] = %s\n", i, argv[i]);
576  }
577  if (argc > 1) {
578  if (strcmp(argv[1], "reset") == 0) {
579  PRINT(" internal reset\n");
580  g_reset = true;
581  }
582  if (strcmp(argv[1], "-help") == 0) {
583  print_usage();
584  }
585  }
586 
587  PRINT("KNX-IOT Server name : \"%s\"\n", MY_NAME);
588 
589  char buff[FILENAME_MAX];
590  char *retbuf = NULL;
591  retbuf = GetCurrentDir(buff, FILENAME_MAX);
592  if (retbuf != NULL) {
593  PRINT("Current working dir: %s\n", buff);
594  }
595 
596  /*
597  The storage folder depends on the build system
598  the folder is created in the makefile, with $target as name with _cred as
599  post fix.
600  */
601  PRINT("\tstorage at './LSAB_minimal_creds' \n");
602  oc_storage_config("./LSAB_minimal_creds");
603 
604  /*initialize the variables */
606 
607  /* initializes the handlers structure */
608  STATIC const oc_handler_t handler = { .init = app_init,
609  .signal_event_loop = signal_event_loop,
610  .register_resources = register_resources
611 #ifdef OC_CLIENT
612  ,
613  .requests_entry = 0
614 #endif
615  };
616 
617  /* set the application callbacks */
619  oc_set_reset_cb(reset_cb, NULL);
622  oc_set_swu_cb(swu_cb, (void *)fname);
623 
624  /* start the stack */
625  init = oc_main_init(&handler);
626 
627  if (init < 0) {
628  PRINT("oc_main_init failed %d, exiting.\n", init);
629  return init;
630  }
631 #ifdef OC_OSCORE
632  PRINT("OSCORE - Enabled\n");
633 #else
634  PRINT("OSCORE - Disabled\n");
635 #endif /* OC_OSCORE */
636 
638  PRINT("serial number: %s\n", oc_string_checked(device->serialnumber));
639 
641  if (my_ep != NULL) {
642  PRINTipaddr(*my_ep);
643  PRINT("\n");
644  }
645  PRINT("Server \"%s\" running, waiting on incoming "
646  "connections.\n",
647  MY_NAME);
648 
649 #ifdef WIN32
650  /* windows specific loop */
651  while (quit != 1) {
652  next_event = oc_main_poll();
653  if (next_event == 0) {
654  SleepConditionVariableCS(&cv, &cs, INFINITE);
655  } else {
656  oc_clock_time_t now = oc_clock_time();
657  if (now < next_event) {
658  SleepConditionVariableCS(
659  &cv, &cs, (DWORD)((next_event - now) * 1000 / OC_CLOCK_SECOND));
660  }
661  }
662  }
663 #endif
664 
665 #ifdef __linux__
666  /* Linux specific loop */
667  while (quit != 1) {
668  next_event = oc_main_poll();
669  pthread_mutex_lock(&mutex);
670  if (next_event == 0) {
671  pthread_cond_wait(&cv, &mutex);
672  } else {
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);
676  }
677  pthread_mutex_unlock(&mutex);
678  }
679 #endif
680 
681  /* shut down the stack */
682 
684  return 0;
685 }
686 #endif /* NO_MAIN */
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"
Definition: oc_helpers.h:56
#define oc_string(ocstring)
cast oc_string to string
Definition: oc_helpers.h:49
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:
Definition: oc_rep.h:401
#define oc_rep_i_set_boolean(object, key, value)
Add an boolean value to the cbor object under the integer key name Example:
Definition: oc_rep.h:378
#define oc_rep_end_root_object()
End the root object.
Definition: oc_rep.h:624
#define oc_rep_begin_root_object()
Begin the root object.
Definition: oc_rep.h:607
#define oc_rep_i_set_text_string(object, key, value)
Add an string value to the cbor object under the integer key name Example:
Definition: oc_rep.h:428
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.
Definition: oc_rep.h:1103
@ OC_STATUS_BAD_REQUEST
Bad Request 4.00.
Definition: oc_ri.h:158
@ OC_STATUS_OK
OK 2.00.
Definition: oc_ri.h:153
@ OC_STATUS_CHANGED
Changed 2.04.
Definition: oc_ri.h:155
@ OC_STATUS_BAD_OPTION
Bad Option 4.02.
Definition: oc_ri.h:160
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_PUT
PUT.
Definition: oc_ri.h:127
@ OC_GET
GET.
Definition: oc_ri.h:125
oc_event_callback_retval_t
callback return values
Definition: oc_ri.h:517
@ OC_EVENT_DONE
callback done, e.g.
Definition: oc_ri.h:518
@ APPLICATION_CBOR
application/cbor
Definition: oc_ri.h:207
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.
Definition: oc_ri.h:261
@ OC_IF_A
if.a (128)
Definition: oc_ri.h:269
struct oc_separate_response_s oc_separate_response_t
separate response type
Definition: oc_ri.h:238
int oc_storage_config(const char *store)
open the storage NOTE: For embedded devices, this function doesn't do anything.
device information
Definition: oc_core_res.h:158
oc_string_t serialnumber
knx serial number
Definition: oc_core_res.h:159
the endpoint information
Definition: oc_endpoint.h:78
Group Object Table Resource (/fp/g) The payload is an array of objects.
Definition: oc_knx_fp.h:119
int ga_len
length of the array of ga identifiers
Definition: oc_knx_fp.h:123
uint32_t * ga
array of group addresses (unsigned integers)
Definition: oc_knx_fp.h:124
Call back handlers that are invoked in response to oc_main_init()
Definition: oc_api.h:116
int(* init)(void)
Device initialization callback that is invoked to initialize the platform and device(s).
Definition: oc_api.h:141
parsed entry of a cbor object This represents a link list of response values one can iterate over the...
Definition: oc_rep.h:1642
oc_rep_value_type_t type
type of the data
Definition: oc_rep.h:1643
union oc_rep_s::oc_rep_value value
the value as union
struct oc_rep_s * next
next in list
Definition: oc_rep.h:1644
int iname
integer (identifier) as tag name
Definition: oc_rep.h:1646
request information structure
Definition: oc_ri.h:412
oc_rep_t * request_payload
request payload structure
Definition: oc_ri.h:419
const oc_resource_t * resource
resource structure
Definition: oc_ri.h:414
resource structure
Definition: oc_ri.h:482
size_t device
device index
Definition: oc_ri.h:484
oc_string_t dpt
dpt of the resource
Definition: oc_ri.h:488
oc_string_t uri
uri of the resource
Definition: oc_ri.h:486