🛰️Zafer Satılmış - Aviora

Network Service — Customer-Driven Generation

Ethernet and GSM (PPP) behaviour is declared per customer in network_config.json under Customers/<customer>/Network/. The Python tool Customers/generate_network_service.py reads that file and emits C headers and a small bridge so the application always compiles against one consistent profile—without hand-editing dozens of macros for each product.

What The Generator Does

Run the script from the repository root (or any working directory, using paths relative to where you invoke Python). Pass --customer <FolderName> where FolderName matches Customers/<FolderName>/Network/network_config.json. The generator parses JSON only; it does not guess missing fields.

Inside networkStack, the tool selects the first object whose use field is exactly true. Every other stack entry is ignored for code generation. That chosen stack defines which TCP/IP integration you build (CycloneTcp, Linux, lwIP profile, etc.), its init header and function name, and the interfaces subtree.

Under interfaces, only two arrays matter today: ethInterfaces and gsmInterfaces. Within each array, only entries with use: true become active. The generator assigns global interface indices in order: all active Ethernet entries first (in array order), then all active PPP/GSM entries (in array order). Those choices drive macro names (for example ETH_ vs ETH0_/ETH1_ when multiple links exist) and the call order in networkServiceStartInterfaces().

Example — PowerShell
PS> cd C:\Users\...\Aviora
PS> python Customers/generate_network_service.py --customer LinuxGcc

- Generated network service for customer: LinuxGcc
- ...\Customers\LinuxGcc\Network\Cus_Network_Config.h
- ...\Customers\LinuxGcc\Network\Cus_Network_Config.c
- ...\Customers\NetworkService_Config.h

Generated Files And Who Consumes Them

File Role Consumed By
Customers/<customer>/Network/Cus_Network_Config.h Defines NET_INTERFACE_COUNT, stack name and version, paths to stack config, DHCP/DNS flags, NET_STACK_STACK_INIT_FUNCTION, and per-interface macros (IP, driver hooks, manager function names, etc.) derived from JSON. Included by Cus_Network_Config.c and, indirectly, by anything that needs the macros after including the customer bridge. Interface modules (Ethernet/PPP managers) implement the functions whose names appear in the macros.
Customers/<customer>/Network/Cus_Network_Config.c Implements networkServiceInitTCPIPStack() (calls the stack init macro when present) and networkServiceStartInterfaces() (OR-combines return codes while calling each active interface’s start macro in Ethernet-then-PPP order). The network service layer (AppNetworkService) calls these two functions during startup. You normally add the generated .c file to the build for that customer.
Customers/NetworkService_Config.h A single line including "<customer>/Network/Cus_Network_Config.h" so the application has one stable include path regardless of which customer tree is active. AppNetworkService.c includes ../../../../Customers/NetworkService_Config.h. Switching customers is therefore a build or configuration step that points at the right generated bridge—not a sweep through application sources.
Workflow: edit network_config.json, run generate_network_service.py, commit the three generated files. Do not hand-edit generated C/H files; they will be overwritten and your changes will be lost.

Build-Time Data Flow (Mermaid)

The diagram below is the mental model: one JSON profile per customer folder drives one generator run, which always writes the same three output locations. Your CI can run the script to ensure headers match JSON.

flowchart LR
  subgraph cfg["Configuration"]
    J["network_config.json"]
  end
  subgraph gen["Generation"]
    P["generate_network_service.py\n--customer X"]
  end
  subgraph out["Outputs"]
    H["Cus_Network_Config.h"]
    C["Cus_Network_Config.c"]
    R["NetworkService_Config.h"]
  end
  J --> P
  P --> H
  P --> C
  P --> R
              

Runtime Sequence

After linking, startup is linear. appNetworkServiceStart() first initializes the selected TCP/IP stack through the macro that points at your stack’s init function (for example appCycloneTcpIpStackInit or appLinuxTcpIpStackInit). The service then waits about one second so the stack can settle. Finally it calls networkServiceStartInterfaces(), which walks every active Ethernet manager start function, then every active PPP manager start function, combining status with bitwise OR so a partial failure is still visible in the return value.

sequenceDiagram
  participant App as AppNetworkService
  participant Init as networkServiceInitTCPIPStack
  participant Stack as NET_STACK_STACK_INIT_FUNCTION
  participant Start as networkServiceStartInterfaces
  participant Eth as ETH*_START
  participant Ppp as PPP*_START
  App->>Init: appNetworkServiceStart
  Init->>Stack: stack init
  Note over App: delay ~1s
  App->>Start: start interfaces
  Start->>Eth: Ethernet in order
  Start->>Ppp: PPP/GSM in order
              

Include Chain

The application never includes a long path into Customers/LinuxGcc/... directly. It includes NetworkService_Config.h, which is regenerated to point at the active customer’s Cus_Network_Config.h. That header in turn pulls in the stack’s public API header and each interface manager header listed in JSON, so the compiler sees the same symbols the macros reference.

flowchart TB
  A["AppNetworkService.c"] --> B["Customers/NetworkService_Config.h"]
  B --> C["Customers<customer>/Network/Cus_Network_Config.h"]
  C --> D["Stack header\ne.g. AppCycloneStack.h"]
  C --> E["Interface headers\nAppCycloneEthMng.h ..."]
              

Animated Overview (Four GIFs)

The following loops are produced by docs/network/generate_network_docs_gifs.py (requires Pillow). They are intentionally small so four of them fit in a 2×2 grid: top row shows the generator pipeline and runtime; bottom row shows the include chain and the JSON selection rules. Re-run the script after editing the Python drawer if you change the storyboard.

Generator reads JSON and emits three files

Generator Pipeline. Customer network_config.json is the single source of truth. The script emits the customer Cus_Network_Config.h and .c plus the root NetworkService_Config.h bridge.

Runtime init then interface start

Runtime. Stack initialization runs first, then a short delay, then networkServiceStartInterfaces() invokes each active Ethernet and PPP start macro in order.

Include chain from app to customer macros

Include Chain. Application code includes one stable header; that header forwards to the generated customer header that carries stack and interface macros.

First use true stack and interface filtering

Selection Rules. Only the first stack with use: true is used. Within it, only interface entries with use: true are expanded; Ethernet is ordered before PPP.

Generated C Sketch

The exact macro names depend on how many Ethernet and PPP links are active. With one of each, the .c file looks like the fragment below. With multiple links, prefixes become ETH0_, ETH1_, PPP0_, etc., matching the order in JSON.

Typical Cus_Network_Config.c Body

RETURN_STATUS networkServiceInitTCPIPStack(void)
{
    return NET_STACK_STACK_INIT_FUNCTION();
}

RETURN_STATUS networkServiceStartInterfaces(void)
{
    RETURN_STATUS retVal = SUCCESS;
    retVal |= ETH_APP_MANAGER_START_FUNCTION();
    retVal |= PPP_APP_MANAGER_START_FUNCTION();
    return retVal;
}

For field-by-field JSON reference and multi-interface naming, see JSON Configuration. For stack-specific source layout, use the sidebar links for CycloneTcp, Linux, or lwIP.