-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
Files: cognit/include/cf_parser.h, cognit/src/cf_parser.c
- Uses
scheduling_t,ecf_response_t(declared incognit_frontend_cli.h) andfaas_t(frompb_parser.h).
- None exported.
-
JSON_ERR_CODE_OK— 0 — success -
JSON_ERR_CODE_INVALID_JSON— -1 — invalid JSON or error building JSON
void cfparser_parse_str_response_as_token(char* token, uint8_t* ui8_payload)Parameters: token (char*) — output buffer for token; ui8_payload (uint8_t*) — raw payload (string)
Return: void
Errors: none (caller must ensure output buffer capacity)
Effects: writes extracted token into token
References: cognit/include/cf_parser.h
int8_t cfparser_parse_requirements_as_str_json(scheduling_t* t_app_requirements, uint8_t* ui8_payload_buff, size_t* payload_len)Parameters: t_app_requirements (scheduling_t*) — requirements struct; ui8_payload_buff (uint8_t*) — out buffer for JSON string; payload_len (size_t*) — out length
Return: int8_t — 0 (JSON_ERR_CODE_OK) on success, -1 (JSON_ERR_CODE_INVALID_JSON) on error
Errors: returns JSON_ERR_CODE_INVALID_JSON for missing required fields or memory errors
Effects: uses cJSON to build JSON and writes into ui8_payload_buff
References: cognit/include/cf_parser.h and implementation in cognit/src/cf_parser.c
int8_t cfparser_parse_json_str_as_ecf_address(const char* json_str, ecf_response_t* pt_ecf_res)Parameters: json_str (const char*) — JSON response string; pt_ecf_res (ecf_response_t*) — output structure
Return: int8_t — 0 on success, -1 on error
Errors: returns JSON_ERR_CODE_INVALID_JSON if expected fields are missing or wrong type
References: cognit/include/cf_parser.h, cognit/src/cf_parser.c
int8_t faasparser_parse_fc_as_str_json(faas_t* pt_faas, uint8_t* ui8_payload_buff, size_t* payload_len)Parameters: pt_faas (faas_t*) — FaaS params; ui8_payload_buff (uint8_t*) — out JSON payload; payload_len (size_t*) — out length
Return: int8_t — 0 on success, -1 on error
Errors: returns JSON_ERR_CODE_INVALID_JSON on serialization/base64/hash failure
Effects: serializes FaaS protobuf with pb_parser, base64-encodes using cognit_encoding, and computes SHA-256 hash using cognit_encoding.
References: cognit/include/cf_parser.h, cognit/src/cf_parser.c
Files: cognit/include/cognit_frontend_cli.h, cognit/src/cognit_frontend_cli.c
-
geolocation_t- Fields:
latitude: float,longitude: float
- Fields:
-
scheduling_t- Fields:
device_id: char *— device identifierflavour: char[NAME_MAX_LEN]— flavour stringmax_latency: int— maximum acceptable latencymax_function_execution_time: float— max function exec timemin_renewable: int— minimal renewable usagegeolocation: geolocation_tprovider: char *confidential_computing: bool
- Fields:
-
ecf_response_t(SEdgeClusterFrontendResponse)- Fields:
id: int,name: char[NAME_MAX_LEN],hosts, datastores, vnets: int[],template: char[MAX_URL_LENGTH]
- Fields:
-
cognit_frontend_cli_t- Fields:
m_t_config: cognit_config_t*,ecf_resp: ecf_response_t,has_connection: bool
- Fields:
- None exported.
-
CF_AUTH_ENDPOINT,CF_REQ_ENDPOINT,CF_ECF_ADDRESS_ENDPOINT,FUNC_UPLOAD_ENDPOINT— endpoint path constants -
MAX_TOKEN_LENGTH,MAX_URL_LENGTH,NAME_MAX_LEN, etc.
int cognit_frontend_cli_init(cognit_frontend_cli_t* pt_cognit_frontend_cli, cognit_config_t* pt_cognit_config)Parameters: pt_cognit_frontend_cli (cognit_frontend_cli_t*) — client to initialize; pt_cognit_config (cognit_config_t*) — config (stored as pointer inside client)
Return: int — 0 on success, -1 on error
Errors: returns -1 if any pointer is NULL
Effects: zeroes the client struct, sets has_connection=false, and stores pt_cognit_config pointer
References: cognit/include/cognit_frontend_cli.h, cognit/src/cognit_frontend_cli.c
int cognit_frontend_cli_authenticate(cognit_frontend_cli_t* pt_cognit_frontend_cli, char* token)Parameters: pt_cognit_frontend_cli (cognit_frontend_cli_t*); token (char*) — output token buffer
Return: int — 0 on success, -1 on error
Effects: POST ${cognit_frontend_endpoint}/v1/authenticate using basic auth (cognit_frontend_usr/pwd), expects HTTP 200/201, parses token from response into token, sets has_connection accordingly
References: cognit/include/cognit_frontend_cli.h, cognit/src/cognit_frontend_cli.c
int cognit_frontend_cli_update_requirements(cognit_frontend_cli_t* pt_cognit_frontend_cli, char* biscuit_token, scheduling_t t_app_reqs, int* pt_app_req_id)Parameters: client; biscuit_token (char*); t_app_reqs (scheduling_t); pt_app_req_id (int*) — output app requirement id
Return: int — 0 on success, -1 on error
Effects: builds requirements JSON (cfparser_parse_requirements_as_str_json) and POSTs to ${endpoint}/v1/app_requirements with token; expects HTTP 200/201; parses response body as integer (atoi) into *pt_app_req_id; sets has_connection accordingly
References: cognit/include/cognit_frontend_cli.h, cognit/src/cognit_frontend_cli.c
int cognit_frontend_cli_get_ecf_address(cognit_frontend_cli_t* pt_cognit_frontend_cli, char* biscuit_token, int app_req_id)Parameters: client; biscuit_token (char*); app_req_id (int)
Return: int — 0 on success, -1 on error
Effects: GET ${endpoint}/v1/app_requirements/<app_req_id>/ec_fe with token; expects HTTP 200/201; parses JSON into pt_cognit_frontend_cli->ecf_resp (cfparser_parse_json_str_as_ecf_address); sets has_connection accordingly
References: cognit/include/cognit_frontend_cli.h, cognit/src/cognit_frontend_cli.c
int cognit_frontend_cli_delete(cognit_frontend_cli_t* pt_cognit_frontend_cli, char* biscuit_token, int app_req_id)Parameters: client; biscuit_token (char*); app_req_id (int)
Return: int — 0 on success, -1 on error
Effects: DELETE ${endpoint}/v1/app_requirements/<app_req_id> with token; expects HTTP 204; sets has_connection accordingly
References: cognit/include/cognit_frontend_cli.h, cognit/src/cognit_frontend_cli.c
int cfc_cli_upload_function_to_daas(cognit_frontend_cli_t* pt_cfc_cli, char* biscuit_token, faas_t* pt_faas)Parameters: client; biscuit_token (char*); pt_faas (faas_t*)
Return: int — fc_id on success (>0), 0 on error
Effects: serializes FC to JSON (faasparser_parse_fc_as_str_json) and POSTs to ${endpoint}/v1/daas/upload; expects HTTP 200 and a numeric response body; parses fc_id = atoi(response). Note: current implementation sets has_connection=false even on successful upload.
References: cognit/include/cognit_frontend_cli.h, cognit/src/cognit_frontend_cli.c
void cfc_set_has_connection(cognit_frontend_cli_t* pt_cognit_frontend_cli, bool value)Parameters: client, value (bool)
Return: void
Effects: sets pt_cognit_frontend_cli->has_connection = value (no NULL check)
References: cognit/include/cognit_frontend_cli.h, cognit/src/cognit_frontend_cli.c
bool cfc_get_has_connection(cognit_frontend_cli_t* pt_cognit_frontend_cli)Parameters: client
Return: bool — current has_connection (no NULL check)
References: cognit/include/cognit_frontend_cli.h, cognit/src/cognit_frontend_cli.c
Files: cognit/include/cognit_encoding.h, cognit/src/cognit_encoding.c
- None exported.
- None exported.
int cognit_base64_encode(unsigned char str_b64_buff[], size_t buff_len, size_t *base64_len, char str[], int str_len)Parameters: str_b64_buff — output buffer; buff_len — buffer capacity; base64_len — out length; str — input bytes; str_len — input length
Return: int — 0 on success, non-zero on error
Errors: delegates to platform callback; non-zero indicates encode error
Effects: writes base64 output to str_b64_buff
References: cognit/include/cognit_encoding.h, cognit/src/cognit_encoding.c
int cognit_base64_decode(unsigned char decoded_buff[], size_t buff_size, size_t* decoded_len, const unsigned char* str, size_t str_len)Parameters: output buffer, buffer size, out length, input base64 string and length
Return: int — 0 on success, non-zero on error
References: cognit/include/cognit_encoding.h
int cognit_hash(const unsigned char* str, size_t str_len, unsigned char hash[])Parameters: input bytes, input length, output hash buffer
Return: int — 0 on success, non-zero on error
Notes: Implementation delegates to an external hash callback (platform-provided)
References: cognit/include/cognit_encoding.h
Files: cognit/include/cognit_http.h, cognit/src/cognit_http.c
-
http_response_t- Fields:
ui8_response_data_buffer: uint8_t[MAX_HTTP_RESPONSE_SIZE],size: size_t,l_http_code: long
- Fields:
-
http_config_t- Fields:
t_http_response: http_response_t,c_url: const char*,c_method: const char*,ui32_timeout_ms: uint32_t,c_username: const char*,c_password: const char*,c_token: const char*,binary: bool
- Fields:
-
send_http_req_cb_t— callback type:int (*)(const char*, size_t, http_config_t*)
-
STR_PROTOCOL— "https" -
HTTP_METHOD_GET,HTTP_METHOD_POST, etc. -
MAX_HTTP_RESPONSE_SIZE,MAX_HTTP_TRANSMISSION_SIZE
int8_t cognit_http_send(const char* c_buffer, size_t size, http_config_t* config)Parameters: c_buffer (const char*) — payload; size (size_t) — length; config (http_config_t*) — request configuration and response container
Return: int8_t — 0 on success, -1 on failure
Errors: returns non-zero for transport/HTTP errors
Effects: fills config->t_http_response with response data
Notes: Actual transport is delegated to a platform callback (my_http_send_req_cb) implemented by the integrator
References: cognit/include/cognit_http.h, cognit/src/cognit_http.c
Files: cognit/include/device_runtime.h, cognit/src/device_runtime.c
-
device_runtime_t- Fields:
m_t_config: cognit_config_t— runtime configurationm_t_device_runtime_sm: device_runtime_sm_t— internal state machine
- Fields:
-
e_status_code_t-
E_ST_CODE_SUCCESS = 0— success -
E_ST_CODE_ERROR = -1— generic error
-
-
FAAS_MAX_SEND_PAYLOD_SIZE— 16384 (16KB)
e_status_code_t device_runtime_init(device_runtime_t* pt_dr, cognit_config_t t_config, scheduling_t t_reqs, faas_t* pt_faas)Parameters: pt_dr (device_runtime_t*) — runtime instance; t_config (cognit_config_t) — configuration (copied by value into pt_dr->m_t_config); t_reqs (scheduling_t) — initial requirements; pt_faas (faas_t*)
Return: e_status_code_t — returns the value returned by dr_state_machine_init (current code stores it in an int and returns it)
Errors: returns E_ST_CODE_ERROR if pt_dr is NULL
Effects: memset(pt_dr, 0, sizeof(device_runtime_t)), stores config, calls dr_state_machine_init(...), then calls dr_sm_update_requirements(...) (its return value is ignored)
References: cognit/include/device_runtime.h, cognit/src/device_runtime.c
e_status_code_t device_runtime_call(device_runtime_t* pt_dr, faas_t* pt_faas, scheduling_t t_new_reqs, void** pt_exec_response)Parameters: pt_dr (device_runtime_t*); pt_faas (faas_t*); t_new_reqs (scheduling_t); pt_exec_response (void**) — output execution response pointer
Return: e_status_code_t — E_ST_CODE_SUCCESS on success; error code otherwise
Errors: returns E_ST_CODE_ERROR if pt_dr is NULL; returns error if offload fails; returns E_ST_CODE_ERROR if *pt_exec_response == NULL after offload
Effects: calls dr_sm_update_requirements(...) (return ignored), then dr_sm_offload_function(...)
References: cognit/include/device_runtime.h, cognit/src/device_runtime.c
e_status_code_t device_runtime_free(device_runtime_t* pt_dr)Parameters: pt_dr (device_runtime_t*) — runtime instance
Return: e_status_code_t — E_ST_CODE_ERROR if pt_dr is NULL, otherwise E_ST_CODE_SUCCESS
Effects: calls dr_state_machine_stop(...) (return value ignored), then zeroes the runtime struct with memset
Notes: current implementation does not free any heap-owned fields that might exist inside cognit_config_t (a free_config() helper exists but is unused)
References: cognit/include/device_runtime.h, cognit/src/device_runtime.c
Files: cognit/include/device_runtime_state_machine.h, cognit/src/device_runtime_state_machine.c
-
State_t(enum)- Values:
INIT,SEND_INIT_REQUEST,GET_ECF_ADDRESS,READY
- Values:
-
Event_t(enum)- Values:
ADDRESS_OBTAINED,TOKEN_NOT_VALID_ADDRESS,RETRY_GET_ADDRESS,LIMIT_GET_ADDRESS,ADDRESS_UPDATE_REQUIREMENTS,SUCCESS_AUTH,REPEAT_AUTH,RESULT_GIVEN,TOKEN_NOT_VALID_READY,TOKEN_NOT_VALID_READY_2,READY_UPDATE_REQUIREMENTS,REQUIREMENTS_UP,TOKEN_NOT_VALID_REQUIREMENTS,RETRY_REQUIREMENTS_UPLOAD,LIMIT_REQUIREMENTS_UPLOAD,SEND_INIT_UPDATE_REQUIREMENTS,TOKEN_UPDATED,UPDATE_ECF_ADDRESS
- Values:
-
device_runtime_sm_t- Fields:
current_state: State_t,m_t_config: cognit_config_t,cfc: cognit_frontend_cli_t,ecf: edge_cluster_frontend_cli_t,biscuit_token: char[MAX_TOKEN_LENGTH],app_req_id: int,m_t_requirements: scheduling_t,up_req_counter: int,get_address_counter: int,requirements_changed: bool,requirements_uploaded: bool,has_requirements_upload_limit_reached: int,has_address_request_limit_reached: int
- Fields:
-
MAX_REQ_UPLOAD_ATTEMPTS— 3 -
MAX_GET_ADDRESS_ATTEMPTS— 3
int dr_state_machine_execute_transition(device_runtime_sm_t* pt_dr_sm, Event_t event)Parameters: pt_dr_sm (device_runtime_sm_t*), event (Event_t)
Return: int — status of transition execution
References: cognit/include/device_runtime_state_machine.h, cognit/src/device_runtime_state_machine.c
int dr_state_machine_init(device_runtime_sm_t* pt_dr_state_machine, cognit_config_t t_config, faas_t* pt_faas)Parameters: pt_dr_state_machine (device_runtime_sm_t*), t_config (cognit_config_t), pt_faas (faas_t*)
Return: int — initialization result
Effects: initializes internal clients, calls pb_parser_init and sets starting state
References: header and cognit/src/device_runtime_state_machine.c
e_status_code_t dr_sm_offload_function(device_runtime_sm_t* pt_dr_sm, faas_t* pt_faas, void** pt_exec_response)Parameters: pt_dr_sm (device_runtime_sm_t*), pt_faas (faas_t*), pt_exec_response (void**) — output pointer to execution response
Return: e_status_code_t — E_ST_CODE_SUCCESS on success, E_ST_CODE_ERROR on failure
Effects:
If current_state == READY, triggers UPDATE_ECF_ADDRESS to refresh ECF address (transitions to GET_ECF_ADDRESS) and then handles transitions until it reaches READY.
Offload flow: uploads function to DaaS (cfc_cli_upload_function_to_daas), then executes synchronously on ECF (ecf_cli_faas_exec_sync).
Errors / Recovery:
If execution fails, it re-authenticates (TOKEN_NOT_VALID_READY then TOKEN_UPDATED) and retries the offload once.
Notes: This call can block on network calls (CFC/ECF).
References: cognit/include/device_runtime_state_machine.h, cognit/src/device_runtime_state_machine.c
e_status_code_t dr_sm_update_requirements(device_runtime_sm_t* pt_dr_sm, scheduling_t t_reqs)Parameters: pt_dr_sm (device_runtime_sm_t*), t_reqs (scheduling_t) — new requirements
Return: e_status_code_t — E_ST_CODE_SUCCESS if requirements are unchanged or upload finishes; E_ST_CODE_ERROR on upload/auth failures
Effects:
If requirements did NOT change, returns E_ST_CODE_SUCCESS immediately.
If they changed: sets requirements_changed=true, stores t_reqs, and attempts to (re)upload them.
If CFC is disconnected, triggers a re-auth transition depending on current_state:
INIT -> TOKEN_NOT_VALID_READY
GET_ECF_ADDRESS -> TOKEN_NOT_VALID_ADDRESS
SEND_INIT_REQUEST -> TOKEN_NOT_VALID_REQUIREMENTS
Depending on state, it may trigger:
INIT -> SUCCESS_AUTH
READY -> READY_UPDATE_REQUIREMENTS (resets up_req_counter)
GET_ECF_ADDRESS -> ADDRESS_UPDATE_REQUIREMENTS
SEND_INIT_REQUEST -> SEND_INIT_UPDATE_REQUIREMENTS
Retries until requirements_uploaded==true. If attempts reach MAX_REQ_UPLOAD_ATTEMPTS, it zeroes stored requirements and transitions with LIMIT_REQUIREMENTS_UPLOAD (back to INIT).
References: cognit/include/device_runtime_state_machine.h, cognit/src/device_runtime_state_machine.c
e_status_code_t dr_state_machine_stop(device_runtime_sm_t* pt_dr_state_machine)Parameters: pt_dr_state_machine (device_runtime_sm_t*)
Return: int — 0 on success, -1 on error
Effects: Deletes the application requirements on Cognit Frontend using cognit_frontend_cli_delete(&cfc, biscuit_token, app_req_id).
Errors: Returns -1 if pt_dr_state_machine is NULL or if the delete call fails.
References: cognit/include/device_runtime_state_machine.h, cognit/src/device_runtime_state_machine.c
Files: cognit/include/edge_cluster_frontend_cli.h, cognit/src/edge_cluster_frontend_cli.c
-
edge_cluster_frontend_cli_t- Fields:
t_ecf_endpoint: char[MAX_URL_LENGTH],has_connection: int
- Fields:
-
MAX_URL_LENGTH,ECF_REQ_TIMEOUT,FAAS_REQUEST_ENDPOINT
void ecf_cli_init(edge_cluster_frontend_cli_t* pt_edge_cluster_frontend_cli, char* c_endpoint)Parameters: client, c_endpoint (char*) — endpoint URL
Return: void
Effects: initializes the client endpoint
References: cognit/include/edge_cluster_frontend_cli.h, cognit/src/edge_cluster_frontend_cli.c
int ecf_cli_faas_exec_sync(edge_cluster_frontend_cli_t* pt_edge_cluster_frontend_cli, char* biscuit_token, int app_req_id, faas_t* pt_faas, void** pt_exec_response)Parameters: client, biscuit_token, app_req_id, pt_faas, pt_exec_response
Return: int — 0 on success, error code otherwise
Effects: performs synchronous FaaS execution request to Edge Cluster
References: header and source
int ecf_cli_upload_function_to_daas(edge_cluster_frontend_cli_t* pt_edge_cluster_frontend_cli, char* biscuit_token, faas_t* pt_faas)Parameters: client, biscuit token, faas pointer
Return: int — 0 on success
References: header and source
void ecf_set_has_connection(edge_cluster_frontend_cli_t* pt_edge_cluster_frontend_cli, bool value)Parameters: client, value
Return: void
References: header
bool ecf_get_has_connection(edge_cluster_frontend_cli_t* pt_edge_cluster_frontend_cli)Parameters: client
Return: bool
References: header
Files: cognit/include/faas_parser.h, cognit/src/faas_parser.c
-
exec_return_code_t(enum):SUCCESS = 0,ERROR = -1 -
exec_response_t- Fields:
ret_code: exec_return_code_t,res: void**,err_code: long,ret_len: size_t
- Fields:
-
JSON_ERR_CODE_OK = 0,JSON_ERR_CODE_INVALID_JSON = -1
int8_t faasparser_parse_exec_faas_params_as_str_json(faas_t* exec_faas_params, uint8_t* ui8_payload_buff, size_t* payload_len)Parameters: exec_faas_params, ui8_payload_buff, payload_len
Return: int8_t — 0 on success, -1 on error
Effects: serializes FaaS params into JSON, base64-encodes protobuf, computes hash
References: header and cognit/src/faas_parser.c
int8_t faasparser_parse_json_str_as_exec_response(const char* json_str, void** pt_res)Parameters: json_str, pt_res
Return: int8_t — 0 on success, -1 on error
References: header and source
void faas_log_json_error_detail(const char* response_body)Parameters: response_body
Return: void
References: header
Files: cognit/include/pb_parser.h, cognit/src/pb_parser.c
-
faas_t- Fields:
myfunc: MyFunc,fc_id: int,params: MyParam[MAX_PARAMS],params_count: uint8_t
- Fields:
-
MAX_PARAMS— 16
void pb_parser_init(faas_t* pt_faas)Parameters: pt_faas
Return: void
Effects: initialize faas_t internal fields
References: cognit/include/pb_parser.h, cognit/src/pb_parser.c
Various helper signatures generated in header (examples):
void printParams(faas_t* pt_faas);
void addFLOATVar(faas_t* pt_faas, float val);
void addDOUBLEVar(faas_t* pt_faas, double val);
void addINT64Var(faas_t* pt_faas, int64_t val);
void addBYTESParam(faas_t* pt_faas, uint8_t* bytes, size_t len);
void addSTRINGParam(faas_t* pt_faas, const char* string);
void addFC(faas_t* pt_faas, char* fc_code);
int pb_serialize_fc(faas_t* pt_faas, uint8_t* fc_req_buf, int buf_len);
int pb_serialize_faas_param(faas_t* pt_faas, int num, uint8_t* req_buf, int len);
int pb_deserialize_faas_param(uint8_t* res_buf, size_t buf_len, size_t* res_len, void** result);Parameters/Returns: see declarations in cognit/include/pb_parser.h
Effects: wrappers around nanopb encode/decode for project-specific proto messages
References: cognit/include/pb_parser.h, cognit/src/pb_parser.c
Files: cognit/include/logger.h
-
COGNIT_LOG_LEVEL_TRACE— 0 -
COGNIT_LOG_LEVEL_DEBUG— 1 -
COGNIT_LOG_LEVEL_INFO— 2 -
COGNIT_LOG_LEVEL_ERROR— 3 -
COGNIT_LOG_LEVEL— configured default (COGNIT_LOG_LEVEL_DEBUG) -
COGNIT_LOG_TRACE(...),COGNIT_LOG_DEBUG(...),COGNIT_LOG_INFO(...),COGNIT_LOG_ERROR(...)— printf-backed logging macros
Notes: macros print tags and messages; arguments are evaluated unconditionally (watch side effects).
References: cognit/include/logger.h
Files: cognit/nanopb/pb.h, cognit/nanopb/pb_common.h, cognit/nanopb/pb_encode.h, cognit/nanopb/pb_decode.h, cognit/nanopb/pb_common.c, cognit/nanopb/pb_encode.c, cognit/nanopb/pb_decode.c, cognit/nanopb/nano.pb.h, cognit/nanopb/nano.pb.c
-
pb_byte_t,pb_type_t,pb_msgdesc_t,pb_field_iter_t,pb_istream_t,pb_ostream_t— nanopb core types
-
NANOPB_VERSION— "nanopb-1.0.0-dev" - PB_, PB_LTYPE_, PB_HTYPE_, PB_ATYPE_, PB_SIZE_MAX etc. — encoding/decoding control macros
From pb_encode.h / pb_decode.h:
bool pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct);
pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize);
bool pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct);
void pb_release(const pb_msgdesc_t *fields, void *dest_struct);
pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen);Parameters/Returns: see nanopb headers in cognit/nanopb/
Notes: nanopb implementation files provide varint encoding/decoding, stream helpers, submessage handling and release/free helpers used by pb_parser.
References: files under cognit/nanopb/