iqengine-plugin 0.0.1

An helper crate to build IQEngine plugin server.
Documentation
openapi: 3.0.0
info:
  title: IQEngine Plugins Open Interface API
  description: |
    The plugins API is a unified open interface for managing the processing of RF recordings and corresponding dataflow,
    with the goal of standardizing inputs and outputs to RF processing functions for easy of interoperability and to combat vendor lockin.
    The plugins API is planned to be converted to an OpenAPI spec once its further refined.  It will use JSON for the fields.
  version: 0.0.1
servers:
  - url: /plugins
paths:
  /:
    get:
      summary: Returns the list of RF Functions available at this ip/host, as a list of strings, must match functionName below.
      responses:
        '200':
          description: 'OK'
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
                minItems: 1
                maxItems: 1000
                uniqueItems: true
  /{functionName}:
    get:
      summary: Gets the RF Function's custom params in the form of a JSON schema that is only 1 layer deep.
      parameters:
        - in: path
          name: functionName
          schema:
            type: string
          required: true
          description: Name of RF Function
      responses:
        '400':
          description: Bad request. RF Function does not exist.
        '200':
          description: 'OK'
          content:
            application/json:
              schema:
                type: object
                required:
                  - custom_params
                properties:
                  max_inputs: # max sets of IQ as input
                    type: integer
                    default: 1 # note that default documents behavior when a field is absent
                    minimum: 0 # a siggen/tx wouldn't have IQ on the input side, only custom params
                  max_outputs: # max sets of IQ as output
                    type: integer
                    default: 1
                    minimum: 0
                  custom_params: # This object is essentially just a json schema that is at most 1 layer deep
                    # e.g.:
                    # {'param1': {'title': 'Param1', 'default': 1,       'type': 'integer'},
                    #  'param2': {'title': 'Param2', 'default': 'test2', 'type': 'string'},
                    #  'param3': {'title': 'Param3', 'default': 5.67,    'type': 'number'}}
                    type: object
                    minProperties: 1
                    maxProperties: 100
                    additionalProperties:
                      type: object
                      properties:
                        title:
                          type: string
                        type:
                          type: string
                          # anyOf:
                          #   # For now this is all we'll support
                          #   - type: string
                          #   - type: number # (float)
                          #   - type: integer
                          #   - type: boolean
                        default:
                            type: string
    post:
      summary: Run the RF Function, using the provided IQ samples and params
      parameters:
        - in: path
          name: functionName
          schema:
            type: string
          required: true
          description: Name of RF Function
      requestBody:
        description: IQ samples and parameters needed to run the RF Function
        required: true
        content:
          application/json:
            schema:
              type: object
              # Provide either samples (IQ samples) or samples_pointer (pointer to blob storage)
              oneOf:
                - required: [samples_b64]
                - required: [samples_cloud]
              properties:
                samples_b64:
                  type: array # list of IQ samples, most functions will just have 1
                  items:
                    $ref: '#/components/schemas/samples_b64'
                samples_cloud:
                  type: array # list of IQ samples, most functions will just have 1
                  items:
                    $ref: '#/components/schemas/samples_cloud'
                # Custom params
                additionalProperties:
                  anyOf:
                    - type: string
                    - type: number # (float)
                    - type: integer
                    - type: boolean
      responses:
        '400':
          description: Bad request. RF Function does not exist.
          content:
            application/json:
              schema:
                type: object
                properties:
                  details:
                    type: string           
        '401':
          description: Bad request. Missing a required param.
          content:
            application/json:
              schema:
                type: object
                properties:
                  details:
                    type: string 
        '200':
          description: 'OK'
          content:
            application/json:
              schema:
                # The following is taken from SigMF's annotations schema (currently a subset of it)
                type: object
                properties:
                  data_output:
                    type: array # list of IQ samples, most functions will just have 1
                    items:
                      $ref: '#/components/schemas/samples_b64'
                  samples_cloud:
                    type: array # list of IQ samples, most functions will just have 1
                    items:
                      $ref: '#/components/schemas/samples_cloud'
                  annotations:
                    description: See https://github.com/sigmf/SigMF/blob/sigmf-v1.x/sigmf-spec.md#annotations-array
                    type: array
                    items:
                      $ref: '#/components/schemas/annotation'

# A way to specify properties that are reused, or simply too large to have look good within parameters/responses objects
components:
  schemas:
    samples_b64: # samples directly within the JSON request/response
      type: object
      required:
        - samples
        - data_type
      properties:
        samples:
          # IQ samples, as a base64 encoded string, MIME type will indicate the datatype of the underlying bytes
          type: string
          format: byte # base64-encoded characters
        data_type: # uses MIME types, plus custom types we are adding for IQ, based on SigMF
          $ref: '#/components/schemas/data_type'
        sample_rate: # in case sample rate changed
          type: number
          default: 1
        center_freq: # in case center freq changed
          type: number
          default: 0

    samples_cloud: # a pointer to IQ samples in cloud storage
      type: object
      required:
        - account_name
        - container_name
        - file_path
        - data_type
      properties:
        account_name:
          type: string
        container_name:
          type: string
        file_path:
          type: string
        sas_token:
          type: string
        byte_offset:
          type: integer
          default: 0
        byte_length: # default is to grab all of the samples in the file
          type: integer
        data_type:
          $ref: '#/components/schemas/data_type'
        sample_rate:
          type: number
          default: 1
        center_freq:
          type: number
          default: 0

    data_type:
      type: string
      enum:
        - iq/ci8_le # from SigMF
        - iq/ci16_le # from SigMF
        - iq/cf32_le # from SigMF
        - image/png
        - audio/wav
        - application/octet-stream # eg application/octet-stream
        - text/plain # e.g. for representing an ASCII message or speech to text output

    annotation:
      type: object
      required:
        - core:sample_start
        - core:sample_count
      properties:
        core:comment:
          default: ''
          description: A human-readable comment
          type: string
        core:freq_lower_edge:
          description: The frequency (Hz) of the lower edge of the feature described by this annotation.
          type: number
          minimum: -1.7976931348623157E+308
          maximum: 1.7976931348623157E+308
        core:freq_upper_edge:
          description: The frequency (Hz) of the upper edge of the feature described by this annotation.
          type: number
          minimum: -1.7976931348623157E+308
          maximum: 1.7976931348623157E+308
        core:generator:
          description: Human-readable name of the entity that created this annotation.
          type: string
        core:label:
          description: A short form human/machine-readable label for the annotation. CAN BE USED TO LABEL CLASSIFIER OUTPUT
          type: string
        core:sample_count:
          description: The number of samples that this Segment applies to.
          type: integer
          minimum: 0
          maximum: 18446744073709551615
        core:sample_start:
          default: 0
          description: The sample index at which this Segment takes effect
          minimum: 0
          maximum: 18446744073709551615
          type: integer
        core:uuid:
          description: RFC-4122 unique identifier.
          format: uuid
          type: string
      additionalProperties: true