### Server Setup Example Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/README.md Sets up a libdtp server. This involves adding file payloads and then starting the main server loop. The `dtp_server_main` function runs until the `exit_server` flag is set to true. ```c dtp_file_payload_add(1, "firmware.bin"); bool exit_server = false; dtp_server_main(&exit_server); ``` -------------------------------- ### Complete DTP Server Example Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/server-api.md A full example demonstrating DTP server setup, including CSP initialization, payload registration (file-based), and running the main server loop. It shows how to add and remove file payloads. ```c #include #include #include #include #include #include // Platform-specific payload getter bool get_payload_meta(dtp_payload_meta_t *meta, uint8_t payload_id) { // Try file payloads first if (dtp_file_payload_get_meta(meta, payload_id)) { return true; } return false; } int main(int argc, char *argv[]) { printf("DTP Server starting\n"); // Initialize CSP csp_conf_t csp_conf; csp_conf_get_defaults(&csp_conf); csp_conf.hostname = "dtp_server"; csp_init(&csp_conf); // Configure CSP interfaces // (application-specific - add loopback, radio, etc.) // Register payloads if (dtp_file_payload_add(1, "/firmware/firmware.bin") == NULL) { printf("Warning: Could not add firmware payload\n"); } else { printf("Firmware payload (ID 1) registered\n"); } if (dtp_file_payload_add(2, "/config/config.dat") == NULL) { printf("Warning: Could not add config payload\n"); } else { printf("Config payload (ID 2) registered\n"); } printf("Available payloads:\n"); dtp_file_payload_info(); // Run server printf("Server listening on CSP port 7\n"); bool exit_server = false; dtp_server_main(&exit_server); printf("Server shutting down\n"); dtp_file_payload_del(1); dtp_file_payload_del(2); return 0; } ``` -------------------------------- ### Complete Custom Session Hooks Example Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/session-hooks.md A full example demonstrating how to implement custom session hooks for managing data transfers. This includes functions for session start, data reception, session end, and resource release. It also shows how to set up and use these hooks with a libdtp session. ```c #include #include #include typedef struct { FILE *output; uint32_t packets_received; uint32_t start_time; } my_context_t; void on_start(dtp_t *session) { my_context_t *ctx = (my_context_t *)dtp_session_get_user_ctx(session); ctx->packets_received = 0; ctx->start_time = csp_get_ms(); printf("[START] Transfer beginning\n"); } bool on_data(dtp_t *session, csp_packet_t *packet) { my_context_t *ctx = (my_context_t *)dtp_session_get_user_ctx(session); dtp_on_data_info_t info = dtp_get_data_info(session, packet); fwrite(info.data, 1, info.data_length, ctx->output); ctx->packets_received++; if (ctx->packets_received % 100 == 0) { printf("[DATA] %u packets, %u bytes received\n", ctx->packets_received, session->bytes_received); } return true; } void on_end(dtp_t *session) { my_context_t *ctx = (my_context_t *)dtp_session_get_user_ctx(session); uint32_t duration = csp_get_ms() - ctx->start_time; float throughput = (float)session->bytes_received / (duration / 1000.0); printf("[END] %u bytes in %u ms (%.1f KB/s)\n", session->bytes_received, duration, throughput / 1024.0); } void on_release(dtp_t *session) { my_context_t *ctx = (my_context_t *)dtp_session_get_user_ctx(session); if (ctx->output) fclose(ctx->output); free(ctx); } int main() { my_context_t *ctx = malloc(sizeof(my_context_t)); ctx->output = fopen("output.bin", "wb"); dtp_t *session = dtp_acquire_session(); dtp_session_set_user_ctx(session, ctx); dtp_opt_session_hooks_cfg hooks = { .on_start = on_start, .on_data_packet = on_data, .on_end = on_end, .on_release = on_release, }; dtp_params param = { .hooks = hooks }; dtp_set_opt(session, DTP_SESSION_HOOKS_CFG, ¶m); dtp_set_opt(session, DTP_REMOTE_CFG, &(dtp_params){ .remote_cfg.node = 10 }); dtp_start_transfer(session); dtp_release_session(session); return 0; } ``` -------------------------------- ### DTP File Server Implementation Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/INDEX.md Guides on setting up a file server using the server API and file payload handling. ```markdown [api-reference/server-api.md](api-reference/server-api.md) [api-reference/file-payload.md](api-reference/file-payload.md) ``` -------------------------------- ### Complete DTP File Payload Example Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/file-payload.md A comprehensive example demonstrating the registration of file payloads, displaying payload information, initiating a transfer, and cleaning up. It includes the necessary platform-specific implementation for get_payload_meta(). ```c #include #include #include #include // Implement platform payload getter bool get_payload_meta(dtp_payload_meta_t *meta, uint8_t payload_id) { return dtp_file_payload_get_meta(meta, payload_id); } int main() { // Register some files as payloads if (dtp_file_payload_add(1, "firmware.bin") == NULL) { printf("Failed to register firmware\n"); return 1; } if (dtp_file_payload_add(2, "config.dat") == NULL) { printf("Failed to register config\n"); dtp_file_payload_del(1); return 1; } // Display registered payloads printf("Registered payloads:\n"); dtp_file_payload_info(); // Start a transfer of payload 1 (firmware) dtp_t *session = dtp_prepare_session(10, 0x900dface, 100000, 30, 1, NULL, 256, false, 0); if (session) { dtp_start_transfer(session); dtp_release_session(session); } // Clean up dtp_file_payload_del(1); dtp_file_payload_del(2); return 0; } ``` -------------------------------- ### Simple DTP Client Implementation Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/INDEX.md Guides on creating a basic client using the core session API and transfer control. ```markdown [api-reference/core-session-api.md](api-reference/core-session-api.md) [api-reference/transfer-control.md](api-reference/transfer-control.md) ``` -------------------------------- ### Example: Resume Transfer with Custom Hooks Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/session-persistence.md This example demonstrates how to implement and use custom hooks for saving and restoring session state to resume interrupted transfers. It covers both initiating a transfer and later resuming it from a saved state file. ```c void save_session_hook(dtp_t *session, void *context) { FILE *f = (FILE *)context; fprintf(f, "version=2\n"); fprintf(f, "bytes_received=%u\n", session->bytes_received); fprintf(f, "payload_size=%u\n", session->payload_size); } void restore_session_hook(dtp_t *session, void *context) { FILE *f = (FILE *)context; int version; unsigned int bytes_rx, payload_sz; if (fscanf(f, "version=%d\n", &version) != 1) { session->dtp_errno = DTP_EINVAL; return; } if (fscanf(f, "bytes_received=%u\n", &bytes_rx) != 1) { session->dtp_errno = DTP_EINVAL; return; } if (fscanf(f, "payload_size=%u\n", &payload_sz) != 1) { session->dtp_errno = DTP_EINVAL; return; } session->bytes_received = bytes_rx; session->payload_size = payload_sz; } dtp_opt_session_hooks_cfg hooks = { .on_serialize = save_session_hook, .on_deserialize = restore_session_hook, }; dtp_params param = { .hooks = hooks }; // First transfer - will be interrupted FILE *state_file = fopen("session.state", "w+"); dtp_t *session = dtp_prepare_session(10, 0x900dface, 100000, 30, 1, state_file, 256, false, 0); if (session) { dtp_set_opt(session, DTP_SESSION_HOOKS_CFG, ¶m); dtp_start_transfer(session); dtp_serialize_session(session, state_file); dtp_release_session(session); } // Later, resume the transfer rewind(state_file); dtp_t *resumed = dtp_prepare_session(10, 0x900dface, 100000, 30, 1, state_file, 256, true, 0); if (resumed) { dtp_set_opt(resumed, DTP_SESSION_HOOKS_CFG, ¶m); dtp_start_transfer(resumed); dtp_release_session(resumed); } else if (dtp_errno(NULL) == DTP_SESSION_EXHAUSTED) { printf("Transfer already complete\n"); } else { printf("Resume failed\n"); } fclose(state_file); ``` -------------------------------- ### DTP Reading Order for New Users Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/INDEX.md Recommended sequence for new users to learn DTP, starting with the README and basic concepts. ```markdown 1. [README.md](README.md) - Documentation guide 2. [api-overview.md](api-overview.md) - DTP concepts 3. [core-session-api.md](api-reference/core-session-api.md) - Basic API 4. [transfer-control.md](api-reference/transfer-control.md) - Transfers ``` -------------------------------- ### Example of Configuring Log Colors Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/logging-and-utils.md Demonstrates disabling colors when the output is not a terminal, ensuring logs are plain text. ```c #include int main() { // Disable colors if output is not a terminal if (!isatty(fileno(stdout))) { dbg_enable_colors(false); } // Now all log messages will be printed without ANSI color codes dtp_t *session = dtp_acquire_session(); // ... } ``` -------------------------------- ### DTP Parameters Union and Usage Example Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/types.md A union that holds all DTP configuration parameter types. Demonstrates setting throughput and getting remote configuration. ```c typedef union { dtp_opt_remote_cfg remote_cfg; dtp_opt_session_hooks_cfg hooks; dtp_opt_throughput_cfg throughput; dtp_opt_timeout_cfg timeout; dtp_opt_payload_id_cfg payload_id; dtp_opt_mtu_cfg mtu; dtp_opt_session_id_cfg session_id; } dtp_params; // Usage: dtpparam param; param.throughput.value = 100000; dtpp_set_opt(session, DTP_THROUGHPUT_CFG, ¶m); dtpp_get_opt(session, DTP_REMOTE_CFG, ¶m); uint16_t server_node = param.remote_cfg.node; ``` -------------------------------- ### Example Usage of dbg_warn Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/logging-and-utils.md Shows how to use dbg_warn for logging recoverable errors or unexpected conditions, with examples for null packets and incomplete data. ```c #include if (packet == NULL) { dbg_warn("No packet received, timeout expired"); } if (bytes_received < expected) { dbg_warn("Received %u bytes, expected %u", bytes_received, expected); ``` -------------------------------- ### Basic Transfer Example Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/README.md Initiates a simple data transfer. Requires acquiring a session, configuring remote node and payload ID, starting the transfer, and then releasing the session. ```c dtp_t *session = dtp_acquire_session(); dtp_set_opt(session, DTP_REMOTE_CFG, &(dtp_params){.remote_cfg.node=10}); dtp_set_opt(session, DTP_PAYLOAD_ID_CFG, &(dtp_params){.payload_id.value=1}); dtp_start_transfer(session); dtp_release_session(session); ``` -------------------------------- ### Example Usage of dbg_log Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/logging-and-utils.md Demonstrates how to use the dbg_log macro for informational messages, including formatted strings. ```c #include dbg_log("Transfer starting"); dbg_log("Received %u bytes at offset %u", bytes, offset); dbg_log("Session state: %d", session->active); ``` -------------------------------- ### Example: Add and Merge Segments Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/segment-utilities.md Demonstrates adding segments using add_segment, showing how overlapping segments are automatically merged into a single range. ```c segments_ctx_t *segments = init_segments_ctx(); add_segment(segments, 0, 10); // [0-10] add_segment(segments, 5, 15); // Merges to [0-15] add_segment(segments, 20, 30); // [0-15], [20-30] print_segments(segments); free_segments(segments); ``` -------------------------------- ### Example: Print Segment Information Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/segment-utilities.md Demonstrates using for_each_segment with a simple callback to print details of each segment. Ensure segments context is initialized and closed properly. ```c bool print_segment(uint32_t idx, uint32_t start, uint32_t end, void *ctx) { printf("Segment %u: [%u-%u] (%u bytes)\n", idx, start, end, (end - start + 1)); return true; // Continue } segments_ctx_t *segments = init_segments_ctx(); update_segments(segments, 0); update_segments(segments, 5); update_segments(segments, 10); close_segments(segments); for_each_segment(segments, print_segment, NULL); free_segments(segments); ``` -------------------------------- ### Initialize and Run DTP Server Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/server-api.md Example of initializing the CSP library, registering file payloads, and running the main DTP server loop. Ensure CSP is initialized before calling this function. ```c #include #include #include #include bool get_payload_meta(dtp_payload_meta_t *meta, uint8_t payload_id) { return dtp_file_payload_get_meta(meta, payload_id); } int main() { // Initialize CSP library (application-specific) csp_init(); // Register payloads dtp_file_payload_add(1, "firmware.bin"); dtp_file_payload_add(2, "config.dat"); // Run server until user requests shutdown bool exit_server = false; dtp_server_main(&exit_server); return 0; } ``` -------------------------------- ### Example Usage of dtp_file_payload_info() Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/file-payload.md Demonstrates how to add file payloads and then display their information using dtp_file_payload_info(). This is useful for debugging and verifying payload registration. ```c dtp_file_payload_add(1, "firmware.bin"); dtpd_file_payload_add(2, "config.dat"); dtpd_file_payload_info(); ``` -------------------------------- ### Custom on_start Hook Example Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/session-hooks.md Implement a custom `on_start` hook to perform actions before a transfer begins, such as initializing resources or logging transfer details. Access session information like payload size. ```c void my_on_start(dtp_t *session) { printf("Transfer starting - payload size: %u bytes\n", session->payload_size); // Open output file, initialize buffers, etc. } ``` -------------------------------- ### Complete Segment Management Example Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/segment-utilities.md Demonstrates a comprehensive workflow for segment management. This includes initializing a segment context, simulating packet reception with gaps using `update_segments`, closing the context, printing received segments, finding missing segments using `get_complement_segment`, and iterating through the missing segments. ```c #include #include int main() { // Initialize segment context segments_ctx_t *segments = init_segments_ctx(); if (!segments) { printf("Failed to allocate segments\n"); return 1; } // Simulate receiving packets with gaps printf("Simulating packet reception:\n"); update_segments(segments, 0); // Receive packet 0 update_segments(segments, 1); // Receive packet 1 update_segments(segments, 2); // Receive packet 2 update_segments(segments, 5); // Receive packet 5 (gap) update_segments(segments, 6); // Receive packet 6 update_segments(segments, 7); // Receive packet 7 update_segments(segments, 10); // Receive packet 10 (gap) close_segments(segments); printf("Received segments:\n"); print_segments(segments); printf("Total segments: %u\n\n", get_nof_segments(segments)); // Find missing segments in range [0, 15] printf("Finding missing segments in [0-15]:\n"); segments_ctx_t *missing = get_complement_segment(segments, 0, 15); print_segments(missing); printf("Missing segments: %u\n\n", get_nof_segments(missing)); // Iterate over missing segments printf("Missing segments details:\n"); for_each_segment(missing, [](uint32_t idx, uint32_t start, uint32_t end, void *ctx) { printf(" [%u-%u]\n", start, end); return true; }, NULL); free_segments(missing); free_segments(segments); return 0; } ``` -------------------------------- ### Resumable Transfer Example Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/README.md Demonstrates how to save the state of a transfer for later resumption. The `dtp_serialize_session` function saves the state, and `dtp_prepare_session` with `resume=true` restores it. ```c // Save dtp_serialize_session(session, state_file); // Resume dtp_t *session = dtp_prepare_session(..., true); // resume=true if (session) dtp_start_transfer(session); ``` -------------------------------- ### Example: Remove Exact Segment Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/segment-utilities.md Shows how to use remove_segment to delete a specific segment from the context. Only exact matches are removed; no splitting occurs. ```c segments_ctx_t *segments = init_segments_ctx(); add_segment(segments, 0, 10); add_segment(segments, 20, 30); remove_segment(segments, 0, 10); // Removes first segment print_segments(segments); // Only [20-30] remains free_segments(segments); ``` -------------------------------- ### Generate Sequential Session ID Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/configuration.md Example of generating a sequential session ID for DTP. Ensure `next_session_id` is managed appropriately. ```c // Sequential static uint32_t next_session_id = 1; uint32_t session_id = next_session_id++; ``` -------------------------------- ### Initialize CSP and DTP Server Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/server-api.md Basic main function structure for initializing CSP, configuring interfaces, and starting the DTP server. This serves as a minimal entry point for a DTP server application. ```c #include #include int main() { // Initialize CSP csp_conf_t csp_conf; csp_conf_get_defaults(&csp_conf); csp_conf.hostname = "server"; csp_init(&csp_conf); // Set up CSP interfaces and routing // (application-specific) // Start DTP server bool exit_server = false; dtp_server_main(&exit_server); return 0; } ``` -------------------------------- ### Implement Async API for Virtual Memory Server Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/server-api.md Example implementation of the required asynchronous API callbacks for the virtual memory server. This includes functions for receiving/sending messages and reading from virtual memory addresses. ```c #include #include #include // Implement async API callbacks void my_recv(dtp_async_api_t *me, dtp_msg_t *msg) { // Receive from queue } bool my_send(dtp_async_api_t *me, dtp_msg_t *msg) { // Send to queue return true; } uint32_t my_read(dtp_async_api_t *me, uint8_t *to_addr, uint64_t from_vaddr, uint32_t size) { // Read from virtual address space memcpy(to_addr, (void *)from_vaddr, size); return size; } int vmem_server_thread(void *arg) { dtp_async_api_t api = { .recv = my_recv, .send = my_send, .read = my_read, .context = NULL }; return dtp_vmem_server_main(&api); } ``` -------------------------------- ### Resume Parameter Behavior Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/session-persistence.md This table outlines the behavior of the `resume` parameter in `dtp_prepare_session`. `false` starts a new transfer, while `true` attempts to resume an existing session. ```c false | Start a fresh transfer, ignore any previous session state true | Attempt to deserialize a previous session and resume it ``` -------------------------------- ### Check Heap Before DTP Session Acquisition Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/errors.md A pseudo-code example demonstrating how to check available heap memory before attempting to acquire a DTP session. This proactive approach helps prevent DTP_MALLOC_FAILED errors. ```c // Pseudo-code for heap monitoring uint32_t free_heap = get_free_heap(); uint32_t required_heap = 10000; // Estimate if (free_heap < required_heap) { printf("Insufficient heap (%u < %u)\n", free_heap, required_heap); return -1; } dtp_t *session = dtp_acquire_session(); ``` -------------------------------- ### Complete DTP Logging Example Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/logging-and-utils.md This C code demonstrates a full DTP transfer with custom logging and event handlers. It includes packet processing, progress reporting, and session completion statistics. Ensure DTP library headers are included and a context structure is used for session-specific data. ```c #include #include #include #include #include #include typedef struct { FILE *output; uint32_t packets; uint32_t start_time; } context_t; bool on_data_packet(dtp_t *session, csp_packet_t *packet) { context_t *ctx = (context_t *)dtp_session_get_user_ctx(session); dtp_on_data_info_t info = dtp_get_data_info(session, packet); fwrite(info.data, 1, info.data_length, ctx->output); ctx->packets++; if (ctx->packets % 100 == 0) { float progress = (float)session->bytes_received / session->payload_size * 100.0; dbg_log("Progress: %.1f%% (%u/%u bytes, %u packets)", progress, session->bytes_received, session->payload_size, ctx->packets); } return true; } void on_end(dtp_t *session) { context_t *ctx = (context_t *)dtp_session_get_user_ctx(session); dtp_errno_t err = dtp_errno(session); if (err == DTP_NO_ERR) { dbg_log("Transfer complete successfully"); } else if (err == DTP_SESSION_EXHAUSTED) { dbg_log("Transfer paused - can resume later"); } else { dbg_warn("Transfer failed: %s", dtp_strerror(err)); } uint32_t duration = session->end_ts - session->start_ts; float throughput = (float)session->bytes_received / (duration / 1000.0); dbg_log("Statistics: %u bytes in %u ms (%.1f KB/s)", session->bytes_received, duration, throughput / 1024.0); } bool get_payload_meta(dtp_payload_meta_t *meta, uint8_t payload_id) { return dtp_file_payload_get_meta(meta, payload_id); } int main() { dbg_enable_colors(true); // Enable colored output dtp_file_payload_add(1, "firmware.bin"); context_t ctx = { .output = fopen("output.bin", "wb"), .packets = 0, }; dtp_t *session = dtp_acquire_session(); if (session == NULL) { dbg_warn("Failed to acquire session: %s", dtp_strerror(dtp_errno(NULL))); return 1; } dtp_session_set_user_ctx(session, &ctx); dtp_opt_session_hooks_cfg hooks = { .on_data_packet = on_data_packet, .on_end = on_end, }; dtp_params param = { .hooks = hooks }; dtp_set_opt(session, DTP_SESSION_HOOKS_CFG, ¶m); dtp_result res = dtp_start_transfer(session); if (res != DTP_OK) { dbg_warn("Transfer failed: %s", dtp_strerror(dtp_errno(session))); } dtp_release_session(session); fclose(ctx.output); dtp_file_payload_del(1); return res == DTP_OK ? 0 : 1; } ``` -------------------------------- ### Example: Request Missing Segments Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/segment-utilities.md Illustrates using for_each_segment to populate a DTP meta request with missing segments. The callback function adds segment intervals to a request context. ```c typedef struct { dtp_t *session; dtp_meta_req_t *request; } request_context_t; bool request_missing(uint32_t idx, uint32_t start, uint32_t end, void *ctx) { request_context_t *rctx = (request_context_t *)ctx; // Add this segment to the request's interval list if (idx < 8) { // DTP supports up to 8 intervals rctx->request->intervals[idx].start = start; rctx->request->intervals[idx].end = end; rctx->request->nof_intervals = idx + 1; } return true; } segments_ctx_t *missing = get_complement_segment(received, 0, total_packets); request_context_t rctx = { .session = session, .request = &session->request_meta }; for_each_segment(missing, request_missing, &rctx); free_segments(missing); ``` -------------------------------- ### Setup Server Transfer Context Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/server-api.md Prepares a server transfer context from a client request. It extracts request details, retrieves payload information, and constructs a response packet. The caller is responsible for sending the response. ```c csp_packet_t *setup_server_transfer(dtp_server_transfer_ctx_t *ctx, uint16_t dst, csp_packet_t *request); ``` -------------------------------- ### DTP Session Preparation Function Signature Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/session-persistence.md This is the function signature for `dtp_prepare_session`. The `resume` parameter controls whether to start a new transfer or attempt to resume a previous one. ```c dtp_t *dtp_prepare_session(uint32_t server, uint32_t session_id, uint32_t max_throughput, uint8_t timeout, uint8_t payload_id, void *ctx, uint16_t mtu, bool resume, uint32_t keep_alive_interval); ``` -------------------------------- ### Start a DTP Transfer Session Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/transfer-control.md Initiates a DTP transfer with a remote server. Call this after preparing a session. Handles connection, metadata exchange, and data reception. The transfer can be interrupted. ```c dtp_result dtp_start_transfer(dtp_t *session); ``` ```c dtp_t *session = dtp_prepare_session(10, 0x900dface, 100000, 30, 1, NULL, 256, false, 0); if (session) { dtp_result res = dtp_start_transfer(session); if (res == DTP_OK) { printf("Transfer complete\n"); } else if (res == DTP_CANCELLED) { printf("Transfer paused, can resume later\n"); } else { printf("Transfer failed: %s\n", dtp_strerror(dtp_errno(session))); } dtp_release_session(session); } ``` -------------------------------- ### DTP Client Session Lifecycle Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-overview.md Illustrates the sequence of function calls for managing a DTP client session, from acquisition to release. This flow includes configuration, starting, stopping, and persisting transfer states. ```c dtp_acquire_session() ┐ ↓ │ dtp_prepare_session() │ Configure ↓ │ dtp_set_opt() [optional] ┘ ↓ dtp_start_transfer() ─── Transfer starts ↓ [data received via hooks] ↓ dtp_stop_transfer() [optional] ─── Pause transfer ↓ dtp_serialize_session() ─── Save state ↓ dtp_release_session() ─── Release resources ``` -------------------------------- ### DTP Server Payload Meta Implementation Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-overview.md Example of implementing the platform-specific payload metadata getter function for the DTP server. This function defines available payloads and returns their size and read function. ```c // Implement platform-specific payload getter bool get_payload_meta(dtp_payload_meta_t *meta, uint8_t payload_id) { // Define which payloads are available // Return their metadata (size, read function) } ``` -------------------------------- ### Simple One-Shot Data Transfer Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-overview.md Initiate a simple, one-shot data transfer. Acquire a session, set remote configuration and payload ID, start the transfer, and then release the session. ```c dtp_t *session = dtp_acquire_session(); dt p_set_opt(session, DTP_REMOTE_CFG, &(dtp_params){.remote_cfg.node=10}); dt p_set_opt(session, DTP_PAYLOAD_ID_CFG, &(dtp_params){.payload_id.value=1}); dt p_start_transfer(session); dt p_release_session(session); ``` -------------------------------- ### Start Sending Data Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/server-api.md Transmits payload data to the client using the configured read callback. Data is packetized according to MTU and sent until all bytes are transferred or the keep_running flag is false. Uses OS-level polling for timing. ```c dtp_result start_sending_data(dtp_server_transfer_ctx_t *ctx); ``` -------------------------------- ### Complete DTP Error Handling Example in C Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/errors.md This C code demonstrates a full error handling workflow for DTP transfers. It includes checking transfer results, retrieving specific error codes, converting them to human-readable strings, and providing actionable advice based on the error type. Use this pattern for robust error management in your DTP applications. ```c #include #include #include void handle_transfer_error(dtp_t *session, dtp_result res) { if (res == DTP_OK) { printf("Transfer successful\n"); return; } if (res == DTP_CANCELLED) { printf("Transfer interrupted - can resume later\n"); return; } // res == DTP_ERR dtp_errno_t err = dtp_errno(session); const char *error_str = dtp_strerror(err); printf("Transfer failed: %s\n", error_str); // Provide specific guidance switch (err) { case DTP_CONNECTION_FAILED: printf("Action: Verify server is running and reachable\n"); break; case DTP_EINVAL: printf("Action: Check session configuration parameters\n"); break; case DTP_MALLOC_FAILED: printf("Action: Check available heap memory\n"); break; case DTP_SESSION_EXHAUSTED: printf("Action: Previous transfer already complete\n"); break; default: printf("Action: Check logs for details\n"); } } int main() { dtp_enable_colors(true); dtp_t *session = dtp_acquire_session(); if (session == NULL) { dtp_errno_t global_err = dtp_errno(NULL); printf("Failed to acquire session: %s\n", dtp_strerror(global_err)); return 1; } // Configure session... dtp_params param = { .remote_cfg.node = 10 }; dtp_set_opt(session, DTP_REMOTE_CFG, ¶m); // Attempt transfer dtp_result res = dtp_start_transfer(session); handle_transfer_error(session, res); // Cleanup if (dtp_release_session(session) != DTP_OK) { printf("Warning: Failed to release session\n"); } return res == DTP_OK ? 0 : 1; } ``` -------------------------------- ### Generate Time-based Session ID Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/configuration.md Example of generating a time-based session ID using `csp_get_ms()`. This provides a simple way to get unique IDs. ```c // Time-based uint32_t session_id = csp_get_ms(); ``` -------------------------------- ### Get Last DTP Error Code Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/logging-and-utils.md Retrieves the error code from the most recent DTP operation. Pass NULL for session to get the global error. ```c dtp_errno_t dtp_errno(dtp_t *session); ``` ```c dtp_t *session = dtp_acquire_session(); if (session == NULL) { dtp_errno_t err = dtp_errno(NULL); // Check global error printf("Failed to acquire session: %s\n", dtp_strerror(err)); return -1; } dtp_result res = dtp_start_transfer(session); if (res != DTP_OK) { dtp_errno_t err = dtp_errno(session); printf("Transfer failed: %s\n", dtp_strerror(err)); } ``` -------------------------------- ### Get Number of Segments Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/segment-utilities.md Returns the number of disjoint segments in the context. This should be called after close_segments(). ```c uint32_t get_nof_segments(segments_ctx_t *ctx); ``` ```c close_segments(segments); uint32_t count = get_nof_segments(segments); printf("Received %u segment(s)\n", count); ``` -------------------------------- ### Server with File Payloads Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-overview.md Set up a DTP server to handle file payloads. Register files using `dtp_file_payload_add`, implement `get_payload_meta` to provide file metadata, and run the server main loop. ```c // Register files dt p_file_payload_add(1, "/firmware/app.bin"); dt p_file_payload_add(2, "/config/settings.dat"); // Implement payload getter bool get_payload_meta(dtp_payload_meta_t *meta, uint8_t payload_id) { return dtp_file_payload_get_meta(meta, payload_id); } // Run server bool exit_server = false; dt p_server_main(&exit_server); ``` -------------------------------- ### Prepare and Configure a DTP Session Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/core-session-api.md Prepares a session with initial configuration parameters, optionally resuming a previous session. Acquires a session from the pool and configures options like server, throughput, timeout, and MTU. Returns NULL on failure. ```c dtp_t *dtp_prepare_session(uint32_t server, uint32_t session_id, uint32_t max_throughput, uint8_t timeout, uint8_t payload_id, void *ctx, uint16_t mtu, bool resume, uint32_t keep_alive_interval); ``` ```c dtp_t *session = dtp_prepare_session( 10, // server CSP node 0x900dface, // session ID 100000, // 100KB/s throughput 30, // 30 second timeout 1, // payload ID 1 NULL, // no user context 256, // 256 byte MTU false, // don't resume 5000 // 5 second keep-alive ); if (session == NULL) { printf("Prepare failed: %s\n", dtp_strerror(dtp_errno(NULL))); } ``` -------------------------------- ### Prepare Session with Parameters Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-overview.md Prepare a DTP session with specific parameters including remote node, session ID, throughput, timeout, payload ID, user context, MTU, resumability, and keep-alive interval. ```c dtp_t *session = dtp_prepare_session( 10, // Remote server CSP node 0x900dface, // Unique session ID 100000, // Max throughput (100 KB/s) 30, // Idle timeout (30 seconds) 1, // Payload ID to transfer NULL, // User context 256, // MTU (256 bytes) false, // Don't resume 5000 // Keep-alive every 5 seconds ); ``` -------------------------------- ### Example Session State Inspection Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/logging-and-utils.md Provides patterns for accessing session fields to check transfer completion, calculate progress, duration, and throughput. ```c // Check if transfer is complete if (session->bytes_received == session->payload_size) { printf("Transfer complete\n"); } // Calculate progress float progress = (float)session->bytes_received / session->payload_size * 100.0; printf("Progress: %.1f%%\n", progress); // Calculate duration uint32_t duration_ms = session->end_ts - session->start_ts; printf("Duration: %u ms\n", duration_ms); // Calculate throughput float throughput_kbs = (float)session->bytes_received / duration_ms / 1024.0 * 1000.0; printf("Throughput: %.1f KB/s\n", throughput_kbs); ``` -------------------------------- ### on_start Hook Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/session-hooks.md Callback invoked when a DTP transfer session is initiated. Useful for initializing resources and performing pre-transfer validation. ```APIDOC ## Hook: on_start ### Description Called when a transfer session is about to begin. This hook is suitable for initializing resources, logging start information, and performing pre-transfer validation. ### Signature ```c void (*on_start)(dtp_t *session); ``` ### Parameters - `session` (dtp_t *) - Pointer to the DTP session object being started. ### Usage - Initialize resources needed for the transfer. - Log transfer start information. - Perform pre-transfer validation. ### Default Behavior Logs "Default on_start hook". ### Example ```c void my_on_start(dtp_t *session) { printf("Transfer starting - payload size: %u bytes\n", session->payload_size); // Open output file, initialize buffers, etc. } ``` ``` -------------------------------- ### Example Usage of DTP Result Type Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/logging-and-utils.md Illustrates checking the return value of a DTP function to handle success, errors, or cancellations appropriately. ```c dtp_result res = dtp_start_transfer(session); if (res == DTP_OK) { printf("Transfer complete\n"); } else if (res == DTP_CANCELLED) { printf("Transfer paused, can resume\n"); } else { // DTP_ERR printf("Error: %s\n", dtp_strerror(dtp_errno(session))); } ``` -------------------------------- ### Safe Session Management with Release Check Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/errors.md Illustrates a robust approach to session management, including acquiring a session, performing operations, releasing the session, and checking for errors during release. It also shows setting the session pointer to NULL after release to prevent accidental reuse. ```c dtp_t *session = dtp_acquire_session(); if (session == NULL) { printf("Failed to acquire\n"); return -1; } // Use session dtpt_start_transfer(session); // Release (check for errors) dtpt_result res = dtp_release_session(session); if (res != DTP_OK) { printf("Release failed: %s\n", dtp_strerror(dtp_errno(NULL))); } session = NULL; // Clear pointer after release to prevent reuse ``` -------------------------------- ### Get DTP Error String Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/logging-and-utils.md Returns a human-readable string for a given DTP error code. Ensures a valid string is always returned. ```c const char *dtp_strerror(dtp_errno_t err); ``` ```c dtp_result res = dtp_start_transfer(session); if (res == DTP_ERR) { printf("Error: %s\n", dtp_strerror(dtp_errno(session))); } ``` -------------------------------- ### Add Segment to Context Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/segment-utilities.md Manually add a segment defined by start and end points to the segment context. This function merges overlapping segments. ```c void add_segment(segments_ctx_t *ctx, uint32_t start, uint32_t end); ``` -------------------------------- ### dtp_prepare_session() Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/core-session-api.md Prepares a session with initial configuration parameters and optionally resumes a previous session. Returns a configured session pointer or NULL on failure. ```APIDOC ## dtp_prepare_session() ### Description Prepares a session with initial configuration parameters and optionally resumes a previous session. Acquires a session from the pool and configures it for transfer. ### Method `dtp_prepare_session(uint32_t server, uint32_t session_id, uint32_t max_throughput, uint8_t timeout, uint8_t payload_id, void *ctx, uint16_t mtu, bool resume, uint32_t keep_alive_interval)` ### Parameters #### Path Parameters - **server** (`uint32_t`) - Required - CSP node address of the DTP server. - **session_id** (`uint32_t`) - Required - Unique identifier for this transfer session. - **max_throughput** (`uint32_t`) - Required - Maximum transfer throughput in bytes/second. - **timeout** (`uint8_t`) - Required - Idle timeout in seconds before canceling transfer. - **payload_id** (`uint8_t`) - Required - Server-specific payload identifier to retrieve. - **ctx** (`void *`) - Required - User context pointer (stored in session, used by hooks). - **mtu** (`uint16_t`) - Required - Maximum transmission unit size in bytes. - **resume** (`bool`) - Required - If true, attempt to deserialize and resume a previous session. - **keep_alive_interval** (`uint32_t`) - Required - Milliseconds between keep-alive messages (0 to disable). ### Return Type `dtp_t *` - Pointer to a configured session object ready for transfer. - Returns `NULL` if session acquisition failed or configuration failed. ### Throws/Rejects - `DTP_ENOMORE_SESSIONS`: No available sessions in the pool. - `DTP_SESSION_EXHAUSTED`: Resume was true but no more data to fetch from previous session. - `DTP_EINVAL`: Failed to set one of the session options. ### Details Acquires a session from the pool. If `resume` is true, attempts to deserialize session state. Configures all session options (remote node, throughput, timeout, payload ID, MTU, session ID, keep-alive) and sets the user context. ### Example ```c dtpp_t *session = dtp_prepare_session( 10, // server CSP node 0x900dface, // session ID 100000, // 100KB/s throughput 30, // 30 second timeout 1, // payload ID 1 NULL, // no user context 256, // 256 byte MTU false, // don't resume 5000 // 5 second keep-alive ); if (session == NULL) { printf("Prepare failed: %s\n", dtp_strerror(dtp_errno(NULL))); } ``` ``` -------------------------------- ### print_segments() Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/segment-utilities.md Dumps the current segments to standard output for debugging purposes. It displays the segments in a human-readable format, showing the start and end of each segment. ```APIDOC ## print_segments(ctx) ### Description Dumps the current segments to stdout for debugging. ### Parameters #### Path Parameters - **ctx** (`segments_ctx_t *`) - Required - Segment context ### Return Type `void` ### Output Format ``` Segment[0]: [0-100] Segment[1]: [150-200] Segment[2]: [250-500] ``` ### Example ```c segments_ctx_t *segments = init_segments_ctx(); update_segments(segments, 0); update_segments(segments, 1); update_segments(segments, 10); close_segments(segments); print_segments(segments); // Output: shows segments free_segments(segments); ``` ``` -------------------------------- ### remove_segment() Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/segment-utilities.md Manually removes an exact segment from the context. This function does not split segments; it only removes segments that precisely match the provided start and end points. ```APIDOC ## remove_segment() ### Description Manually removes an exact segment from the context. This function does not split segments; it only removes segments that precisely match the provided start and end points. If no exact match is found, no action is taken. ### Signature ```c void remove_segment(segments_ctx_t *ctx, uint32_t start, uint32_t end); ``` ### Parameters - **ctx** (`segments_ctx_t *`) - Required - Segment context. - **start** (`uint32_t`) - Required - Start of the segment to remove. - **end** (`uint32_t`) - Required - End of the segment to remove. ### Return Type `void` ### Details - Finds and removes exact segment matching [start, end]. - Does not split segments; only removes exact matches. ### Example ```c segments_ctx_t *segments = init_segments_ctx(); add_segment(segments, 0, 10); add_segment(segments, 20, 30); remove_segment(segments, 0, 10); // Removes first segment print_segments(segments); // Only [20-30] remains free_segments(segments); ``` ``` -------------------------------- ### Remove Segment from Context Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/segment-utilities.md Manually remove a segment from the context that exactly matches the provided start and end points. This function does not split existing segments. ```c void remove_segment(segments_ctx_t *ctx, uint32_t start, uint32_t end); ``` -------------------------------- ### DTP Configuration Options Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/INDEX.md Lists and describes the available configuration parameters for DTP. ```markdown [configuration.md](configuration.md) ``` -------------------------------- ### Run DTP Server Main Loop Source: https://github.com/spaceinventor/libdtp/blob/master/_autodocs/api-reference/server-api.md Use this simplified entry point to run the DTP server event loop. It handles connection acceptance, metadata exchange, and data transmission until a shutdown flag is set. ```c int dtp_server_main(bool *exit_server); ```