[{"data":1,"prerenderedAt":33},["ShallowReactive",2],{"project-plugin-hostd-protocol-":3},{"page":4,"others":29},{"slug":5,"src":6,"title":7,"source":8,"toc":9,"html":28},"","README.md","plugin-hostd-protocol","https:\u002F\u002Fgithub.com\u002FFreeMixer\u002Fplugin-hostd-protocol\u002Fblob\u002F5e12b959fa098ee4800a4a8485d5c6ce1ffada2c\u002FREADME.md",[10,13,16,19,22,25],{"id":11,"title":12},"use-it","Use it",{"id":14,"title":15},"the-declared-protocol","The declared protocol",{"id":17,"title":18},"build-and-test","Build and test",{"id":20,"title":21},"what-differs-from-mod-host","What differs from mod-host",{"id":23,"title":24},"credit","Credit",{"id":26,"title":27},"licence","Licence","\u003Ch1 id=\"plugin-hostd-protocol\">plugin-hostd-protocol\u003C\u002Fh1>\n\u003Cp>The plugin-hostd protocol, a superset of mod-host's text protocol: any mod-host client works unchanged.\u003C\u002Fp>\n\u003Cp>\u003Ccode>libplugin-hostd-protocol\u003C\u002Fcode> is the socket server, the line protocol and the command dispatch that plugin-hostd and\nomx-clap-host answer their controllers with. A host registers a backend (\u003Ccode>host_backend_t\u003C\u002Fcode>) and the library does the\nrest: it listens on the command and feedback ports, splits the input into NUL-terminated commands, parses them against\nthe command table and answers \u003Ccode>resp &lt;status&gt; [value]\u003C\u002Fcode>, as mod-host does.\u003C\u002Fp>\n\u003Cp>The library answers mod-host's commands as mod-host does, byte for byte, with two bugs fixed (below). Since 0.2 it also\nholds the whole declared protocol: the verbs plugin-hostd and omx-clap-host add, their replies and refusals, the\nevents, and the one verb table and the grammar written from them (below and \u003Ca href=\"\u002Fprojects\u002Fplugin-hostd-protocol\u002Fprotocol\">doc\u002Fprotocol.md\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch2 id=\"use-it\">Use it\u003C\u002Fh2>\n\u003Cpre>\u003Ccode>pkg-config --cflags --libs plugin-hostd-protocol\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>The headers are installed under \u003Ccode>&lt;includedir&gt;\u002Fplugin-hostd-protocol\u002F\u003C\u002Fcode> with the names and the API of\n\u003Ccode>libmod-host-protocol\u003C\u002Fcode> (\u003Ccode>protocol.h\u003C\u002Fcode>, \u003Ccode>socket.h\u003C\u002Fcode>, \u003Ccode>host-dispatch.h\u003C\u002Fcode>, \u003Ccode>host-backend.h\u003C\u002Fcode>, \u003Ccode>host-errors.h\u003C\u002Fcode>,\n\u003Ccode>host-scenario.h\u003C\u002Fcode>, \u003Ccode>mod-host.h\u003C\u002Fcode>, \u003Ccode>utils.h\u003C\u002Fcode>), so a program built against \u003Ccode>mod-host-protocol\u003C\u002Fcode> changes only the package\nname it asks pkg-config for. The scenario corpus every host is tested with, the source of its runner and the protocol\npage are installed too: \u003Ccode>pkg-config --variable=scenarios\u003C\u002Fcode> (\u003Ccode>runner\u003C\u002Fcode>, \u003Ccode>protocoldoc\u003C\u002Fcode>) \u003Ccode>plugin-hostd-protocol\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>The commands and the error codes: \u003Ca href=\"\u002Fprojects\u002Fplugin-hostd-protocol\u002Fprotocol\">doc\u002Fprotocol.md\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2 id=\"the-declared-protocol\">The declared protocol\u003C\u002Fh2>\n\u003Cp>What plugin-hostd declares of the protocol is installed with the development package, so no consumer keeps a copy:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>&lt;plugin-hostd\u002Fprotocol.h&gt;\u003C\u002Fcode> (under \u003Ccode>&lt;includedir&gt;\u002Fplugin-hostd-protocol\u002F\u003C\u002Fcode>, found with this package's Cflags): the\nverbs, the placement, the reply codes, the events, the host verb table and the settings, with the headers omx-contract\nrenders from \u003Ccode>data\u002Fverbs.json\u003C\u002Fcode> (\u003Ccode>plugin_hostd_protocol_host_verbs.h\u003C\u002Fcode>, \u003Ccode>plugin_hostd_protocol_vocabulary.h\u003C\u002Fcode>) and from\nomx-clap-core's package of the contract directory (\u003Ccode>omx_clap_core_host_verbs.h\u003C\u002Fcode>, \u003Ccode>omx_clap_core_vocabulary.h\u003C\u002Fcode>);\u003C\u002Fli>\n\u003Cli>the one verb table, \u003Ccode>plugin-hostd-protocol.json\u003C\u002Fcode>: every command, each once, with its origin (mod-host, plugin-hostd or\nomx-clap-core), its argument types, its reply and its refusals, and every feedback line\n(\u003Ccode>pkg-config --variable=table plugin-hostd-protocol\u003C\u002Fcode>);\u003C\u002Fli>\n\u003Cli>the grammar of a line, in ABNF, generated from that table (\u003Ccode>--variable=grammar\u003C\u002Fcode>);\u003C\u002Fli>\n\u003Cli>\u003Ccode>plugin-hostd.json\u003C\u002Fcode>, what \u003Ccode>protocol.h\u003C\u002Fcode> declares as JSON, and its schema (\u003Ccode>--variable=protocoljson\u003C\u002Fcode>,\n\u003Ccode>--variable=protocolschema\u003C\u002Fcode>), and \u003Ccode>mod-host.json\u003C\u002Fcode>, mod-host's commands and codes (\u003Ccode>--variable=modhostjson\u003C\u002Fcode>);\u003C\u002Fli>\n\u003Cli>the source of the generator of \u003Ccode>plugin-hostd.json\u003C\u002Fcode> (\u003Ccode>--variable=protocolgen\u003C\u002Fcode>), for a consumer that checks its own\npages against a changed copy of the headers;\u003C\u002Fli>\n\u003Cli>\u003Ccode>data\u002Fverbs.json\u003C\u002Fcode>, as the package plugin-hostd-protocol of omx-contract's contract directory\n(\u003Ccode>plugin-hostd-protocol-contract\u003C\u002Fcode>).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Every one is written from the declarations by a tool of \u003Ccode>tools\u002F\u003C\u002Fcode>, and \u003Ccode>make check-generated\u003C\u002Fcode> fails when one is not what\nits tool writes. A word added to the protocol never changes a mod-host word: \u003Ccode>tools\u002Fprotocol-table.py\u003C\u002Fcode> refuses to write\nthe table when a verb of another origin neither extends mod-host's command of the same word nor is a second form of it\ntold apart by its number of arguments (\u003Ccode>preset_show &lt;uri&gt;\u003C\u002Fcode> is mod-host's, \u003Ccode>preset_show &lt;instance&gt; &lt;key&gt;\u003C\u002Fcode> plugin-hostd's).\nThere is no list of exceptions.\u003C\u002Fp>\n\u003Cp>What each host profile owes each verb a controller sends:\u003C\u002Fp>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>verb\u003C\u002Fth>\n\u003Cth>sent by\u003C\u002Fth>\n\u003Cth>lv2-worker\u003C\u002Fth>\n\u003Cth>clap-worker\u003C\u002Fth>\n\u003Cth>console\u003C\u002Fth>\n\u003Cth>zynthian\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>add\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>remove\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>bypass\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>connect\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>param_set\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>state_load\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>state_save\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>state_tmpdir\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>feature_enable\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>bundle_add\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>bundle_remove\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>preset_load\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>preset_save\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>preset_show\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>transport\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>transport_sync\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cpu_load\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>midi_learn\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>midi_map\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>midi_unmap\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cv_map\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cv_unmap\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>monitor_midi_program\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>monitor_output\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>output_data_ready\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>patch_get\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>patch_set\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cc_map\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cc_value_set\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cc_unmap\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>hmi_map\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>hmi_unmap\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>show_external_ui\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>set_midi_program_change_pedalboard_bank_channel\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>set_midi_program_change_pedalboard_snapshot_channel\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-ui\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003Ctd>absent\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>disconnect\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>set_bpm\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>set_bpb\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quit\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>param_get\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>param_monitor\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>licensee\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>monitor\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>load\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>save\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>help\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>track_info\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>remote_pages\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>remote_page_get\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>param_info\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>mod-host\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>preset_list\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>preset_get\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>note_input\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>note_on\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>note_off\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>all_notes_off\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003Ctd>optional\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>worker_list\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>instance_info\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>supervisor_reset\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quarantine_clear\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>policy_set\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>pool_config\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>worker_env\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>pin_set\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>pin_clear\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>pin_accept\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>pin_reload\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>pin_changed\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>lv2_worker_set\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>chain\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>chain_clear\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>chain_get\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>plan\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>plan_get\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>plan_clear\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>descriptor_get\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>panel_get\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>history_get\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>history_clear\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>estimate\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>daemon\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003Ctd>required\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>The profiles: \u003Ccode>lv2-worker\u003C\u002Fcode>, an LV2 plugin's worker: mod-host, or omx-clap-host's LV2 adapter; \u003Ccode>clap-worker\u003C\u002Fcode>, a CLAP plugin's worker, omx-clap-host; \u003Ccode>console\u003C\u002Fcode>, the openmixer console as a controller of the daemon; \u003Ccode>zynthian\u003C\u002Fcode>, Zynthian's mod-ui and its plugind engine as a controller of the daemon. \u003Ccode>required\u003C\u002Fcode> is answered as its grammar says; \u003Ccode>optional\u003C\u002Fcode> is answered, or refused with -902, and never misread; \u003Ccode>absent\u003C\u002Fcode> is refused on purpose, and no client of the profile may need it.\u003C\u002Fp>\n\u003Cp>Packages: \u003Ccode>plugin-hostd-protocol\u003C\u002Fcode>, \u003Ccode>plugin-hostd-protocol-devel\u003C\u002Fcode> and \u003Ccode>plugin-hostd-protocol-contract\u003C\u002Fcode> (RPM),\n\u003Ccode>libplugin-hostd-protocol0\u003C\u002Fcode>, \u003Ccode>libplugin-hostd-protocol-dev\u003C\u002Fcode> and \u003Ccode>plugin-hostd-protocol-contract\u003C\u002Fcode> (DEB). The library\npackage carries the table, the grammar and the JSON documents a program reads at run time; the development package the\nheaders, the schema, the scenario corpus and its runner, the protocol page and the generator's source.\u003C\u002Fp>\n\u003Ch2 id=\"build-and-test\">Build and test\u003C\u002Fh2>\n\u003Cpre>\u003Ccode>make\nmake test\nmake install PREFIX=\u002Fusr LIBDIR=\u002Fusr\u002Flib64\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>make test\u003C\u002Fcode> needs gcc with AddressSanitizer and UndefinedBehaviorSanitizer (libasan, libubsan), python3 and\nomx-contract's C headers (omx-contract-devel, libomx-contract-dev). It runs:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>the protocol, dispatcher and scenario tests over a fake backend (\u003Ccode>test-protocol\u003C\u002Fcode>, \u003Ccode>test-protocol-commands\u003C\u002Fcode>), and the\ninput splitter, NUL framing and bind address tests (\u003Ccode>test-utils\u003C\u002Fcode>, \u003Ccode>test-socket\u003C\u002Fcode>, \u003Ccode>test-bind\u003C\u002Fcode>);\u003C\u002Fli>\n\u003Cli>the golden test (\u003Ccode>test-golden\u003C\u002Fcode>): the scenario corpus and both fuzz seed corpora sent over a real socket, each command\nanswered nine ways by a recording backend, the transcript held byte for byte to \u003Ccode>tests\u002Fgolden\u002Fplugin-hostd-protocol.txt\u003C\u002Fcode>;\u003C\u002Fli>\n\u003Cli>the comparison with mod-host (\u003Ccode>test-golden-modhost\u003C\u002Fcode>): every exchange of \u003Ccode>tests\u002Fgolden\u002Fmod-host-protocol.txt\u003C\u002Fcode>, the\nsame transcript taken from libmod-host-protocol 0.10.6-11.3, is the same in ours, except the ones\n\u003Ccode>tests\u002Fgolden\u002Fdeviations.txt\u003C\u002Fcode> names, which must differ. \u003Ccode>make golden-modhost MODHOST_PREFIX=&lt;dir&gt;\u003C\u002Fcode> takes it again\nfrom a libmod-host-protocol installed there;\u003C\u002Fli>\n\u003Cli>the fixes below (\u003Ccode>test-fixes\u003C\u002Fcode>), and each fix taken out again, which must fail (\u003Ccode>test-fixes-sabotage\u003C\u002Fcode>);\u003C\u002Fli>\n\u003Cli>the installed library as a consumer meets it (\u003Ccode>test-install\u003C\u002Fcode>), the exported symbols (\u003Ccode>test-abi\u003C\u002Fcode>, the list of\nlibmod-host-protocol.so.0) and the version (\u003Ccode>version-check\u003C\u002Fcode>);\u003C\u002Fli>\n\u003Cli>the declared protocol: every generated file is what its tool writes from the declarations (\u003Ccode>check-generated\u003C\u002Fcode>,\n\u003Ccode>check-protocol-doc\u003C\u002Fcode>; \u003Ccode>make gen\u003C\u002Fcode> writes them), the host verb table covers every verb (\u003Ccode>test-verb-table\u003C\u002Fcode>),\n\u003Ccode>mod-host.json\u003C\u002Fcode> follows its headers (\u003Ccode>test-mod-host-json\u003C\u002Fcode>), and each generated file edited by hand, or each\ndeclaration changed without writing them again, turns those checks red (\u003Ccode>test-generated-sabotage\u003C\u002Fcode>), and so does each\nrule of the host verb table broken in a scratch copy of the header.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Ccode>make check-protocol-tools\u003C\u002Fcode> runs what needs tools a package build does not carry, as CI does: the rendered headers\nagainst the installed omx-contract and omx-clap-core-contract (\u003Ccode>check-rendered\u003C\u002Fcode>, and \u003Ccode>test-rendered-sabotage\u003C\u002Fcode>), the\nstaged contract package (\u003Ccode>check-contract-dir\u003C\u002Fcode>), the JSON against its schema (\u003Ccode>check-schema\u003C\u002Fcode>, python3-jsonschema), and\nthe grammar against the scenario corpus, the golden transcript and the table (\u003Ccode>test-grammar\u003C\u002Fcode>, python's \u003Ccode>abnf\u003C\u002Fcode> module,\n\u003Ccode>PYTHON=&lt;an interpreter that has it&gt;\u003C\u002Fcode>), each with its sabotage.\u003C\u002Fp>\n\u003Cp>\u003Ccode>make fuzz\u003C\u002Fcode> and \u003Ccode>make fuzz-run\u003C\u002Fcode> build and run the libFuzzer harnesses with clang (\u003Ca href=\"https:\u002F\u002Fgithub.com\u002FFreeMixer\u002Fplugin-hostd-protocol\u002Fblob\u002F5e12b959fa098ee4800a4a8485d5c6ce1ffada2c\u002Ffuzz\u002FREADME.md\">fuzz\u002FREADME.md\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch2 id=\"what-differs-from-mod-host\">What differs from mod-host\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Ccode>format_number()\u003C\u002Fcode> writes NaN, Infinity and -Infinity, where it wrote past a stack array: \u003Ccode>param_info\u003C\u002Fcode> of a port whose\nrange or default is not finite (plugin-hostd#371).\u003C\u002Fli>\n\u003Cli>\u003Ccode>protocol_parse()\u003C\u002Fcode> runs the callback of the command the message names, and no other: \u003Ccode>zzz %s 5\u003C\u002Fcode> is not found, where\nit ran \u003Ccode>add\u003C\u002Fcode> (plugin-hostd#372).\u003C\u002Fli>\n\u003Cli>A verb may have more than one form, told apart by its number of arguments (\u003Ccode>preset_show &lt;uri&gt;\u003C\u002Fcode> is mod-host's,\n\u003Ccode>preset_show &lt;instance&gt; &lt;key&gt;\u003C\u002Fcode> plugin-hostd's): \u003Ccode>protocol_parse()\u003C\u002Fcode> reads every command registered for the verb and\nruns the first whose arguments fit, in number and then in types (\u003Ccode>%i\u003C\u002Fcode> a whole number, \u003Ccode>%f\u003C\u002Fcode> a number), where it read\nonly the first one registered. A line no form takes is refused as the first form refuses it, so a verb of one form\nanswers as mod-host answers it (\u003Ccode>make test-forms\u003C\u002Fcode>, and \u003Ccode>test-forms-sabotage\u003C\u002Fcode> puts the first-form reading back).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"credit\">Credit\u003C\u002Fh2>\n\u003Cp>The library's code (\u003Ccode>src\u002F\u003C\u002Fcode>, the headers at the top of \u003Ccode>include\u002F\u003C\u002Fcode>) is mod-host's\n(\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmod-audio\u002Fmod-host\">mod-audio\u002Fmod-host\u003C\u002Fa>), by Filipe Coelho, MOD Audio UG and the mod-host\ncontributors, taken from FreeMixer's fork (\u003Ca href=\"https:\u002F\u002Fgithub.com\u002FFreeMixer\u002Fmod-host\">FreeMixer\u002Fmod-host\u003C\u002Fa>, branch\n\u003Ccode>freemixer\u003C\u002Fcode>, 013ac7d): upstream 12335c2 with the pull requests that made it a library (#81, #82, #98, #100, #101, #104\nto #109, #112, #113, #116 and the bind address of FreeMixer\u002Fmod-host#12). The files that come from it keep mod-host's\ncopyright and licence lines. The declared protocol (\u003Ccode>include\u002Fplugin-hostd\u002F\u003C\u002Fcode>, \u003Ccode>data\u002F\u003C\u002Fcode>, \u003Ccode>protocol\u002F\u003C\u002Fcode>, \u003Ccode>grammar\u002F\u003C\u002Fcode>,\n\u003Ccode>tools\u002F\u003C\u002Fcode>) came from plugin-hostd.\u003C\u002Fp>\n\u003Ch2 id=\"licence\">Licence\u003C\u002Fh2>\n\u003Cp>GPL-3.0-or-later, as mod-host: \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FFreeMixer\u002Fplugin-hostd-protocol\u002Fblob\u002F5e12b959fa098ee4800a4a8485d5c6ce1ffada2c\u002FCOPYING\">COPYING\u003C\u002Fa>.\u003C\u002Fp>\n",[30],{"slug":31,"title":32},"protocol","doc\u002Fprotocol.md",1793954996741]