Skip to main content

OEM Resources

OEM resources provide Firefly extended KVM/ADB, VNC, WebTTY, and alert notification capabilities.

Plain HTTP requests on this page support HTTP Basic Auth and session tokens. The token is carried in the `X-Xsrf-Token` request header. WebSocket connections also use the `X-Xsrf-Token` request header. In the examples, replace `` with `http` or `https` according to the service configuration.

1 Remote Management Resources

1.1 Query the ADB Device List

Queries the devices currently connected via USB or network ADB.

ItemContent
MethodGET
Path/redfish/v1/Oem/KvmServices
AuthenticationHTTP Basic Auth or X-Xsrf-Token
Request bodyNone
Basic Auth Token ```bash title="Query the ADB Device List" curl --user ':' \ --header 'Accept: application/json' \ --max-time 20 \ '://:/redfish/v1/Oem/KvmServices' ``` ```bash title="Query the ADB Device List with a Token" curl --header 'X-Xsrf-Token: ' \ --header 'Accept: application/json' \ --max-time 20 \ '://:/redfish/v1/Oem/KvmServices' ```

Success Response Structure

The following structure is returned when the backend successfully retrieves ADB devices:

200 OK · Backend Response Structure
{
"@odata.type": "#Oem.v1_0_2.FireflyKvmService.DeviceList",
"Oem": {
"Firefly": {
"DeviceList": []
}
},
"Name": "FireflyKvmService.DeviceList",
"Id": "FireflyKvmService.DeviceList",
"@odata.id": "/redfish/v1/Oem/KvmServices"
}

Response Fields

FieldTypeDescription
@odata.typestringOEM type of the ADB device list.
OemobjectOEM extension information.
Oem.FireflyobjectFirefly KVM extension information.
Oem.Firefly.DeviceListarrayADB device list. The specific device fields are returned by the current ADB implementation.
NamestringResource name.
IdstringResource identifier.
@odata.idstringPath of the current resource.
On-device requests did not return any response within 20 seconds and curl reported a timeout. This interface synchronously waits for the ADB device scan; callers should set a client timeout and handle "no devices found" and "ADB service not responding" as separate cases.

1.2 Remote Management WebSocket

Establishes an Android device screen-casting session via WebSocket. After the connection succeeds, the server first sends the device display and video encoding capabilities, the client then submits screen-casting parameters, and afterwards video data is continuously received as binary WebSocket messages.

ItemContent
MethodGET + WebSocket Upgrade
Path/redfish/v1/Oem/KvmServices/ws
AuthenticationX-Xsrf-Token
Query parameterudid, the unique identifier of the Android device
Success status code101 Switching Protocols
Transferred contentJSON negotiation messages, binary video frames, and control messages
When the BMC uses HTTP, connect via `ws://`; when it uses HTTPS, connect via `wss://`. This interface does not return an ordinary `200 OK` JSON response.

Connection Example

HTTP / WS HTTPS / WSS ```bash title="Establish an Android Screen-Casting Connection" websocat \ --header 'X-Xsrf-Token: ' \ 'ws://:/redfish/v1/Oem/KvmServices/ws?udid=' ``` ```bash title="Establish an Encrypted Android Screen-Casting Connection" websocat \ --header 'X-Xsrf-Token: ' \ 'wss://:/redfish/v1/Oem/KvmServices/ws?udid=' ```

The udid should be a valid device identifier returned by "1.1 Query the ADB Device List". If udid is not passed in the URL, the server remains compatible with legacy clients: after the WebSocket connection is established, send the following JSON as the first text message.

Legacy Client Device Selection Message
{
"udid": "<device-udid>"
}

Connection Flow

  1. The client initiates a WebSocket Upgrade request with a valid udid.
  2. The server looks up the Android device and reads the device name, resolution, display, and encoder information.
  3. The server sends a JSON text message informing the client of the available video capabilities.
  4. The new client sends a setting message to select the bitrate, frame rate, resolution, display, and encoder.
  5. The server starts the scrcpy session and continuously sends binary video data; the client may simultaneously send control messages such as touch events.

Video Capability Message

The following is an example structure of the server's first text message. The device name, resolution, and encoder list depend on the actual Android device.

WebSocket Text Message · Structure Example
{
"deviceName": "<android-device-name>",
"displayInfo": {
"displayId": 0,
"width": 1080,
"height": 1920,
"rotation": 0,
"layerStack": 0
},
"connectionCount": 0,
"screenInfo": {
"left": 0,
"top": 0,
"right": 0,
"bottom": 0,
"width": 1080,
"height": 1920,
"deviceRotation": 0
},
"videoSettings": {
"video": true,
"bitrate": 0,
"maxFps": 0,
"width": 0,
"height": 0,
"left": 0,
"top": 0,
"right": 0,
"bottom": 0,
"displayId": 0,
"encoderName": "",
"codecOptions": "",
"iFrameInterval": 0,
"sendFrameMeta": false,
"lockedVideoOrientation": 0,
"videoBuffer": 0,
"control": true,
"audio": false
},
"encoders": [
"<encoder-name>"
],
"clientId": 1
}
FieldTypeDescription
deviceNamestringAndroid device product name.
displayInfoobjectCurrent display information.
displayInfo.displayIdintegerAndroid display number.
displayInfo.widthintegerDisplay width in pixels.
displayInfo.heightintegerDisplay height in pixels.
displayInfo.rotationintegerDisplay rotation angle.
displayInfo.layerStackintegerAndroid display layer stack identifier.
connectionCountintegerCurrent number of connections.
screenInfoobjectCurrent screen region and rotation information.
screenInfo.leftintegerLeft boundary of the screen region.
screenInfo.topintegerTop boundary of the screen region.
screenInfo.rightintegerRight boundary of the screen region.
screenInfo.bottomintegerBottom boundary of the screen region.
screenInfo.widthintegerScreen width in pixels.
screenInfo.heightintegerScreen height in pixels.
screenInfo.deviceRotationintegerDevice screen rotation angle.
videoSettingsobjectInitial video configuration suggested by the server.
videoSettings.videobooleanWhether video transmission is enabled.
videoSettings.bitrateintegerVideo bitrate in bit/s; may be 0 in the initial capability message.
videoSettings.maxFpsintegerMaximum video frame rate; may be 0 in the initial capability message.
videoSettings.widthintegerTarget video width in pixels.
videoSettings.heightintegerTarget video height in pixels.
videoSettings.leftintegerLeft boundary of the video crop region.
videoSettings.topintegerTop boundary of the video crop region.
videoSettings.rightintegerRight boundary of the video crop region.
videoSettings.bottomintegerBottom boundary of the video crop region.
videoSettings.displayIdintegerAndroid display number.
videoSettings.encoderNamestringName of the selected video encoder.
videoSettings.codecOptionsstringAdditional options passed to the video encoder.
videoSettings.iFrameIntervalintegerKeyframe interval.
videoSettings.sendFrameMetabooleanWhether video frame metadata is transmitted.
videoSettings.lockedVideoOrientationintegerLocked video orientation.
videoSettings.videoBufferintegerVideo buffer configuration.
videoSettings.controlbooleanWhether remote control is enabled.
videoSettings.audiobooleanWhether audio transmission is enabled.
encodersarrayList of video encoder names supported by the current device.
clientIdintegerIdentifier of the current WebSocket client.

Client Setting Message

After receiving the video capability message, the new client should send a setting JSON text message.

WebSocket Text Message
{
"type": "setting",
"data": {
"bitrate": 4000000,
"maxFps": 24,
"bounds": {
"width": 720,
"height": 1280
},
"displayId": 0,
"control": true,
"audio": false,
"video": true,
"encoderName": "<encoder-name>",
"codecOptions": ""
}
}
FieldTypeDescription
typestringMessage type, fixed as setting.
data.bitrateintegerVideo bitrate in bit/s.
data.maxFpsintegerMaximum video frame rate.
data.bounds.widthintegerOutput video width in pixels.
data.bounds.heightintegerOutput video height in pixels.
data.displayIdintegerAndroid display number to cast.
data.controlbooleanWhether remote control is enabled.
data.audiobooleanWhether audio transmission is enabled.
data.videobooleanWhether video transmission is enabled.
data.encoderNamestringVideo encoder name, which should be selected from the encoders returned by the server.
data.codecOptionsstringAdditional options passed to the scrcpy video encoder; pass an empty string when there are no additional options.

Video and Control Messages

  • The server continuously sends video data as binary WebSocket messages; the client must handle it as a scrcpy video stream and must not parse it as JSON.
  • The client may send scrcpy binary control packets, or compatible JSON text touch messages.
  • The pong text message is used for client keep-alive; the server does not forward it to the Android device after receiving it.
Touch Control Message
{
"messageType": "touch",
"data": {
"actionType": 0,
"x": 416,
"y": 243,
"width": 1080,
"height": 1920
}
}
FieldTypeDescription
messageTypestringMessage type. touch for touch events, pong for keep-alive messages.
data.actionTypeintegerTouch action: 0 means press down, 1 means release, 2 means move.
data.xintegerX coordinate of the touch point.
data.yintegerY coordinate of the touch point.
data.widthintegerWidth of the coordinate system; must be greater than 0 and no more than 65535.
data.heightintegerHeight of the coordinate system; must be greater than 0 and no more than 65535.

Error Messages

When the WebSocket Upgrade has succeeded but a later initialization step fails, the server sends a JSON string and then closes the connection.

MessageDescription
"udid is empty"The legacy handshake message did not provide a valid udid.
"device not found"No Android device matching the udid was found.
"scrcpy option list failed"Failed to read the device's scrcpy encoder or display information.
"scrcpy client create failed"Failed to create the scrcpy session.
"scrcpy client start failed"Failed to start the scrcpy session.

2 Alert Management Resources

2.1 Query SMTP Configuration

ItemContent
MethodGET
Path/redfish/v1/Oem/Alert/GetSMTPServer
AuthenticationHTTP Basic Auth or X-Xsrf-Token
Required privilegeOemDebug
Success status code200 OK
Basic Auth Token ```bash title="Query SMTP Configuration" curl --user ':' \ --header 'Accept: application/json' \ '://:/redfish/v1/Oem/Alert/GetSMTPServer' ``` ```bash title="Query SMTP Configuration with a Token" curl --header 'X-Xsrf-Token: ' \ --header 'Accept: application/json' \ '://:/redfish/v1/Oem/Alert/GetSMTPServer' ```

Response Example

200 OK
{
"@odata.id": "/redfish/v1/Oem/Alert/GetSMTPServer",
"enable": false,
"mail_addr": "",
"smtp_addr": "",
"smtp_port": 0
}

Response Fields

FieldTypeDescription
@odata.idstringPath of the SMTP configuration resource.
enablebooleanWhether email sending is enabled.
mail_addrstringSender email account.
smtp_addrstringSMTP server address.
smtp_portintegerSMTP server port.
The query interface does not return `mail_auth`, so the current SMTP configuration cannot be fully reconstructed from the GET response alone. The authorization code must be confirmed separately before writing the original values back.

2.2 Set SMTP Configuration

ItemContent
MethodPOST
Path/redfish/v1/Oem/Alert/SetSMTPServer
Required privilegeOemDebug
Success status code200 OK
Request FieldsTypeRequiredDescription
mail_addrstringYesSender email account.
mail_authstringYesSMTP authorization code or application password.
smtp_addrstringYesSMTP server domain name or address.
smtp_portintegerYesSMTP server port.
enablebooleanYesWhether email alerts are enabled.
Set SMTP Configuration with a Token
curl --request POST \
--header 'X-Xsrf-Token: <token>' \
--header 'Content-Type: application/json' \
--data '{
"mail_addr": "sender@example.com",
"mail_auth": "<smtp-authorization-code>",
"smtp_addr": "smtp.example.com",
"smtp_port": 465,
"enable": true
}' \
'<protocol>://<device-ip>:<port>/redfish/v1/Oem/Alert/SetSMTPServer'

This interface replaces the sender configuration as a whole and writes it to the database; it was not executed this time.

Response Example

200 OK
{
"@odata.type": "#Message.v1_1_1.Message",
"Timestamp": "1785836138",
"MessageId": "Base.1.11.0.Success",
"Message": "The request completed successfully.",
"MessageArgs": [],
"MessageSeverity": "OK",
"Severity": "",
"Oem": null,
"RelatedProperties": null,
"Resolution": "None"
}

Response Fields

FieldTypeDescription
@odata.typestringOData type of the Redfish message resource.
TimestampstringServer response timestamp.
MessageIdstringSuccess message identifier.
MessagestringRequest processing result.
MessageArgsarrayMessage formatting arguments.
MessageSeveritystringMessage severity level.
SeveritystringSeverity field retained for compatibility.
Oemobject | nullOEM extension message.
RelatedPropertiesarray | nullRelated property paths.
ResolutionstringSuggested resolution.

2.3 Send a Test Email

ItemContent
MethodPOST
Path/redfish/v1/Oem/Alert/SendMsg
Required privilegeOemDebug
PrerequisitesValid SMTP configuration and network access to the SMTP server
Request FieldsTypeRequiredDescription
tostring[]YesRecipient list.
ccstring[]NoCC list.
bccstring[]NoBCC list.
subjectstringYesEmail subject.
msgstringYesEmail body.
msg_formatstringYesMIME type of the body, for example text/plain or text/html.
Request Body Example
{
"to": ["receiver@example.com"],
"subject": "BMC alert test",
"msg": "This is a test message.",
"msg_format": "text/plain"
}

This operation actually sends an email to an external mailbox; it was not executed this time.

Response Example

200 OK
{
"@odata.type": "#Message.v1_1_1.Message",
"Timestamp": "1785836138",
"MessageId": "Base.1.11.0.Success",
"Message": "The request completed successfully.",
"MessageArgs": [],
"MessageSeverity": "OK",
"Severity": "",
"Oem": null,
"RelatedProperties": null,
"Resolution": "None"
}

Response Fields

FieldTypeDescription
@odata.typestringOData type of the Redfish message resource.
TimestampstringServer response timestamp.
MessageIdstringSuccess message identifier.
MessagestringRequest processing result.
MessageArgsarrayMessage formatting arguments.
MessageSeveritystringMessage severity level.
SeveritystringSeverity field retained for compatibility.
Oemobject | nullOEM extension message.
RelatedPropertiesarray | nullRelated property paths.
ResolutionstringSuggested resolution.

2.4 Query Alert Receivers

ItemContent
MethodGET
Path/redfish/v1/Oem/Alert/GetReceivers
AuthenticationHTTP Basic Auth or X-Xsrf-Token
Required privilegeOemDebug
Success status code200 OK
Basic Auth Token ```bash title="Query Alert Receivers" curl --user ':' \ --header 'Accept: application/json' \ '://:/redfish/v1/Oem/Alert/GetReceivers' ``` ```bash title="Query Alert Receivers with a Token" curl --header 'X-Xsrf-Token: ' \ --header 'Accept: application/json' \ '://:/redfish/v1/Oem/Alert/GetReceivers' ```

Response Example

200 OK
{
"@odata.id": "/redfish/v1/Oem/Alert/GetReceivers",
"Receivers": {}
}

Response Fields

FieldTypeDescription
@odata.idstringPath of the alert receiver resource.
ReceiversobjectReceiver map keyed by receiver name.
Receivers.{name}.NamestringReceiver name.
Receivers.{name}.WayintegerNotification channel combination code, ranging from 1 to 8.
Receivers.{name}.SeveritystringSeverity level of alerts received.
Receivers.{name}.MailstringEmail address.
Receivers.{name}.EnterpriseWechatstringWeCom (Enterprise WeChat) robot webhook.
Receivers.{name}.DingTalkstringDingTalk robot webhook.

2.5 Add or Modify an Alert Receiver

OperationMethodPath
Add a receiverPOST/redfish/v1/Oem/Alert/AddReceivers
Modify a receiverPOST/redfish/v1/Oem/Alert/SetReceivers

Both interfaces use the same request structure.

Request FieldsTypeRequiredDescription
NamestringYesUnique receiver name. The modify interface uses this field to locate or create the record.
WayintegerYesChannel combination: 1 no notification, 2 email, 3 WeCom, 4 DingTalk, 5 email + WeCom, 6 email + DingTalk, 7 WeCom + DingTalk, 8 all.
SeveritystringYesSeverity level of alerts received.
MailstringConditionally requiredFill in when the email channel is used.
EnterpriseWechatstringConditionally requiredFill in the webhook when the WeCom channel is used.
DingTalkstringConditionally requiredFill in the webhook when the DingTalk channel is used.
Request Body Example
{
"Name": "operations-team",
"Way": 2,
"Severity": "Critical",
"Mail": "operations@example.com",
"EnterpriseWechat": "",
"DingTalk": ""
}

The backend rejects duplicate names, as well as email addresses or robot webhooks that duplicate those of other receivers. No receivers were modified this time.

Response Example

Both add and modify return the following on success:

200 OK
{
"@odata.type": "#Message.v1_1_1.Message",
"Timestamp": "1785836138",
"MessageId": "Base.1.11.0.Success",
"Message": "The request completed successfully.",
"MessageArgs": [],
"MessageSeverity": "OK",
"Severity": "",
"Oem": null,
"RelatedProperties": null,
"Resolution": "None"
}

Response Fields

FieldTypeDescription
@odata.typestringOData type of the Redfish message resource.
TimestampstringServer response timestamp.
MessageIdstringSuccess message identifier.
MessagestringRequest processing result.
MessageArgsarrayMessage formatting arguments.
MessageSeveritystringMessage severity level.
SeveritystringSeverity field retained for compatibility.
Oemobject | nullOEM extension message.
RelatedPropertiesarray | nullRelated property paths.
ResolutionstringSuggested resolution.

2.6 Delete an Alert Receiver

ItemContent
MethodPOST
Path/redfish/v1/Oem/Alert/DelReceivers
Request fieldsName, string, required
Success status code200 OK
Request Body Example
{
"Name": "operations-team"
}

If the receiver does not exist, a generic Redfish error is returned. This operation permanently deletes the receiver configuration; it was not executed this time.

Response Example

200 OK
{
"@odata.type": "#Message.v1_1_1.Message",
"Timestamp": "1785836138",
"MessageId": "Base.1.11.0.Success",
"Message": "The request completed successfully.",
"MessageArgs": [],
"MessageSeverity": "OK",
"Severity": "",
"Oem": null,
"RelatedProperties": null,
"Resolution": "None"
}

Response Fields

FieldTypeDescription
@odata.typestringOData type of the Redfish message resource.
TimestampstringServer response timestamp.
MessageIdstringSuccess message identifier.
MessagestringRequest processing result.
MessageArgsarrayMessage formatting arguments.
MessageSeveritystringMessage severity level.
SeveritystringSeverity field retained for compatibility.
Oemobject | nullOEM extension message.
RelatedPropertiesarray | nullRelated property paths.
ResolutionstringSuggested resolution.

2.7 Test an Alert Receiver

Triggers a test notification for one or more existing receivers.

ItemContent
MethodPOST
Path/redfish/v1/Oem/Alert/Test
Request bodyArray of receiver name objects
Success status code200 OK
Request Body Example
[
{ "Name": "operations-team" }
]

The interface asynchronously invokes the email, WeCom, or DingTalk channels configured for the receivers, which may generate real external notifications; it was not executed this time.

Response Example

200 OK
{
"@odata.type": "#Message.v1_1_1.Message",
"Timestamp": "1785836138",
"MessageId": "Base.1.11.0.Success",
"Message": "The request completed successfully.",
"MessageArgs": [],
"MessageSeverity": "OK",
"Severity": "",
"Oem": null,
"RelatedProperties": null,
"Resolution": "None"
}

Response Fields

FieldTypeDescription
@odata.typestringOData type of the Redfish message resource.
TimestampstringServer response timestamp.
MessageIdstringSuccess message identifier.
MessagestringRequest processing result.
MessageArgsarrayMessage formatting arguments.
MessageSeveritystringMessage severity level.
SeveritystringSeverity field retained for compatibility.
Oemobject | nullOEM extension message.
RelatedPropertiesarray | nullRelated property paths.
ResolutionstringSuggested resolution.