KNX IoT
KNX IoT Point API stack implementation
lssb_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 
19 #ifndef DOXYGEN
20 // Force doxygen to document static inline
21 #define STATIC static
22 #endif
23 
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 "Sensor (LSSB) 421.61"
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;
128 void
129 oc_add_s_mode_response_cb(char *url, oc_rep_t *rep, oc_rep_t *rep_value)
130 {
131  (void)rep;
132  (void)rep_value;
133 
134  PRINT("oc_add_s_mode_response_cb %s\n", url);
135 }
136 
150 int
151 app_init(void)
152 {
153  int ret = oc_init_platform("Cascoda", NULL, NULL);
154 
155  /* set the application name, version, base url, device serial number */
156  ret |= oc_add_device(MY_NAME, "1.0.0", "//", "00FA10010401", NULL, NULL);
157 
159  PRINT("Serial Number: %s\n", oc_string_checked(device->serialnumber));
160 
161  /* set the hardware version 1.0.0 */
162  oc_core_set_device_hwv(0, 1, 0, 0);
163 
164  /* set the firmware version 1.0.0 */
165  oc_core_set_device_fwv(0, 1, 0, 0);
166 
167  /* set the hardware type*/
168  oc_core_set_device_hwt(0, "Pi");
169 
170  /* set the model */
171  oc_core_set_device_model(0, "my model");
172 
173  /* set the application info*/
174  oc_core_set_device_ap(0, 1, 0, 0);
175 
176  /* set the manufacturer info*/
177  oc_core_set_device_mid(0, 12);
178 
180 
181 #ifdef OC_SPAKE
182 #define PASSWORD "LETTUCE"
183  oc_spake_set_password(PASSWORD);
184  PRINT(" SPAKE password %s\n", PASSWORD);
185 #endif
186  return ret;
187 }
188 
201 STATIC void
203  void *user_data)
204 {
205  (void)user_data; /* variable not used */
206 
207  /* TODO: SENSOR add here the code to talk to the HW if one implements a
208  sensor. the call to the HW needs to fill in the global variable before it
209  returns to this function here. alternative is to have a callback from the
210  hardware that sets the global variables.
211  */
212  bool error_state = false; /* the error state, the generated code */
214 
215  PRINT("-- Begin get_dpa_421_61: interface %d\n", interfaces);
216  /* check if the accept header is CBOR */
217  if (oc_check_accept_header(request, APPLICATION_CBOR) == false) {
219  return;
220  }
221 
222  // check the query parameter m with the various values
223  char *m;
224  char *m_key;
225  size_t m_key_len;
226  size_t m_len = (int)oc_get_query_value(request, "m", &m);
227  if (m_len != -1) {
228  PRINT(" Query param: %.*s", (int)m_len, m);
230  size_t device_index = request->resource->device;
231  oc_device_info_t *device = oc_core_get_device_info(device_index);
232  if (device != NULL) {
234  while (oc_iterate_query(request, &m_key, &m_key_len, &m, &m_len) != -1) {
235  // unique identifier
236  if ((strncmp(m, "id", m_len) == 0) | (strncmp(m, "*", m_len) == 0)) {
237  char mystring[100];
238  snprintf(mystring, 99, "urn:knx:sn:%s%s",
239  oc_string(device->serialnumber),
240  oc_string(request->resource->uri));
241  oc_rep_i_set_text_string(root, 0, mystring);
242  }
243  // resource types
244  if ((strncmp(m, "rt", m_len) == 0) | (strncmp(m, "*", m_len) == 0)) {
245  oc_rep_set_text_string(root, rt, "urn:knx:dpa.421.6");
246  }
247  // interfaces
248  if ((strncmp(m, "if", m_len) == 0) | (strncmp(m, "*", m_len) == 0)) {
249  oc_rep_set_text_string(root, if, "if.s");
250  }
251  if ((strncmp(m, "dpt", m_len) == 0) | (strncmp(m, "*", m_len) == 0)) {
252  oc_rep_set_text_string(root, dpt, oc_string(request->resource->dpt));
253  }
254  // ga
255  if ((strncmp(m, "ga", m_len) == 0) | (strncmp(m, "*", m_len) == 0)) {
257  oc_string(request->resource->uri));
258  if (index > -1) {
259  oc_group_object_table_t *got_table_entry =
261  if (got_table_entry) {
262  oc_rep_set_int_array(root, ga, got_table_entry->ga,
263  got_table_entry->ga_len);
264  }
265  }
266  }
267  } /* query iterator */
269  } else {
270  /* device is NULL */
272  }
274  return;
275  }
276 
277  CborError error;
281  error = g_err;
282 
283  if (error) {
284  oc_status_code = true;
285  }
286  PRINT("CBOR encoder size %d\n", oc_rep_get_encoded_payload_size());
287 
288  if (error_state == false) {
290  } else {
292  }
293  PRINT("-- End get_dpa_421_61\n");
294 }
295 
312 void
314 {
315  PRINT("Register Resource with local path \"/p/o_1_1\"\n");
316  PRINT("Light Switching Sensor 421.61 (LSSB) : SwitchOnOff \n");
317  PRINT("Data point 61 (DPT_Switch) \n");
318  PRINT("Register Resource with local path \"/p/o_1_1\"\n");
319 
320  oc_resource_t *res_pushbutton =
321  oc_new_resource("push button", "/p/o_1_1", 2, 0);
322  oc_resource_bind_resource_type(res_pushbutton, "urn:knx:dpa.421.61");
323  oc_resource_bind_dpt(res_pushbutton, "urn:knx:dpt.Switch");
325  oc_resource_bind_resource_interface(res_pushbutton, OC_IF_S); /* if.s */
326  oc_resource_set_discoverable(res_pushbutton, true);
327  /* periodic observable
328  to be used when one wants to send an event per time slice
329  period is 1 second */
330  // oc_resource_set_periodic_observable(res_pushbutton, 1);
331  /* set observable
332  events are send when oc_notify_observers(oc_resource_t *resource) is
333  called. this function must be called when the value changes, preferable on
334  an interrupt when something is read from the hardware. */
335  /*oc_resource_set_observable(res_352, true); */
336  oc_resource_set_request_handler(res_pushbutton, OC_GET, get_o_1_1, NULL);
337  oc_add_resource(res_pushbutton);
338 }
339 
346 void
347 factory_presets_cb(size_t device_index, void *data)
348 {
349  (void)device_index;
350  (void)data;
351 
352  if (g_reset) {
353  PRINT("factory_presets_cb: resetting device\n");
355  }
356 }
357 
365 void
366 reset_cb(size_t device_index, int reset_value, void *data)
367 {
368  (void)device_index;
369 
370  PRINT("reset_cb %d\n", reset_value);
371 }
372 
379 void
380 restart_cb(size_t device_index, void *data)
381 {
382  (void)device_index;
383  (void)data;
384 
385  PRINT("-----restart_cb -------\n");
386  // exit(0);
387 }
388 
396 void
397 hostname_cb(size_t device_index, oc_string_t host_name, void *data)
398 {
399  (void)device_index;
400  (void)data;
401 
402  PRINT("-----host name ------- %s\n", oc_string_checked(host_name));
403 }
404 
406 send_delayed_response(void *context)
407 {
408  oc_separate_response_t *response = (oc_separate_response_t *)context;
409 
410  if (response->active) {
413  PRINT("Delayed response sent\n");
414  } else {
415  PRINT("Delayed response NOT active\n");
416  }
417 
418  return OC_EVENT_DONE;
419 }
420 
433 void
434 swu_cb(size_t device, oc_separate_response_t *response, size_t binary_size,
435  size_t offset, uint8_t *payload, size_t len, void *data)
436 {
437  (void)device;
438  (void)binary_size;
439  char filename[] = "./downloaded.bin";
440  PRINT(" swu_cb %s block=%d size=%d \n", filename, (int)offset, (int)len);
441 
442  FILE *write_ptr = fopen("downloaded_bin", "ab");
443  size_t r = fwrite(payload, sizeof(*payload), len, write_ptr);
444  fclose(write_ptr);
445 
446  oc_set_delayed_callback(response, &send_delayed_response, 0);
447 }
448 
453 void
455 {
456  /* initialize global variables for resources */
457  /* if wanted read them from persistent storage */
458 }
459 
463 static void
464 issue_requests_s_mode(void)
465 {
466  PRINT("issue_requests_s_mode: Demo \n\n");
467 
468  oc_do_s_mode_with_scope(2, "p/o_1_1", "w");
469  oc_do_s_mode_with_scope(5, "p/o_1_1", "w");
470 }
471 
472 #ifndef NO_MAIN
473 #ifdef WIN32
478 STATIC void
479 signal_event_loop(void)
480 {
481  WakeConditionVariable(&cv);
482 }
483 #endif /* WIN32 */
484 
485 #ifdef __linux__
490 STATIC void
491 signal_event_loop(void)
492 {
493  pthread_mutex_lock(&mutex);
494  pthread_cond_signal(&cv);
495  pthread_mutex_unlock(&mutex);
496 }
497 #endif /* __linux__ */
498 
503 void
504 handle_signal(int signal)
505 {
506  (void)signal;
507  signal_event_loop();
508  quit = 1;
509 }
510 
515 void
517 {
518  PRINT("Usage:\n");
519  PRINT("no arguments : starts the server\n");
520  PRINT("-help : this message\n");
521  PRINT("s-mode : starts the server and issue a s-mode message at start up "
522  "according the application/config\n");
523  PRINT("reset : does an full reset of the device\n");
524  exit(0);
525 }
526 
534 int
535 main(int argc, char *argv[])
536 {
537  int init;
538  oc_clock_time_t next_event;
539  bool do_send_s_mode = false;
540  char *fname = "my_software_image";
541 
542 #ifdef WIN32
543  /* windows specific */
544  InitializeCriticalSection(&cs);
545  InitializeConditionVariable(&cv);
546  /* install Ctrl-C */
547  signal(SIGINT, handle_signal);
548 #endif
549 #ifdef __linux__
550  /* Linux specific */
551  struct sigaction sa;
552  sigfillset(&sa.sa_mask);
553  sa.sa_flags = 0;
554  sa.sa_handler = handle_signal;
555  /* install Ctrl-C */
556  sigaction(SIGINT, &sa, NULL);
557 #endif
558 
559  for (int i = 0; i < argc; i++) {
560  PRINT("argv[%d] = %s\n", i, argv[i]);
561  }
562  if (argc > 1) {
563  PRINT("s-mode: %s\n", argv[1]);
564  if (strcmp(argv[1], "s-mode") == 0) {
565  do_send_s_mode = true;
566  }
567  if (strcmp(argv[1], "reset") == 0) {
568  PRINT(" internal reset\n");
569  g_reset = true;
570  }
571  if (strcmp(argv[1], "-help") == 0) {
572  print_usage();
573  }
574  }
575 
576  PRINT("KNX-IOT Server name : \"%s\"\n", MY_NAME);
577 
578  // show the current working folder
579  char buff[FILENAME_MAX];
580  char *retbuf = NULL;
581  retbuf = GetCurrentDir(buff, FILENAME_MAX);
582  if (retbuf != NULL) {
583  PRINT("Current working dir: %s\n", buff);
584  }
585 
586  /*
587  The storage folder depends on the build system
588  the folder is created in the makefile, with $target as name with _cred as
589  post fix.
590  */
591  PRINT("\tstorage at './LSSB_minimal_all_creds' \n");
592  oc_storage_config("./LSSB_minimal_all_creds");
593 
594  /*initialize the variables */
596 
597  /* initializes the handlers structure */
598  STATIC oc_handler_t handler = { .init = app_init,
599  .signal_event_loop = signal_event_loop,
600  .register_resources = register_resources,
601  .requests_entry = NULL };
602 
603  if (do_send_s_mode) {
604 
605  handler.requests_entry = issue_requests_s_mode;
606  }
607 
608  /* set the application callbacks */
610  oc_set_reset_cb(reset_cb, NULL);
613  oc_set_swu_cb(swu_cb, (void *)fname);
614 
615  /* start the stack */
616  init = oc_main_init(&handler);
617 
618  if (init < 0) {
619  PRINT("oc_main_init failed %d, exiting.\n", init);
620  return init;
621  }
622 
623 #ifdef OC_OSCORE
624  PRINT("OSCORE - Enabled\n");
625 #else
626  PRINT("OSCORE - Disabled\n");
627 #endif /* OC_OSCORE */
628 
630  PRINT("serial number: %s\n", oc_string_checked(device->serialnumber));
631 
633  if (my_ep != NULL) {
634  PRINTipaddr(*my_ep);
635  PRINT("\n");
636  }
637  PRINT("Server \"%s\" running, waiting on incoming "
638  "connections.\n",
639  MY_NAME);
640 
641 #ifdef WIN32
642  /* windows specific loop */
643  while (quit != 1) {
644  next_event = oc_main_poll();
645  if (next_event == 0) {
646  SleepConditionVariableCS(&cv, &cs, INFINITE);
647  } else {
648  oc_clock_time_t now = oc_clock_time();
649  if (now < next_event) {
650  SleepConditionVariableCS(
651  &cv, &cs, (DWORD)((next_event - now) * 1000 / OC_CLOCK_SECOND));
652  }
653  }
654  }
655 #endif
656 
657 #ifdef __linux__
658  /* Linux specific loop */
659  while (quit != 1) {
660  next_event = oc_main_poll();
661  pthread_mutex_lock(&mutex);
662  if (next_event == 0) {
663  pthread_cond_wait(&cv, &mutex);
664  } else {
665  ts.tv_sec = (next_event / OC_CLOCK_SECOND);
666  ts.tv_nsec = (next_event % OC_CLOCK_SECOND) * 1.e09 / OC_CLOCK_SECOND;
667  pthread_cond_timedwait(&cv, &mutex, &ts);
668  }
669  pthread_mutex_unlock(&mutex);
670  }
671 #endif
672 
673  /* shut down the stack */
674 
676  return 0;
677 }
678 #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.
void oc_do_s_mode_with_scope(int scope, const char *resource_url, char *rp)
sends (transmits) an s-mode message the value comes from the GET of the resource indicated by the res...
bool oc_set_s_mode_response_cb(oc_s_mode_response_cb_t my_func)
set the s-mode response callback e.g.
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_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.
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 421.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 oc_add_s_mode_response_cb(char *url, oc_rep_t *rep, oc_rep_t *rep_value)
s-mode response callback will be called when a response is received on an s-mode read request
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 factory_presets_cb(size_t device_index, void *data)
initiate preset for device current implementation: device reset as command line argument
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_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_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_S
if.s (256)
Definition: oc_ri.h:270
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
request information structure
Definition: oc_ri.h:412
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