73 Commits
v1.0 ... master

Author SHA1 Message Date
Dmitry Baryshkov
b6c766db1f Merge pull request #88 from krzk/dupa
schema: Allow Fastboot serial numbers up to 16 characters
2025-07-05 16:31:36 +03:00
Krzysztof Kozlowski
031948ff19 schema: Allow Fastboot serial numbers up to 16 characters
WinLink e850 board reports Fastboot ID/serial of "00000b66ce9c23e0" and
fastboot sources [1] allow up to 256 bytes, so grow the pattern to at least
16 characters:

[1] https://android.googlesource.com/platform/system/core/+/refs/heads/android16-release/fastboot/usb.h#54

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
2025-07-05 15:00:58 +02:00
Neil Armstrong
30c30ce84c Merge pull request #86 from lumag/laurent-usb
laurent: add support for controlling USB power
2025-03-18 09:32:35 +01:00
Neil Armstrong
95a40706be Merge pull request #84 from stephan-gh/ftdi-usb1
drivers: ftdi-gpio: Add second USB disconnect GPIO & schema.yaml fixes
2025-03-18 09:28:37 +01:00
Dmitry Baryshkov
4320c482d3 Merge pull request #81 from mwasilew/boot_mode
device_parser: improve error reporting
2025-02-21 19:25:36 +02:00
Dmitry Baryshkov
cdee00d9a4 Merge pull request #83 from stephan-gh/keys
cdba: Add keys to remotely press power or fastboot key
2025-02-21 19:24:42 +02:00
Dmitry Baryshkov
5bade34946 Merge pull request #85 from stephan-gh/local
cdba: Add option to run cdba-server locally without ssh and without timeout
2025-02-21 19:22:50 +02:00
Dmitry Baryshkov
3c1e7cc886 laurent: add separate USB relays support
Extend laurent driver, allowing using a relay to control USB circuits.
For example, the relay might be connected to the DIP switch on RB1 / RB2
boards.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2025-02-21 19:19:45 +02:00
Dmitry Baryshkov
bad935cbf2 device: support PPPS in parallel with the driver's USB control
Don't make PPPS path exclusive to the driver USB control. Allow both to
be used at the same time in case the setup uses both PPPS-hubs and
driver-specific control.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2025-02-21 19:17:01 +02:00
Dmitry Baryshkov
9335390898 cdba-server: don't try opening the board if there is none
If the cdba failed to find the board, don't call device_fastboot_open().

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2025-02-21 19:14:49 +02:00
Stephan Gerhold
b6d70e8b0c cdba: Add option to disable timeout_total when set to 0
If cdba is run with "-t 0", then disable the timeout completely and keep
running until manually interrupted. This is useful for non-shared boards,
e.g. when cdba is just used to power up the board remotely and you then SSH
into a standard Linux distro installed on the board.
2025-02-14 13:58:26 +01:00
Stephan Gerhold
06531f3db1 cdba: Add option to run cdba-server locally without ssh
cdba is mainly intended for remote usage, but it also works well for
controlling devices that you just need occasionally and then directly
connect to your local laptop instead of a remote server.

Another use case is if you just use cdba to power up a standard distro on a
remote board and then SSH into it remotely. To avoid interruptions, it's
better to start cdba locally on the server in a tmux session. That way,
temporary disconnections do not power down the board.

From a protocol perspective, everything is transferred through STDIN and
STDOUT. It makes no difference if we have ssh piping the data to a remote
server, or if the data is directly passed to the cdba-server binary started
locally. The functionality works exactly the same.

Add an option for this in the cdba client. If the -h <host> option is
omitted, cdba-server is started locally.
2025-02-14 13:58:26 +01:00
Stephan Gerhold
828d76df63 cdba: Avoid hardcoding ssh binary path
Use execlp() instead of execl() to search the PATH for the ssh binary. This
avoids problems in case the ssh binary is installed in a different path.
2025-02-14 13:58:26 +01:00
Stephan Gerhold
e799564f44 cdba: Document behavior when omitting <boot.img>
The <boot.img> option is optional in cdba. If omitted, cdba falls back to
falls back to running "fastboot continue" to boot the installed operating
system.
2025-02-14 13:58:21 +01:00
Stephan Gerhold
720922913c drivers: ftdi-gpio: Add second USB disconnect GPIO
Some boards have more than one USB port. In that case, there is a second
GPIO on the debug board to simulate a USB disconnection for those.

Add the option to describe both USB disconnect GPIOs using
"usb0_disconnect" and "usb1_disconnect" and change both of them
when disabling USB power.

In the future it might be useful to control them separately, but for now
this ensures that power to the board is cut properly when the board is
powered off.
2025-02-14 11:42:59 +01:00
Stephan Gerhold
8bd8eeda33 schema.yaml: Fix ftdi_gpio patternProperties
"patternProperties" must be on the same indentation level as "properties",
otherwise it just defines a property called "patternProperties" in
cdba.yaml.

Also add additionalProperties: false, so properties not matching the regex
are actually disallowed and reported.
2025-02-14 11:26:35 +01:00
Stephan Gerhold
f801448422 schema.yaml: Fix unevaluatedItems -> additionalProperties
unevaluatedItems is for array items, we need unevaluatedProperties here.
But actually this can just be additionalProperties.
2025-02-14 11:26:26 +01:00
Stephan Gerhold
3922dc793a cdba: Add keys to remotely press power or fastboot key
Add special keys to allow triggering power and fastboot key presses from
the cdba client. There is an option to send a short key "pulse" (press
followed by release after 100ms) or to press/release keys separately:

 - ctrl+a -> o: Send power key pulse
 - ctrl+a -> O: Toggle power key (first use: press, next use: release)
 - ctrl+a -> f: Send fastboot key pulse
 - ctrl+a -> F: Toggle fastboot key (first use: press, next use: release)

In most cases you want to send the "pulse" (short key press), so it's
helpful to have this mapped to a single key. This avoids forgetting to
release the key again after pressing it.

The protocol between CDBA client and server is:

 (MSG_KEY_PRESS <key:u8, state:u8>)

where key is either DEVICE_KEY_FASTBOOT (0) or DEVICE_KEY_POWER (1)
and state is either KEY_PRESS_RELEASE (0), KEY_PRESS_PRESS (1) or
KEY_PRESS_PULSE (2).

The reason for implementing the "pulse" on the server side is that it's
hard to guarantee the timing on the client side. We don't know exactly when
the packets will arrive on the server. Also, "state" is a full byte anyway,
so might as well use some of the extra bits. :-)
2025-02-14 10:35:27 +01:00
Konrad Dybcio
61babbf9ac Merge pull request #82 from lumag/fix-ci
Fix CI builds
2025-02-12 19:18:42 +01:00
Dmitry Baryshkov
358fea7207 Merge pull request #80 from quic-bjorande/for-linux-msm/dont-detect-fastboot-done-by-usb
cdba: Rely on fastboot completion rather than USB disconnect
2025-02-12 20:17:56 +02:00
Dmitry Baryshkov
b0df12edc0 status: use %lld to print time_t
Some build configurations are switching to 64-bit time_t, breaking
builds on 32-bit architectures. Always use %lld and perform an explicit
conversion to (long long int) in order to make the code compile on all
architectures.

../status.c: In function 'status_send_values':
../status.c:46:53: error: format '%ld' expects argument of type 'long int', but argument 4 has type '__time64_t' {aka 'long long int'} [-Werror=format=]

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2025-02-12 12:36:10 +02:00
Dmitry Baryshkov
59db2941f5 CI: add more Fedora releases
Add Fedora 41 and 42 to the list of build configurations.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2025-02-12 12:30:33 +02:00
Dmitry Baryshkov
8715e3b74d CI: refresh Ubuntu releases
Ubuntu Mantic has been removed from the mirros, drop it from the CI
workflow. At the same time add new Ubuntu Oracular release.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2025-02-12 12:23:04 +02:00
Milosz Wasilewski
aa0e50bb1d device_parser: improve error reporting
Add more verbose output to config file parsing errors.

Signed-off-by: Milosz Wasilewski <milosz.wasilewski@oss.qualcomm.com>
2025-02-12 10:09:18 +00:00
Bjorn Andersson
0852da5424 cdba: Rely on fastboot completion rather than USB disconnect
The purpose for providing different exit codes (2 vs 110) for timeout
before or after fastboot was to allow tools invoking cdba to detect if
the device arrived at and performed fastboot or not.

In most cases relying on the fastboot (USB) disconnect notification
works fine, but in cases where the provided image fails to decompress
the standard fastboot implementation will OKAY the transfer, fail to
process the image and then return to process further fastboot requests.

This has been observed in cases where the image is too big, or when it
contains a big endian kernel.

Change the logic to rely on the "FASTBOOT_DOWNLOAD" response to
determine that we did reach fastboot and where able to upload the image
and then something happened - i.e. "there's a problem with the image" vs
"there's a setup problem".

Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
2024-11-26 09:48:15 -08:00
Konrad Dybcio
2f3e661f4d Merge pull request #77 from eberman-quic/master
ftdi_gpio: Turn on OUTPUT_ENABLE first
2024-06-18 02:47:54 +02:00
Elliot Berman
2899fbcbb1 ftdi_gpio: Turn on OUTPUT_ENABLE first
Observed instability in controlling devices when OUTPUT_ENABLE wasn't
enabled in the first step. I couldn't find any documented reason why
this is, but the documentation does say: "FtdiOutput Pin always kept at
1".

Alpaca always keeps OUTUT_ENABLE as 1, and never turns it off. The
documentation seems to imply it should always be left on. This change
updates the open sequence so that the OUTPUT_ENABLE bit is set first.

Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
2024-06-05 10:36:23 -07:00
Konrad Dybcio
61139604fb Merge pull request #76 from lumag/lock-who
Fix quitting if the board is locked
2024-05-31 15:57:46 +02:00
Dmitry Baryshkov
cbad92a838 cdba-server: log message on CDBA exit
To identify closing of the session, log the message when CDBA quits.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2024-05-31 16:57:17 +03:00
Dmitry Baryshkov
95ff3049f8 cdba-server: include PID to the syslog message
Include PID into syslog message to simplify identifying the CDBA
sessions.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2024-05-31 16:57:17 +03:00
Dmitry Baryshkov
5db3df360a device: loop around flock/warn
Loop around the flock(), sleeping in the middle. This allows CDBA to
break early if user closes the terminal (by killing SSH or by Ctrl-A-Q
sequence).

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2024-05-31 16:57:14 +03:00
Dmitry Baryshkov
02210fe6e2 Merge pull request #75 from krzk/ci-releases
Refresh CI releases
2024-05-21 10:16:49 +02:00
Krzysztof Kozlowski
b3b50a7441 ci: update checkout to v4 (to fix warning)
Fixes Github deprecation warning:

  Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20: actions/checkout@v3

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
2024-05-21 09:01:41 +02:00
Krzysztof Kozlowski
c86932d361 ci: add latest Ubuntu release
It is easy to forget to roll to new Ubuntu (or Fedora) release, so
always test on the latest Ubuntu version as well.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
2024-05-21 08:47:40 +02:00
Krzysztof Kozlowski
d77816052d ci: add new Fedora and Ubuntu
Refresh the list of distros used for testing: add new Fedora 40 and
Ubuntu 23.10 and 24.04, while dropping unsupported Ubuntu 23.04 (Lunar).

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
2024-05-21 08:41:49 +02:00
Dmitry Baryshkov
f4e95f6f0c Merge pull request #72 from lumag/laurent
laurent: driver for KernelChip Laurent family of relays
2024-04-08 23:09:06 +03:00
Dmitry Baryshkov
8f668bde64 laurent: driver for KernelChip Laurent family of relays
Add support for the KernelChip Laurent-2 / Laurent-5 / Laurent-112 /
Laurent-128 network-controlled relay arrays.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2024-03-30 18:20:12 +02:00
Konrad Dybcio
798a76ad62 Merge pull request #71 from lumag/cdba-power
cdba-power: add tool to control power-on/-off
2024-03-30 17:06:41 +01:00
Dmitry Baryshkov
ca5f95d6cd cdba-power: add power-on/-off tool
Add simple tool reusing CDBA code to power boards on and off.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2024-03-30 18:06:19 +02:00
Dmitry Baryshkov
762879fd0c device: add support for leaving device powered
For some devices it might be desirable to leave device powered on after
the cdba exits (e.g. to run some long-running tests). Add the
'power_always_on' option that tells cdba server to leave device powered
on after exiting and to toggle power (to reset the device) when
connecting.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2024-03-30 18:06:19 +02:00
Dmitry Baryshkov
62dc594cb1 device: split fastboot_open from device_open
Create new function calling fastboot_open so that device_open doesn't
have dependency on the fastboot_ops or udev.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2024-03-30 18:06:19 +02:00
Dmitry Baryshkov
2f1caa28c0 tty: split tty_open to a separate file
Split the function tty_open() to a separate file.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2024-03-30 18:06:19 +02:00
Dmitry Baryshkov
f6bd2d01d7 watch: split implementation to aseparate file
Split CDBA's watching code to a separate file.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2024-03-30 18:06:19 +02:00
Dmitry Baryshkov
bde90b4a15 cdba: replace licence headers with SPDX identifiers
Replace all license headers with the SPDX-License-Identitier headers to
follow the current recommendations.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2024-03-30 18:06:19 +02:00
Dmitry Baryshkov
b6c6807add drivers: move device / console backends to separte dir
In order to stop clobbering the root directory, move all device and
console backends to drivers/ subdir.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2024-03-30 18:06:17 +02:00
Dmitry Baryshkov
1da135b08e Merge pull request #70 from niej/readme-quit-session
README: add cmd to quit console and close session
2024-03-13 05:51:33 +02:00
Jun Nie
efd1b44e74 README: add cmd to quit console and close session
Signed-off-by: Jun Nie <jun.nie@linaro.org>
2024-03-13 10:01:27 +08:00
Dmitry Baryshkov
baa48a82c2 Merge pull request #69 from calebccff/ppps-segfault
ppps: check if ppps3_path is valid
2024-03-12 21:45:17 +02:00
Caleb Connolly
98b4aa893a ppps: check if ppps3_path is valid
funny joke about steel + water or something

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
2024-02-09 22:51:50 +00:00
Konrad Dybcio
d678216fd7 Merge pull request #66 from 0xB0D/master
Implement fastboot continue when omitting boot img from cdba command line
2024-01-17 11:12:13 +01:00
Bryan O'Donoghue
68ca7e49b4 cdba: Default to fastboot continue if image is omitted
Add the ability to omit the image from the cdba call. In this case default
to "fastboot continue" on the cdba-server side.

Regular booting continues to work like this:
cdba -b db410c -h benchtop-cdba ./qlt-kernel/build/square_5.x-tracking/boot_t2a.img

New option to boot the default image a proxy for "fastboot continue"
cdba -b db410c -h benchtop-cdba

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
2024-01-17 02:09:05 +00:00
Bryan O'Donoghue
30e6838a12 cdba-server: Implement fastboot continue
Add cdba-server side support for "fastboot continue" which allows
fastboot to continue its default boot process.

I find it useful to setup my boards with an additional SD card which I
frequently use the default image on eMMC to chroot to and populate
modules, rebooting into fastboot and subsequently booting via fastboot
a rootfs on the SD card.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
2024-01-17 02:08:44 +00:00
Dmitry Baryshkov
f9c4d71650 Merge pull request #62 from krzk/ftdi-ci
ci: switch to new libftdi on Arch Linux
2023-12-10 23:48:27 +02:00
Krzysztof Kozlowski
266d885cde ci: switch to new libftdi on Arch Linux
Use latest (not compat) version of libftdi in install scripts for Arch
Linux.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
2023-12-10 22:45:30 +01:00
Dmitry Baryshkov
4a38c0e8e1 Merge pull request #61 from krzk/cdba-server-info
Cdba server info
2023-12-10 23:35:56 +02:00
Krzysztof Kozlowski
316119c473 README: add install dependencies for Arch Linux
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
2023-12-10 22:33:27 +01:00
Krzysztof Kozlowski
fcada07889 meson: fix language typo
Fix language typo "of" -> "if".

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
2023-12-10 22:33:09 +01:00
Dmitry Baryshkov
65d867355e Merge pull request #54 from krzk/space-clean
Clean trailing white-spaces
2023-12-03 21:43:11 +02:00
Krzysztof Kozlowski
581f14d8f6 Clean trailing white-spaces
Drop trailing white-spaces and tabs.  No functional changes.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
2023-12-03 20:07:06 +01:00
Dmitry Baryshkov
2c465e56dd Merge pull request #53 from lumag/banner
cdba-server: add CDBA-server banner to be output on startup
2023-11-29 15:44:26 +02:00
Dmitry Baryshkov
d35abc800d cdba-server: add CDBA-server banner to be output on startup
Granted all possible issues with SSH, especially in the remote and/or
proxied labs, and possible issues with the board being present but
failing to power up, it is useful to have a banner message once CDBA was
started. This gives user a clear picture that the connection is fine and
the server is trying to power up the board.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-11-29 15:23:46 +02:00
Dmitry Baryshkov
5edc55cff8 Merge pull request #52 from lumag/syslog
Syslog sypport
2023-11-29 15:22:45 +02:00
Dmitry Baryshkov
43ed93357d cdba-server: add syslog support
Log messages to the syslog when the user opens a board.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-11-29 15:22:26 +02:00
Dmitry Baryshkov
b32d98f7a4 cdba-server: provide fallbacks for the username value
We use the CDBA_USER value as a way to pass info from cdba-shell to
cdba-server. However if it is not provide (e.g. because the cdba-server
is started directly by shell) add a fallback to the system's USER
variable. And if that's also not set, provide a safe default of
'nobody'.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
2023-11-29 15:22:26 +02:00
Dmitry Baryshkov
3269b8b891 Merge pull request #51 from CodeLinaro/for-linux-msm/status-support
Programmatic access to remote power measurements
2023-11-28 05:34:11 +02:00
Bjorn Andersson
0ad34da4f2 samples: Provide sample with status-cmd
Provide a sample defining the status-cmd property.

Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
2023-11-27 21:33:35 -06:00
Bjorn Andersson
6d8ff75e31 README: Introduce status messages and fifo
Introduce description of the status fifo, the status command, and the
data format for these in the README.

Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
2023-11-27 21:19:58 -06:00
Bjorn Andersson
cc91b34f3a device: Disable USB on boot
Leaving USB connected might cause hickups on the USB bus, and causes
power measurements to report incorrect data. Turn it off once the image
has been downloaded.

Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
2023-11-27 21:19:57 -06:00
Bjorn Andersson
81e46878ed cdba-server: Allow external status command
While the CDB Assist and QcomLT Debugboard is measuring voltage and
current on the DC jack directly in the backend, other backends and
further measurements can be performed using custom tooling.

Introduce support for invoking an external "status-cmd" to produce such
status updates.

The status command should on its stdout produce json-formatted status
updates following the same format as the cdba-server:

  {"ts":%d.%03d, "name": {["mv"|"ma"]: %u}(, "name2": {["mv"|"ma"]: %u})*}

with the ts aquired using clock_gettime(CLOCK_MONOTONIC) and provided in
seconds and milliseconds since the first measurement.

Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
2023-11-27 21:19:57 -06:00
Bjorn Andersson
c8e29e3400 qcomlt_dbg: Enable power status reporting
The QcomLT DebugBoard has a voltage and current sensor on the 12V DC
line, which the firmware will measure upon request.

Add a periodic request for this information, parse out the responses and
report using the status helper functions.

Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
2023-11-27 21:19:56 -06:00
Bjorn Andersson
130720a6df cdba: Introduce status pipe
The updated format and behavior of the status messages is not useful for
human consumption in the console stream, but rather for programatical
consumption by 3rd party tools.

Switch the status message stream to an optional fifo, which can be
consumed separately from the console - by humans or by tools.

The fifo is created and opened and status messages requested, if the
'-s <file>' option is specified.

Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
2023-11-27 21:19:55 -06:00
Bjorn Andersson
0a3d51e9c8 cdba-server: Repurpose status update request
The MSG_STATUS_UPDATE message when sent from the client to the server,
has until now indicated a request for a single status update. This was
suitable when the update was for human consumption on occasional basis.

But with the transition to producing status messages for programatical
consumption it makes more sense to just keep the stream on, without the
client having to poll the server for updates. This can in particular
keep the external "status command" mechanism simpler.

Just enabling the stream of status updates would spam the console with
status updates for those users that hasn't updated their clients, so the
client needs to opt-in to the status stream.

Repurpose the status update message (sent from the client) to indicate
that the streaming of status updates should be enabled.

Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
2023-11-27 21:19:54 -06:00
Bjorn Andersson
1cef583b11 cdba-server: Introduce helper for sending measurements
The current format of the cdb_assist backend status messages was never
intended to be parsed by a non-human, and the format doesn't extend well
to other backends.

Extend the format to be formatted as a json string, with a timestamp,
implemented in a separate status module.

The button status is skipped from the new status message, as it reflect
the output-values as set by cdba itself, rather than any measured state.

The timestamp is offset to the first measurement, to avoid disclosing
the uptime of the machine cdba-server is running on.

Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
2023-11-27 21:18:23 -06:00
47 changed files with 1623 additions and 923 deletions

View File

@@ -43,10 +43,15 @@ jobs:
# Fails on configure on GCC and clang (process restrictions?) # Fails on configure on GCC and clang (process restrictions?)
# - fedora:rawhide # - fedora:rawhide
- fedora:latest - fedora:latest
- fedora:42
- fedora:41
- fedora:40
- fedora:39 - fedora:39
- fedora:38 - fedora:38
- fedora:37 - fedora:37
- ubuntu:lunar # EOL 01.2024 - ubuntu:latest
- ubuntu:oracular
- ubuntu:noble
- ubuntu:jammy - ubuntu:jammy
- ubuntu:focal - ubuntu:focal
# On Ubuntu Bionic the Meson doesn't support feature options # On Ubuntu Bionic the Meson doesn't support feature options
@@ -178,7 +183,7 @@ jobs:
echo "PKG_CONFIG_PATH: $PKG_CONFIG_PATH" echo "PKG_CONFIG_PATH: $PKG_CONFIG_PATH"
- name: Git checkout - name: Git checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Install additional packages - name: Install additional packages
run: | run: |

View File

@@ -24,7 +24,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v2

View File

@@ -27,7 +27,7 @@ jobs:
steps: steps:
- name: Git checkout - name: Git checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Install additional packages - name: Install additional packages
run: | run: |

60
README
View File

@@ -5,6 +5,7 @@ attached using a CDB Assist [https://github.com/sonyxperiadev/CDB-Assist] or Con
= Dependencies = Dependencies
sudo apt-get install libudev-dev libyaml-dev libftdi1-dev pkg-config meson for debian systems sudo apt-get install libudev-dev libyaml-dev libftdi1-dev pkg-config meson for debian systems
dnf install systemd-devel libyaml-devel libftdi1-devel pkg-config meson for fedora systems dnf install systemd-devel libyaml-devel libftdi1-devel pkg-config meson for fedora systems
pacman -S libftdi libgpiod libyaml pkgconf meson for Arch systems
= Device side = Device side
On the host with the CDB Assist or Conmux attached the "cdba-server" executable is run On the host with the CDB Assist or Conmux attached the "cdba-server" executable is run
@@ -18,11 +19,13 @@ from sandbox/cdba/cdba-server. Available devices are read from $HOME/.cdba
= Client side = Client side
The client is invoked as: The client is invoked as:
cdba -b <board> -h <host> [-c <power-cylce-count>] boot.img cdba -b <board> [-h <host>] [-c <power-cylce-count>] [-s <status-fifo>] [boot.img]
<host> will be connected to using ssh and <board> will be selected for <host> will be connected to using ssh and <board> will be selected for
operation. As the board's fastboot interface shows up the given boot.img will operation. As the board's fastboot interface shows up the given boot.img
be transfered and booted on the device. will be transfered and booted on the device. If <host> is omitted, the
cdba-server is started locally without using ssh. If [boot.img] is omitted,
"fastboot continue" is run to boot the installed operating system.
The board will execute until the key sequence ^A q is invoked or the board The board will execute until the key sequence ^A q is invoked or the board
outputs a sequence of 20 ~ (tilde) chards in a row. outputs a sequence of 20 ~ (tilde) chards in a row.
@@ -31,9 +34,25 @@ If the optional -c is given, the board will upon receiving the tilde sequence
restart the board the given number of times. Each time booting the given restart the board the given number of times. Each time booting the given
boot.img. boot.img.
The optional -s argument can be used to specify that a fifo should be created
and opened. cdba will request the server to start sending status/measurement
updates, which will be written to this fifo.
How to quit the console and close session: ctrl+a then q
= Server side
== Device configuration == Device configuration
The list of attached devices is read from $HOME/.cdba and is YAML formatted. The list of attached devices is read from $HOME/.cdba and is YAML formatted.
== Status command
The "status-cmd" property for a board specifies a command line that should be
executed to perform measurements and report status updates to the client. The
command is expected to run for the duration of the board session and should
produce a continuous stream of json-formatted lines of status updates according
to the format defined in this document.
=== Example === Example
devices: devices:
- board: db2k - board: db2k
@@ -110,3 +129,38 @@ devices:
fastboot: cacafada fastboot: cacafada
fastboot_set_active: true fastboot_set_active: true
fastboot_key_timeout: 2 fastboot_key_timeout: 2
= Status messages
The status messages that are used by the client fifo and the server's status
command should be json-formatted, with one status update per line.
Each message should contain one timestamp member "ts", and one or more
measurement members. Like so:
{"ts":%d.%03d, "name": {["mv"|"ma"]: %u}(, "name2": {["mv"|"ma"]: %u})*}
The timestamp member ("ts"), should provide the time since first measurement in
decimal form with millisecond accuracy.
The key for the measurement members should be an identifier of the measured
resources, and the value should be an object with members for each unit
measured for the given resource and the measured value.
Valid units to report are "mv", "ma", and "mw".
Note that the cadence of measurement might differ between different items to be
measured, so not all status messages contains data for all items that can be
measured.
== Examples
Single resource "dc" measured at 20.271s, with voltage and current reported:
{"ts":20.271, "dc":{ "mv": 12165, "ma": 114}}
Multiple resources measured in a single status message, followed by single
resource measurement, all with voltage and current reported:
{"ts":38.341, "battery":{"mv":8023, "ma":725}, "vdd_cx":{"mv":750, "ma":466}}
{"ts":44.339, "battery":{"mv":8023, "ma":733}}

87
cdba-power.c Normal file
View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 2024, Linaro Ltd.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "cdba-server.h"
#include "device.h"
#include "device_parser.h"
#include "watch.h"
void cdba_send_buf(int type, size_t len, const void *buf)
{
/* ignore console messages */
}
static void usage(const char *name)
{
fprintf(stderr, "Usage: %s <board> on|off\n", name);
exit(EXIT_FAILURE);
}
static struct device *selected_device;
bool ready(void)
{
return device_is_running(selected_device);
}
int main(int argc, char **argv)
{
const char *home;
const char *name;
bool on;
int ret;
if (argc != 3)
usage(argv[0]);
if (!strcmp(argv[2], "on"))
on = true;
else if (!strcmp(argv[2], "off"))
on = false;
else
usage(argv[0]);
home = getenv("HOME");
if (home)
chdir(home);
ret = device_parser(".cdba");
if (ret) {
ret = device_parser("/etc/cdba");
if (ret) {
fprintf(stderr, "device parser: unable to open config file\n");
exit(1);
}
}
name = argv[1];
selected_device = device_open(name, "nobody");
if (!selected_device) {
fprintf(stderr, "failed to open %s\n", name);
exit(EXIT_FAILURE);
}
if (on) {
device_power(selected_device, true);
watch_main_loop(ready);
selected_device->usb_always_on = true;
selected_device->power_always_on = true;
} else {
device_usb(selected_device, false);
device_power(selected_device, false);
}
device_close(selected_device);
return 0;
}

View File

@@ -2,34 +2,8 @@
* Copyright (c) 2016-2018, Linaro Ltd. * Copyright (c) 2016-2018, Linaro Ltd.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * SPDX-License-Identifier: BSD-3-Clause
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sys/time.h>
#include <alloca.h>
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@@ -38,6 +12,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <syslog.h>
#include "cdba-server.h" #include "cdba-server.h"
#include "circ_buf.h" #include "circ_buf.h"
@@ -45,40 +20,12 @@
#include "device_parser.h" #include "device_parser.h"
#include "fastboot.h" #include "fastboot.h"
#include "list.h" #include "list.h"
#include "watch.h"
static bool quit_invoked;
static const char *username; static const char *username;
struct device *selected_device; struct device *selected_device;
int tty_open(const char *tty, struct termios *old)
{
struct termios tios;
int ret;
int fd;
fd = open(tty, O_RDWR | O_NOCTTY | O_EXCL);
if (fd < 0)
err(1, "unable to open \"%s\"", tty);
ret = tcgetattr(fd, old);
if (ret < 0)
err(1, "unable to retrieve \"%s\" tios", tty);
memset(&tios, 0, sizeof(tios));
tios.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
tios.c_iflag = IGNPAR;
tios.c_oflag = 0;
tcflush(fd, TCIFLUSH);
ret = tcsetattr(fd, TCSANOW, &tios);
if (ret < 0)
err(1, "unable to update \"%s\" tios", tty);
return fd;
}
static void fastboot_opened(struct fastboot *fb, void *data) static void fastboot_opened(struct fastboot *fb, void *data)
{ {
const uint8_t one = 1; const uint8_t one = 1;
@@ -108,10 +55,12 @@ static struct fastboot_ops fastboot_ops = {
static void msg_select_board(const void *param) static void msg_select_board(const void *param)
{ {
selected_device = device_open(param, username, &fastboot_ops); selected_device = device_open(param, username);
if (!selected_device) { if (!selected_device) {
fprintf(stderr, "failed to open %s\n", (const char *)param); fprintf(stderr, "failed to open %s\n", (const char *)param);
quit_invoked = true; watch_quit();
} else {
device_fastboot_open(selected_device, &fastboot_ops);
} }
cdba_send(MSG_SELECT_BOARD); cdba_send(MSG_SELECT_BOARD);
@@ -144,6 +93,34 @@ static void msg_fastboot_download(const void *data, size_t len)
} }
} }
static void msg_fastboot_continue(void)
{
device_fastboot_continue(selected_device);
cdba_send(MSG_FASTBOOT_CONTINUE);
}
static void msg_key_release(void *data)
{
int key = (int)(uintptr_t)data;
device_key(selected_device, key, false);
}
static void msg_key_press(const void *data, size_t len)
{
const struct key_press *press = data;
if (len != sizeof(*press))
return;
if (press->state == KEY_PRESS_PULSE) {
device_key(selected_device, press->key, true);
watch_timer_add(100, msg_key_release, (void*)(uintptr_t)press->key);
} else {
device_key(selected_device, press->key, !!press->state);
}
}
void cdba_send_buf(int type, size_t len, const void *buf) void cdba_send_buf(int type, size_t len, const void *buf)
{ {
struct msg msg = { struct msg msg = {
@@ -210,7 +187,7 @@ static int handle_stdin(int fd, void *buf)
// fprintf(stderr, "fastboot boot\n"); // fprintf(stderr, "fastboot boot\n");
break; break;
case MSG_STATUS_UPDATE: case MSG_STATUS_UPDATE:
device_print_status(selected_device); device_status_enable(selected_device);
break; break;
case MSG_VBUS_ON: case MSG_VBUS_ON:
device_usb(selected_device, true); device_usb(selected_device, true);
@@ -227,6 +204,12 @@ static int handle_stdin(int fd, void *buf)
case MSG_BOARD_INFO: case MSG_BOARD_INFO:
device_info(username, msg->data, msg->len); device_info(username, msg->data, msg->len);
break; break;
case MSG_FASTBOOT_CONTINUE:
msg_fastboot_continue();
break;
case MSG_KEY_PRESS:
msg_key_press(msg->data, msg->len);
break;
default: default:
fprintf(stderr, "unk %d len %d\n", msg->type, msg->len); fprintf(stderr, "unk %d len %d\n", msg->type, msg->len);
exit(1); exit(1);
@@ -238,124 +221,33 @@ static int handle_stdin(int fd, void *buf)
return 0; return 0;
} }
struct watch {
struct list_head node;
int fd;
int (*cb)(int, void*);
void *data;
};
struct timer {
struct list_head node;
struct timeval tv;
void (*cb)(void *);
void *data;
};
static struct list_head read_watches = LIST_INIT(read_watches);
static struct list_head timer_watches = LIST_INIT(timer_watches);
void watch_add_readfd(int fd, int (*cb)(int, void*), void *data)
{
struct watch *w;
w = calloc(1, sizeof(*w));
w->fd = fd;
w->cb = cb;
w->data = data;
list_add(&read_watches, &w->node);
}
void watch_timer_add(int timeout_ms, void (*cb)(void *), void *data)
{
struct timeval tv_timeout;
struct timeval now;
struct timer *t;
t = calloc(1, sizeof(*t));
gettimeofday(&now, NULL);
tv_timeout.tv_sec = timeout_ms / 1000;
tv_timeout.tv_usec = (timeout_ms % 1000) * 1000;
t->cb = cb;
t->data = data;
timeradd(&now, &tv_timeout, &t->tv);
list_add(&timer_watches, &t->node);
}
static struct timeval *watch_timer_next(void)
{
static struct timeval timeout;
struct timeval now;
struct timer *next;
struct timer *t;
if (list_empty(&timer_watches))
return NULL;
next = list_entry_first(&timer_watches, struct timer, node);
list_for_each_entry(t, &timer_watches, node) {
if (timercmp(&t->tv, &next->tv, <))
next = t;
}
gettimeofday(&now, NULL);
timersub(&next->tv, &now, &timeout);
if (timeout.tv_sec < 0) {
timeout.tv_sec = 0;
timeout.tv_usec = 0;
}
return &timeout;
}
static void watch_timer_invoke(void)
{
struct timeval now;
struct timer *tmp;
struct timer *t;
gettimeofday(&now, NULL);
list_for_each_entry_safe(t, tmp, &timer_watches, node) {
if (timercmp(&t->tv, &now, <)) {
t->cb(t->data);
list_del(&t->node);
free(t);
}
}
}
static void sigpipe_handler(int signo) static void sigpipe_handler(int signo)
{ {
quit_invoked = true; watch_quit();
} }
void watch_quit(void) static void atexit_handler(void)
{ {
quit_invoked = true; syslog(LOG_INFO, "exiting");
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
struct timeval *timeoutp;
struct watch *w;
fd_set rfds;
int flags; int flags;
int nfds;
int ret; int ret;
signal(SIGPIPE, sigpipe_handler); signal(SIGPIPE, sigpipe_handler);
fprintf(stderr, "Starting cdba server\n");
username = getenv("CDBA_USER"); username = getenv("CDBA_USER");
if (!username)
username = getenv("USER");
if (!username)
username = "nobody";
openlog("cdba-server", LOG_PID, LOG_DAEMON);
atexit(atexit_handler);
ret = device_parser(".cdba"); ret = device_parser(".cdba");
if (ret) { if (ret) {
@@ -371,40 +263,7 @@ int main(int argc, char **argv)
flags = fcntl(STDIN_FILENO, F_GETFL, 0); flags = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK); fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
while (!quit_invoked) { watch_run();
nfds = 0;
list_for_each_entry(w, &read_watches, node) {
nfds = MAX(nfds, w->fd);
FD_SET(w->fd, &rfds);
}
if (!FD_ISSET(STDIN_FILENO, &rfds)) {
fprintf(stderr, "rfds is trash!\n");
goto done;
}
timeoutp = watch_timer_next();
ret = select(nfds + 1, &rfds, NULL, NULL, timeoutp);
if (ret < 0 && errno == EINTR)
continue;
else if (ret < 0)
break;
watch_timer_invoke();
list_for_each_entry(w, &read_watches, node) {
if (FD_ISSET(w->fd, &rfds)) {
ret = w->cb(w->fd, w->data);
if (ret < 0) {
fprintf(stderr, "cb returned %d\n", ret);
goto done;
}
}
}
}
done:
/* if we got here, stdin/out/err might be not accessible anymore */ /* if we got here, stdin/out/err might be not accessible anymore */
ret = open("/dev/null", O_RDWR); ret = open("/dev/null", O_RDWR);

View File

@@ -6,14 +6,6 @@
#include "cdba.h" #include "cdba.h"
void watch_add_readfd(int fd, int (*cb)(int, void*), void *data);
int watch_add_quit(int (*cb)(int, void*), void *data);
void watch_timer_add(int timeout_ms, void (*cb)(void *), void *data);
void watch_quit(void);
int watch_run(void);
int tty_open(const char *tty, struct termios *old);
void cdba_send_buf(int type, size_t len, const void *buf); void cdba_send_buf(int type, size_t len, const void *buf);
#define cdba_send(type) cdba_send_buf(type, 0, NULL) #define cdba_send(type) cdba_send_buf(type, 0, NULL)

182
cdba.c
View File

@@ -2,31 +2,7 @@
* Copyright (c) 2016-2018, Linaro Ltd. * Copyright (c) 2016-2018, Linaro Ltd.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * SPDX-License-Identifier: BSD-3-Clause
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sys/select.h> #include <sys/select.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -51,6 +27,9 @@
static bool quit; static bool quit;
static bool fastboot_repeat; static bool fastboot_repeat;
static bool fastboot_done; static bool fastboot_done;
static bool fastboot_continue;
static int status_fd = -1;
static const char *fastboot_file; static const char *fastboot_file;
@@ -124,8 +103,13 @@ static int fork_ssh(const char *host, const char *cmd, int *pipes)
close(piped_stderr[0]); close(piped_stderr[0]);
close(piped_stderr[1]); close(piped_stderr[1]);
execl("/usr/bin/ssh", "ssh", host, cmd, NULL); if (host) {
err(1, "launching ssh failed"); execlp("ssh", "ssh", host, cmd, NULL);
err(1, "launching ssh failed");
} else {
execlp(cmd, cmd, NULL);
err(1, "launching cdba-server failed");
}
default: default:
close(piped_stdin[0]); close(piped_stdin[0]);
close(piped_stdout[1]); close(piped_stdout[1]);
@@ -164,8 +148,25 @@ static int cdba_send_buf(int fd, int type, size_t len, const void *buf)
return ret < 0 ? ret : 0; return ret < 0 ? ret : 0;
} }
static int cdba_send_key(int fd, int key, uint8_t state)
{
struct key_press press = {
.key = key,
.state = state,
};
return cdba_send_buf(fd, MSG_KEY_PRESS, sizeof(press), &press);
}
static int cdba_toggle_key(int fd, int key, bool key_state[DEVICE_KEY_COUNT])
{
key_state[key] = !key_state[key];
return cdba_send_key(fd, key, key_state[key]);
}
static int tty_callback(int *ssh_fds) static int tty_callback(int *ssh_fds)
{ {
static bool key_state[DEVICE_KEY_COUNT];
static const char ctrl_a = 0x1; static const char ctrl_a = 0x1;
static bool special; static bool special;
char buf[32]; char buf[32];
@@ -205,6 +206,18 @@ static int tty_callback(int *ssh_fds)
case 'B': case 'B':
cdba_send(ssh_fds[0], MSG_SEND_BREAK); cdba_send(ssh_fds[0], MSG_SEND_BREAK);
break; break;
case 'o':
cdba_send_key(ssh_fds[0], DEVICE_KEY_POWER, KEY_PRESS_PULSE);
break;
case 'O':
cdba_toggle_key(ssh_fds[0], DEVICE_KEY_POWER, key_state);
break;
case 'f':
cdba_send_key(ssh_fds[0], DEVICE_KEY_FASTBOOT, KEY_PRESS_PULSE);
break;
case 'F':
cdba_toggle_key(ssh_fds[0], DEVICE_KEY_FASTBOOT, key_state);
break;
} }
special = false; special = false;
@@ -338,6 +351,22 @@ static void request_power_off(void)
list_add(&work_items, &work.node); list_add(&work_items, &work.node);
} }
static void request_fastboot_continue_fn(struct work *work, int ssh_stdin)
{
int ret;
ret = cdba_send(ssh_stdin, MSG_FASTBOOT_CONTINUE);
if (ret < 0)
err(1, "failed to send fastboot continue request");
}
static void request_fastboot_continue(void)
{
static struct work work = { request_fastboot_continue_fn };
list_add(&work_items, &work.node);
}
struct fastboot_download_work { struct fastboot_download_work {
struct work work; struct work work;
@@ -398,12 +427,40 @@ static void request_fastboot_files(void)
static void handle_status_update(const void *data, size_t len) static void handle_status_update(const void *data, size_t len)
{ {
char *str = alloca(len + 1); if (status_fd < 0)
return;
memcpy(str, data, len); write(status_fd, data, len);
str[len] = '\n'; }
write(STDOUT_FILENO, str, len + 1); static void status_enable_fn(struct work *work, int ssh_stdin)
{
cdba_send(ssh_stdin, MSG_STATUS_UPDATE);
free(work);
}
static void status_pipe_open(const char *path)
{
struct work *work;
int ret;
int fd;
ret = mkfifo(path, 0600);
if (ret < 0 && errno != EEXIST)
err(1, "failed to create fifo %s", path);
fd = open(path, O_RDWR | O_NONBLOCK);
if (fd < 0)
err(1, "failed to open fifo %s", path);
status_fd = fd;
/* Queue a MSG_STATUS_UPDATE request */
work = malloc(sizeof(*work));
work->fn = status_enable_fn;
list_add(&work_items, &work->node);
} }
static void handle_list_devices(const void *data, size_t len) static void handle_list_devices(const void *data, size_t len)
@@ -502,17 +559,19 @@ static int handle_message(struct circ_buf *buf)
case MSG_FASTBOOT_PRESENT: case MSG_FASTBOOT_PRESENT:
if (*(uint8_t*)msg->data) { if (*(uint8_t*)msg->data) {
// printf("======================================== MSG_FASTBOOT_PRESENT(on)\n"); // printf("======================================== MSG_FASTBOOT_PRESENT(on)\n");
if (!fastboot_done || fastboot_repeat) if (fastboot_continue) {
request_fastboot_continue();
fastboot_continue = false;
} else if (!fastboot_done || fastboot_repeat) {
request_fastboot_files(); request_fastboot_files();
else } else {
quit = true; quit = true;
} else { }
fastboot_done = true;
// printf("======================================== MSG_FASTBOOT_PRESENT(off)\n");
} }
break; break;
case MSG_FASTBOOT_DOWNLOAD: case MSG_FASTBOOT_DOWNLOAD:
// printf("======================================== MSG_FASTBOOT_DOWNLOAD\n"); // printf("======================================== MSG_FASTBOOT_DOWNLOAD\n");
fastboot_done = true;
break; break;
case MSG_FASTBOOT_BOOT: case MSG_FASTBOOT_BOOT:
// printf("======================================== MSG_FASTBOOT_BOOT\n"); // printf("======================================== MSG_FASTBOOT_BOOT\n");
@@ -527,6 +586,10 @@ static int handle_message(struct circ_buf *buf)
handle_board_info(msg->data, msg->len); handle_board_info(msg->data, msg->len);
return -1; return -1;
break; break;
case MSG_FASTBOOT_CONTINUE:
// printf("======================================== MSG_FASTBOOT_CONTINUE\n");
fastboot_done = true;
break;
default: default:
fprintf(stderr, "unk %d len %d\n", msg->type, msg->len); fprintf(stderr, "unk %d len %d\n", msg->type, msg->len);
return -1; return -1;
@@ -554,12 +617,12 @@ static void usage(void)
{ {
extern const char *__progname; extern const char *__progname;
fprintf(stderr, "usage: %s -b <board> -h <host> [-t <timeout>] " fprintf(stderr, "usage: %s -b <board> [-h <host>] [-t <timeout>] "
"[-T <inactivity-timeout>] boot.img\n", "[-T <inactivity-timeout>] [boot.img]\n",
__progname); __progname);
fprintf(stderr, "usage: %s -i -b <board> -h <host>\n", fprintf(stderr, "usage: %s -i -b <board> [-h <host>]\n",
__progname); __progname);
fprintf(stderr, "usage: %s -l -h <host>\n", fprintf(stderr, "usage: %s -l [-h <host>]\n",
__progname); __progname);
exit(1); exit(1);
} }
@@ -575,8 +638,10 @@ int main(int argc, char **argv)
bool power_cycle_on_timeout = true; bool power_cycle_on_timeout = true;
struct timeval timeout_inactivity_tv; struct timeval timeout_inactivity_tv;
struct timeval timeout_total_tv; struct timeval timeout_total_tv;
struct timeval *timeout = NULL;
struct termios *orig_tios; struct termios *orig_tios;
const char *server_binary = "cdba-server"; const char *server_binary = "cdba-server";
const char *status_pipe = NULL;
int timeout_inactivity = 0; int timeout_inactivity = 0;
int timeout_total = 600; int timeout_total = 600;
struct work *next; struct work *next;
@@ -597,7 +662,7 @@ int main(int argc, char **argv)
int opt; int opt;
int ret; int ret;
while ((opt = getopt(argc, argv, "b:c:C:h:ilRt:S:T:")) != -1) { while ((opt = getopt(argc, argv, "b:c:C:h:ilRt:S:s:T:")) != -1) {
switch (opt) { switch (opt) {
case 'b': case 'b':
board = optarg; board = optarg;
@@ -623,6 +688,9 @@ int main(int argc, char **argv)
case 'S': case 'S':
server_binary = optarg; server_binary = optarg;
break; break;
case 's':
status_pipe = optarg;
break;
case 't': case 't':
timeout_total = atoi(optarg); timeout_total = atoi(optarg);
break; break;
@@ -634,18 +702,17 @@ int main(int argc, char **argv)
} }
} }
if (!host)
usage();
switch (verb) { switch (verb) {
case CDBA_BOOT: case CDBA_BOOT:
if (optind >= argc || !board) if (optind > argc || !board)
usage(); usage();
fastboot_file = argv[optind]; fastboot_file = argv[optind];
if (lstat(fastboot_file, &sb)) if (!fastboot_file)
fastboot_continue = true;
else if (lstat(fastboot_file, &sb))
err(1, "unable to read \"%s\"", fastboot_file); err(1, "unable to read \"%s\"", fastboot_file);
if (!S_ISREG(sb.st_mode) && !S_ISLNK(sb.st_mode)) else if (!S_ISREG(sb.st_mode) && !S_ISLNK(sb.st_mode))
errx(1, "\"%s\" is not a regular file", fastboot_file); errx(1, "\"%s\" is not a regular file", fastboot_file);
request_select_board(board); request_select_board(board);
@@ -661,6 +728,9 @@ int main(int argc, char **argv)
break; break;
} }
if (status_pipe)
status_pipe_open(status_pipe);
ret = fork_ssh(host, server_binary, ssh_fds); ret = fork_ssh(host, server_binary, ssh_fds);
if (ret) if (ret)
err(1, "failed to connect to \"%s\"", host); err(1, "failed to connect to \"%s\"", host);
@@ -669,6 +739,8 @@ int main(int argc, char **argv)
timeout_total_tv = get_timeout(timeout_total); timeout_total_tv = get_timeout(timeout_total);
timeout_inactivity_tv = get_timeout(timeout_inactivity); timeout_inactivity_tv = get_timeout(timeout_inactivity);
if (timeout_total || timeout_inactivity)
timeout = &tv;
while (!quit) { while (!quit) {
if (received_power_off || reached_timeout) { if (received_power_off || reached_timeout) {
@@ -706,14 +778,16 @@ int main(int argc, char **argv)
if (!list_empty(&work_items)) if (!list_empty(&work_items))
FD_SET(ssh_fds[0], &wfds); FD_SET(ssh_fds[0], &wfds);
gettimeofday(&now, NULL); if (timeout) {
if (timeout_inactivity && timercmp(&timeout_inactivity_tv, &timeout_total_tv, <)) { gettimeofday(&now, NULL);
timersub(&timeout_inactivity_tv, &now, &tv); if (timeout_inactivity && (!timeout_total ||
} else { timercmp(&timeout_inactivity_tv, &timeout_total_tv, <))) {
timersub(&timeout_total_tv, &now, &tv); timersub(&timeout_inactivity_tv, &now, timeout);
} else {
timersub(&timeout_total_tv, &now, timeout);
}
} }
ret = select(nfds + 1, &rfds, &wfds, NULL, timeout);
ret = select(nfds + 1, &rfds, &wfds, NULL, &tv);
#if 0 #if 0
printf("select: %d (%c%c%c)\n", ret, FD_ISSET(STDIN_FILENO, &rfds) ? 'X' : '-', printf("select: %d (%c%c%c)\n", ret, FD_ISSET(STDIN_FILENO, &rfds) ? 'X' : '-',
FD_ISSET(ssh_fds[1], &rfds) ? 'X' : '-', FD_ISSET(ssh_fds[1], &rfds) ? 'X' : '-',

19
cdba.h
View File

@@ -30,6 +30,25 @@ enum {
MSG_SEND_BREAK, MSG_SEND_BREAK,
MSG_LIST_DEVICES, MSG_LIST_DEVICES,
MSG_BOARD_INFO, MSG_BOARD_INFO,
MSG_FASTBOOT_CONTINUE,
MSG_KEY_PRESS,
};
struct key_press {
uint8_t key;
uint8_t state;
} __packed;
enum {
DEVICE_KEY_FASTBOOT,
DEVICE_KEY_POWER,
DEVICE_KEY_COUNT
};
enum {
KEY_PRESS_RELEASE,
KEY_PRESS_PRESS,
KEY_PRESS_PULSE,
}; };
#endif #endif

View File

@@ -17,7 +17,7 @@ case $CC in
esac esac
pacman -Syu --noconfirm \ pacman -Syu --noconfirm \
libftdi-compat \ libftdi \
libyaml \ libyaml \
systemd-libs \ systemd-libs \
libgpiod \ libgpiod \

View File

@@ -2,31 +2,7 @@
* Copyright (c) 2018, Linaro Ltd. * Copyright (c) 2018, Linaro Ltd.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * SPDX-License-Identifier: BSD-3-Clause
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <errno.h> #include <errno.h>

View File

@@ -2,31 +2,7 @@
* Copyright (c) 2018, Linaro Ltd. * Copyright (c) 2018, Linaro Ltd.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * SPDX-License-Identifier: BSD-3-Clause
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef __CIRC_BUF_H__ #ifndef __CIRC_BUF_H__
#define __CIRC_BUF_H__ #define __CIRC_BUF_H__

View File

@@ -0,0 +1,8 @@
---
devices:
- board: myboard
name: "My Board"
alpaca: /dev/ttyACM0
console: /dev/ttyUSB0
fastboot: cacafada
status-cmd: /usr/bin/sample-measure-app --sample-rate 100 /dev/measure0

View File

@@ -0,0 +1,13 @@
---
devices:
- board: myboard
name: "My Board"
description: |
My Awesome board
console: /dev/ttyABC0
fastboot: cacafada
fastboot_set_active: true
fastboot_key_timeout: 2
laurent:
server: laurent.lan
relay: 5

View File

@@ -73,3 +73,32 @@ devices:
power: power:
interface: D interface: D
line: 6 line: 6
- board: myboard-5
name: "My Board 5"
description: |
My super awesome board Number 5
console: /dev/ttyABC1
fastboot: cacafada
ftdi_gpio:
vendor: "0x0403"
product: "0x6011"
index: 0
power:
interface: B
line: 1
active_low: true
fastboot_key:
interface: B
line: 0
active_low: true
power_key:
interface: B
line: 2
usb0_disconnect:
interface: C
line: 7
active_low: true
usb1_disconnect:
interface: A
line: 4
active_low: true

View File

@@ -2,31 +2,7 @@
* Copyright (c) 2020, Linaro Ltd. * Copyright (c) 2020, Linaro Ltd.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * SPDX-License-Identifier: BSD-3-Clause
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sys/file.h> #include <sys/file.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -37,6 +13,8 @@
#include "cdba-server.h" #include "cdba-server.h"
#include "device.h" #include "device.h"
#include "tty.h"
#include "watch.h"
struct console { struct console {
int console_fd; int console_fd;

130
device.c
View File

@@ -2,31 +2,7 @@
* Copyright (c) 2016-2018, Linaro Ltd. * Copyright (c) 2016-2018, Linaro Ltd.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * SPDX-License-Identifier: BSD-3-Clause
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sys/file.h> #include <sys/file.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -39,12 +15,15 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <syslog.h>
#include "cdba-server.h" #include "cdba-server.h"
#include "device.h" #include "device.h"
#include "fastboot.h" #include "fastboot.h"
#include "list.h" #include "list.h"
#include "ppps.h" #include "ppps.h"
#include "status-cmd.h"
#include "watch.h"
#define ARRAY_SIZE(x) ((sizeof(x)/sizeof((x)[0]))) #define ARRAY_SIZE(x) ((sizeof(x)/sizeof((x)[0])))
@@ -85,15 +64,21 @@ static void device_lock(struct device *device)
if (fd < 0) if (fd < 0)
err(1, "failed to open lockfile %s", lock); err(1, "failed to open lockfile %s", lock);
n = flock(fd, LOCK_EX | LOCK_NB); while (1) {
if (!n) char c;
return;
warnx("board is in use, waiting..."); n = flock(fd, LOCK_EX | LOCK_NB);
if (!n)
return;
n = flock(fd, LOCK_EX); warnx("board is in use, waiting...");
if (n < 0)
err(1, "failed to lock lockfile %s", lock); sleep(3);
/* check that connection isn't gone */
if (read(STDIN_FILENO, &c, 1) == 0)
errx(1, "connection is gone");
}
} }
static bool device_check_access(struct device *device, static bool device_check_access(struct device *device,
@@ -115,9 +100,10 @@ static bool device_check_access(struct device *device,
return false; return false;
} }
static int device_power_off(struct device *device);
struct device *device_open(const char *board, struct device *device_open(const char *board,
const char *username, const char *username)
struct fastboot_ops *fastboot_ops)
{ {
struct device *device; struct device *device;
@@ -126,11 +112,17 @@ struct device *device_open(const char *board,
goto found; goto found;
} }
syslog(LOG_INFO, "user %s asked for non-existing board %s", username, board);
return NULL; return NULL;
found: found:
if (!device_check_access(device, username)) if (!device_check_access(device, username)) {
syslog(LOG_INFO, "user %s access denied to the board %s", username, board);
return NULL; return NULL;
}
syslog(LOG_INFO, "user %s opening board %s", username, board);
assert(device->console_ops); assert(device->console_ops);
assert(device->console_ops->open); assert(device->console_ops->open);
@@ -148,11 +140,21 @@ found:
if (!device->console) if (!device->console)
errx(1, "failed to open device console"); errx(1, "failed to open device console");
/*
* Power off before opening fastboot. Otherwise if the device is
* already in the fastboot state, CDBA will detect it, then power up
* procedure will restart the device causing fastboot to disappear and
* appear again. This will cause CDBA to exit, ending up with the
* unbreakable fastboot-reset-second_fastboot-quit cycle.
* */
if (device->power_always_on) {
device_power_off(device);
sleep(2);
}
if (device->usb_always_on) if (device->usb_always_on)
device_usb(device, true); device_usb(device, true);
device->fastboot = fastboot_open(device->serial, fastboot_ops, NULL);
return device; return device;
} }
@@ -161,7 +163,7 @@ static void device_impl_power(struct device *device, bool on)
device_control(device, power, on); device_control(device, power, on);
} }
static void device_key(struct device *device, int key, bool asserted) void device_key(struct device *device, int key, bool asserted)
{ {
if (device_has_control(device, key)) if (device_has_control(device, key))
device_control(device, key, key, asserted); device_control(device, key, key, asserted);
@@ -231,6 +233,11 @@ static void device_tick(void *data)
} }
} }
bool device_is_running(struct device *device)
{
return device->state == DEVICE_STATE_RUNNING;
}
static int device_power_on(struct device *device) static int device_power_on(struct device *device)
{ {
if (!device || !device_has_control(device, power)) if (!device || !device_has_control(device, power))
@@ -260,17 +267,25 @@ int device_power(struct device *device, bool on)
return device_power_off(device); return device_power_off(device);
} }
void device_print_status(struct device *device) void device_status_enable(struct device *device)
{ {
if (device_has_control(device, print_status)) if (device->status_enabled)
device_control(device, print_status); return;
if (device_has_control(device, status_enable))
device_control(device, status_enable);
if (device->status_cmd)
status_cmd_open(device);
device->status_enabled = true;
} }
void device_usb(struct device *device, bool on) void device_usb(struct device *device, bool on)
{ {
if (device->ppps_path) if (device->ppps_path)
ppps_power(device, on); ppps_power(device, on);
else if (device_has_control(device, usb)) if (device_has_control(device, usb))
device_control(device, usb, on); device_control(device, usb, on);
} }
@@ -282,13 +297,36 @@ int device_write(struct device *device, const void *buf, size_t len)
return device_console(device, write, buf, len); return device_console(device, write, buf, len);
} }
void device_fastboot_open(struct device *device,
struct fastboot_ops *fastboot_ops)
{
device->fastboot = fastboot_open(device->serial, fastboot_ops, NULL);
}
void device_fastboot_boot(struct device *device) void device_fastboot_boot(struct device *device)
{ {
if (!device->fastboot) {
fprintf(stderr, "fastboot not opened\n");
return;
}
fastboot_boot(device->fastboot); fastboot_boot(device->fastboot);
} }
void device_fastboot_continue(struct device *device)
{
if (!device->fastboot) {
fprintf(stderr, "fastboot not opened\n");
return;
}
fastboot_continue(device->fastboot);
}
void device_fastboot_flash_reboot(struct device *device) void device_fastboot_flash_reboot(struct device *device)
{ {
if (!device->fastboot) {
fprintf(stderr, "fastboot not opened\n");
return;
}
fastboot_flash(device->fastboot, "boot"); fastboot_flash(device->fastboot, "boot");
fastboot_reboot(device->fastboot); fastboot_reboot(device->fastboot);
} }
@@ -300,6 +338,11 @@ void device_boot(struct device *device, const void *data, size_t len)
fastboot_set_active(device->fastboot, device->set_active); fastboot_set_active(device->fastboot, device->set_active);
fastboot_download(device->fastboot, data, len); fastboot_download(device->fastboot, data, len);
device->boot(device); device->boot(device);
if (device->status_enabled && !device->usb_always_on) {
warnx("disabling USB, use ^A V to enable");
device_usb(device, false);
}
} }
void device_send_break(struct device *device) void device_send_break(struct device *device)
@@ -356,7 +399,8 @@ void device_close(struct device *dev)
{ {
if (!dev->usb_always_on) if (!dev->usb_always_on)
device_usb(dev, false); device_usb(dev, false);
device_power(dev, false); if (!dev->power_always_on)
device_power(dev, false);
if (device_has_control(dev, close)) if (device_has_control(dev, close))
device_control(dev, close); device_control(dev, close);

View File

@@ -2,6 +2,7 @@
#define __DEVICE_H__ #define __DEVICE_H__
#include <termios.h> #include <termios.h>
#include "cdba.h"
#include "list.h" #include "list.h"
struct cdb_assist; struct cdb_assist;
@@ -17,7 +18,7 @@ struct control_ops {
int (*power)(struct device *dev, bool on); int (*power)(struct device *dev, bool on);
void (*usb)(struct device *dev, bool on); void (*usb)(struct device *dev, bool on);
void (*key)(struct device *device, int key, bool asserted); void (*key)(struct device *device, int key, bool asserted);
void (*print_status)(struct device *dev); void (*status_enable)(struct device *dev);
}; };
struct console_ops { struct console_ops {
@@ -41,11 +42,14 @@ struct device {
unsigned voltage; unsigned voltage;
bool tickle_mmc; bool tickle_mmc;
bool usb_always_on; bool usb_always_on;
bool power_always_on;
struct fastboot *fastboot; struct fastboot *fastboot;
unsigned int fastboot_key_timeout; unsigned int fastboot_key_timeout;
int state; int state;
bool has_power_key; bool has_power_key;
bool status_enabled;
void (*boot)(struct device *); void (*boot)(struct device *);
const struct control_ops *control_ops; const struct control_ops *control_ops;
@@ -56,6 +60,8 @@ struct device {
void *cdb; void *cdb;
void *console; void *console;
char *status_cmd;
struct list_head node; struct list_head node;
}; };
@@ -68,27 +74,26 @@ struct device_user {
void device_add(struct device *device); void device_add(struct device *device);
struct device *device_open(const char *board, struct device *device_open(const char *board,
const char *username, const char *username);
struct fastboot_ops *fastboot_ops);
void device_close(struct device *dev); void device_close(struct device *dev);
int device_power(struct device *device, bool on); int device_power(struct device *device, bool on);
void device_key(struct device *device, int key, bool asserted);
void device_print_status(struct device *device); void device_status_enable(struct device *device);
void device_usb(struct device *device, bool on); void device_usb(struct device *device, bool on);
int device_write(struct device *device, const void *buf, size_t len); int device_write(struct device *device, const void *buf, size_t len);
void device_boot(struct device *device, const void *data, size_t len); void device_boot(struct device *device, const void *data, size_t len);
void device_fastboot_open(struct device *device,
struct fastboot_ops *fastboot_ops);
void device_fastboot_boot(struct device *device); void device_fastboot_boot(struct device *device);
void device_fastboot_flash_reboot(struct device *device); void device_fastboot_flash_reboot(struct device *device);
void device_send_break(struct device *device); void device_send_break(struct device *device);
void device_list_devices(const char *username); void device_list_devices(const char *username);
void device_info(const char *username, const void *data, size_t dlen); void device_info(const char *username, const void *data, size_t dlen);
void device_fastboot_continue(struct device *device);
enum { bool device_is_running(struct device *device);
DEVICE_KEY_FASTBOOT,
DEVICE_KEY_POWER,
};
extern const struct control_ops alpaca_ops; extern const struct control_ops alpaca_ops;
extern const struct control_ops cdb_assist_ops; extern const struct control_ops cdb_assist_ops;
@@ -97,6 +102,7 @@ extern const struct control_ops ftdi_gpio_ops;
extern const struct control_ops local_gpio_ops; extern const struct control_ops local_gpio_ops;
extern const struct control_ops external_ops; extern const struct control_ops external_ops;
extern const struct control_ops qcomlt_dbg_ops; extern const struct control_ops qcomlt_dbg_ops;
extern const struct control_ops laurent_ops;
extern const struct console_ops conmux_console_ops; extern const struct console_ops conmux_console_ops;
extern const struct console_ops console_ops; extern const struct console_ops console_ops;

View File

@@ -2,31 +2,7 @@
* Copyright (c) 2018, Linaro Ltd. * Copyright (c) 2018, Linaro Ltd.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * SPDX-License-Identifier: BSD-3-Clause
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
@@ -46,6 +22,11 @@ static void nextsym(struct device_parser *dp)
{ {
if (!yaml_parser_parse(&dp->parser, &dp->event)) { if (!yaml_parser_parse(&dp->parser, &dp->event)) {
fprintf(stderr, "device parser: error %u\n", dp->parser.error); fprintf(stderr, "device parser: error %u\n", dp->parser.error);
fprintf(stderr,
"device parser: index %zu, line %zu, column %zu\n",
dp->parser.context_mark.index,
dp->parser.context_mark.line,
dp->parser.context_mark.column);
exit(1); exit(1);
} }
} }
@@ -67,6 +48,33 @@ int device_parser_accept(struct device_parser *dp, int type,
} }
} }
void decode_yaml_type_error(struct device_parser *dp, int type)
{
char event_type[11][26] = {
"YAML_NO_EVENT",
"YAML_STREAM_START_EVENT",
"YAML_STREAM_END_EVENT",
"YAML_DOCUMENT_START_EVENT",
"YAML_DOCUMENT_END_EVENT",
"YAML_ALIAS_EVENT",
"YAML_SCALAR_EVENT",
"YAML_SEQUENCE_START_EVENT",
"YAML_SEQUENCE_END_EVENT",
"YAML_MAPPING_START_EVENT",
"YAML_MAPPING_END_EVENT"
};
fprintf(stderr,
"device parser: expected %s got %s\n",
event_type[type],
event_type[dp->event.type]);
fprintf(stderr,
"device parser: index %zu, line %zu, column %zu\n",
dp->parser.mark.index,
dp->parser.mark.line,
dp->parser.mark.column);
}
bool device_parser_expect(struct device_parser *dp, int type, bool device_parser_expect(struct device_parser *dp, int type,
char *scalar, size_t scalar_len) char *scalar, size_t scalar_len)
{ {
@@ -74,7 +82,7 @@ bool device_parser_expect(struct device_parser *dp, int type,
return true; return true;
} }
fprintf(stderr, "device parser: expected %d got %u\n", type, dp->event.type); decode_yaml_type_error(dp, type);
exit(1); exit(1);
} }
@@ -139,6 +147,11 @@ static void parse_board(struct device_parser *dp)
if (dev->control_options) if (dev->control_options)
set_control_ops(dev, &ftdi_gpio_ops); set_control_ops(dev, &ftdi_gpio_ops);
continue; continue;
} else if (!strcmp(key, "laurent")) {
dev->control_options = laurent_ops.parse_options(dp);
if (dev->control_options)
set_control_ops(dev, &laurent_ops);
continue;
} }
device_parser_expect(dp, YAML_SCALAR_EVENT, value, TOKEN_LENGTH); device_parser_expect(dp, YAML_SCALAR_EVENT, value, TOKEN_LENGTH);
@@ -193,6 +206,10 @@ static void parse_board(struct device_parser *dp)
dev->ppps_path = strdup(value); dev->ppps_path = strdup(value);
} else if (!strcmp(key, "ppps3_path")) { } else if (!strcmp(key, "ppps3_path")) {
dev->ppps3_path = strdup(value); dev->ppps3_path = strdup(value);
} else if (!strcmp(key, "status-cmd")) {
dev->status_cmd = strdup(value);
} else if (!strcmp(key, "power_always_on")) {
dev->power_always_on = !strcmp(value, "true");
} else { } else {
fprintf(stderr, "device parser: unknown key \"%s\"\n", key); fprintf(stderr, "device parser: unknown key \"%s\"\n", key);
exit(1); exit(1);

View File

@@ -2,31 +2,7 @@
* Copyright (c) 2018, Linaro Ltd. * Copyright (c) 2018, Linaro Ltd.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * SPDX-License-Identifier: BSD-3-Clause
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
@@ -41,8 +17,8 @@
#include <termios.h> #include <termios.h>
#include <unistd.h> #include <unistd.h>
#include "cdba-server.h"
#include "device.h" #include "device.h"
#include "tty.h"
struct alpaca { struct alpaca {
int alpaca_fd; int alpaca_fd;

Some files were not shown because too many files have changed in this diff Show More