... and a little more info ...
You can invoke the following to wait for and display all BT events. The example that follows shows what happens when you disconnect/connect a given audio device. You can use this to watch the events for other sources too (e.g., com.lab126.powerd).
Quote:
# lipc-wait-event -m com.lab126.btfd "*"
|
Disconnecting and reconnecting the audio device results in the following output:
Code:
Disconnect_Result 0 "EWA Audio A106Pro" "49:41:7E:DB:AD:F3"
BTstateChanged 1
Connect_Result 0 "EWA Audio A106Pro" "49:41:7E:DB:AD:F3"
BTstateChanged 2
I'm now listening for the Disconnect_Result events and forcing the reconnect at that time. I no longer need my cron job.
Below is an updated version of my btconnect.sh script that now accepts the device name and address as parameters, which my event processing script will pass. Also below is my event processing script that shows how I'm listening for various events which might be of some use. I'm basically using this latter script to manage the display of screen saver images when the Kindle is normally displaying its screen saver, as well as managing the Bluetooth connection for my grandfather clock sounds. It also keeps the device from suspending while the screen saver is visible as long as the device is charging or its battery level is > a given threshold. cron jobs are used to update the screen with a new image every "n" minutes and to play the grandfather clock sounds at the appropriate times.
The comments throughout should help explain things. The "com.daddo.playingmedia" and "com.daddo.media" source and associated events are my own custom events used to pass data to the processing script from another script that I use to play sound files.
I'm also using my Kindle to manage my home automation (turning lights on and off at various times) via various cron jobs. This is another reason why want to keep the device from suspending when its screensaver is visible.
This really is a cool little device with a lot of potential.

None of this would be possible without the help and hard work of all those who established jailbreak approaches and other utilities needed to gain access, so THANK YOU!!
btconnect.sh:
Code:
#!/bin/bash
IFS="
"
PATH="/bin:/usr/bin:/sbin:/usr/sbin"
CMD=$(basename $0)
CMDPATH=$(dirname "$0")
if [[ "${CMDPATH}" == "" ]]; then CMDPATH="./"; fi
CMDPATH=$(realpath "${CMDPATH}")
source "${CMDPATH}/../config/config.sh"
source "${CMDPATH}/../config/btconfig.sh"
source "${CMDPATH}/shLib/fn_logger.sh"
if [[ $# -eq 2 ]]
then
connectToDevName=$1
connectToDevAddr=$2
else
connectToDevName="${BTDEVICE_NAME}"
connectToDevAddr="${BTDEVICE_ADDR}"
fi
logfile="${LOGDIR}/btconnect"
connectedDevName=$(lipc-get-prop com.lab126.btfd BTconnectedDevName 2>/dev/null)
if [[ "${DEBUG}" == 1 ]]; then (fn_loginfo "${CMD}" "connectToDevName = \"${connectToDevName}\", connectedDevName = \"$connectedDevName\"") 2>> "${logfile}"; fi
if [[ "${connectToDevName}" != "${connectedDevName}" ]]
then
# Determine if the device is actively charging. It's
# possible that the device can be plugged in and isCharging
# be 0 (e.g., the battery is at 99% charged), meaning the
# device is allowing itself to discharge before entering a
# charing state again, so as to protect the battery.
#
# Therefore, we check both the charging indicator and battery level
# when determining whether or not we should prevent the device
# from suspending.
#
# On startup, battLevel could be "" and waiting for a battLevelChanged
# event could be futile, since the battery level might not change.
# Therefore, just busy wait for the device to record one.
battLevel=$(lipc-get-prop com.lab126.powerd battLevel 2>/dev/null)
while [[ -z "${battLevel}" ]]
do
if [[ "${DEBUG}" == 1 ]]; then (fn_loginfo "${CMD}" "waiting for battery level to be assigned") 2>> "${logfile}"; fi
sleep 10
battLevel=$(lipc-get-prop com.lab126.powerd battLevel 2>/dev/null)
done
# The same might be said of the isCharging property.
charging=$(lipc-get-prop com.lab126.powerd isCharging 2>/dev/null)
while [[ -z "${charging}" ]]
do
if [[ "${DEBUG}" == 1 ]]; then (fn_loginfo "${CMD}" "waiting for charging property to be assigned") 2>> "${logfile}"; fi
sleep 10
charging=$(lipc-get-prop com.lab126.powerd isCharging 2>/dev/null)
done
# Only establish a bluetooth connection if we are actively charging
# or the battery level is greater than the threshold that we've
# defined.
if [[ "${charging}" -eq 1 || "${battLevel}" -ge "${BATTLEVELTHRESHOLD}" ]]
then
# Ensure that the desired Bluetooth audio device is connected.
if [[ "${DEBUG}" == 1 ]]; then (fn_loginfo "${CMD}" "connecting to \"${connectToDevName}\"") 2>> "${logfile}"; fi
lipc-set-prop com.lab126.btfd Connect "${connectToDevAddr}"
# The following does not seem to have any effect. I thought maybe
# it might help keep the Bluetooth connection alive all the time.
#
# lipc-set-prop com.lab126.btfd ensureBTconnection 1
sleep 5 # Give the device a chance to connect.
# else, it's already connected.
fi
fi
processDeviceEvents.sh:
Note that it's too bad the busybox version of bash on the Kindle is not a full blown bash(1) implementation. It doesn't support associative arrays which would have been really useful.
Code:
#!/bin/bash
IFS="
"
PATH="/bin:/usr/bin:/sbin:/usr/sbin"
CMD=$(basename $0)
CMDPATH=$(dirname "$0")
if [[ "${CMDPATH}" == "" ]]; then CMDPATH="./"; fi
CMDPATH=$(realpath "${CMDPATH}")
source "${CMDPATH}/../config/config.sh"
source "${CMDPATH}/../bin/shLib/fn_logger.sh"
# We use the following to decrease the number of readyToSuspend events
# that we see when the screen saver is visible. See the readyToSuspend
# event processing for details.
DEFERSUSPEND=600 # 10 minutes in seconds.
# Note that the following will stop the device from ever going
# displaying the screen saver and going to sleep, even when
# pressing the power button:
#
# lipc-set-prop com.lab126.powerd preventScreenSaver 0
#
# To enable this support again invoke:
#
# lipc-set-prop com.lab126.powerd preventScreenSaver 1
#
# If we set preventScreenSaver to 1, the power button seems to be
# ignored totally and there isn't an even that we could grab
# while allowing our screen saver to appear to be able to
# know that we should stop the screen saver and set
# preventScreenSaver back to 0.
#
# This is not the behaviour that we want. We want to show
# a screen saver when the device would normally show a screen
# saver while preventing it from going to sleep while
# showing the screen saver if the device is plugged in.
# This was the default behavior of my Kindle Touch, but
# not the Kindle Signature 12th Gen. The Signature will
# suspend the device while showing the screen saver even
# if plugged in.
#
# We also want to allow the user to press the power button
# to exit the screen saver. Using the preventScreenSaver property,
# we would prevent this.
logfile="${LOGDIR}/screensaver"
inScreenSaverMode=false
playingMedia=false
mediafile=""
f_onexit() {
if [[ "${inScreenSaverMode}" == true ]]
then
# The wakeUp propery only exists when the device is displaying
# the screen saver.
lipc-set-prop com.lab126.powerd wakeUp 1
${CMDPATH}/startstop.sh stop
fi
if [[ "${DEBUG}" == 1 ]]; then (fn_loginfo "${CMD}" "exiting") 2>> "${logfile}"; fi
}
trap "f_onexit" EXIT SIGTERM
# Determine if the device is actively charging. It's
# possible that the device can be plugged in and isCharging
# be 0 (e.g., the battery is at 99% charged), meaning the
# device is allowing itself to discharge before entering a
# charging state again, so as to protect the battery.
#
# Therefore, we check both the charging indicator and battery level
# when determining whether or not we should prevent the device
# from suspending.
#
# On startup, battLevel could be "" and waiting for a battLevelChanged
# event could be futile, since the battery level might not change.
# Therefore, just busy wait for the device to record one.
battLevel=$(lipc-get-prop com.lab126.powerd battLevel 2>/dev/null)
while [[ -z "${battLevel}" ]]
do
if [[ "${DEBUG}" == 1 ]]; then (fn_loginfo "${CMD}" "waiting for battery level to be assigned") 2>> "${logfile}"; fi
sleep 10
battLevel=$(lipc-get-prop com.lab126.powerd battLevel 2>/dev/null)
done
# The same might be said of the isCharging property.
charging=$(lipc-get-prop com.lab126.powerd isCharging 2>/dev/null)
while [[ -z "${charging}" ]]
do
if [[ "${DEBUG}" == 1 ]]; then (fn_loginfo "${CMD}" "waiting for charging property to be assigned") 2>> "${logfile}"; fi
sleep 10
charging=$(lipc-get-prop com.lab126.powerd isCharging 2>/dev/null)
done
if [[ "${charging}" -eq 1 ]]
then
charging=true
else
charging=false
fi
if [[ "${DEBUG}" == 1 ]]; then (fn_loginfo "${CMD}" "initialized, inScreenSaverMode = ${inScreenSaverMode}, charging = ${charging}, battLevel = ${battLevel}") 2>> "${logfile}"; fi
printf 'com.lab126.powerd\ncom.lab126.btfd\ncom.daddo.media' |\
lipc-wait-event -l -m powerButtonPressed,charging,notCharging,battLevelChanged,goingToScreenSaver,outOfScreenSaver,readyToSuspend,suspending,Disconnect_Result,playingmedia,notplayingmedia 2>/dev/null |\
while read event
do
case "${event}" in
"Event Source"*|"Waiting for events"*)
# We can ignore these lines. These are reported by lipc-wait-event
# as confirmation that it is waiting on multiple sources.
#
# Example:
#
# Event Source: com.lab126.powerd
# Event Source: com.daddo.media
# Waiting for events...
continue
;;
esac
# $event contains all of the event details in the form:
#
# source name data
#
# where:
#
# data can contain multiple values, with string data enclosed in double
# quotes.
#
# We cannot use IFS substitution because the data
# may include spaces. Therefore, we just use cut.
source=$(echo "${event}" | cut -d ' ' -f1)
name=$(echo "${event}" | cut -d ' ' -f2)
# Given that the data associated with the event is a string, it
# will be enclosed in double quotes. Remove them.
data=$(echo "${event}" | cut -d ' ' -f3-)
if [[ "${DEBUG}" == 1 ]]; then (fn_loginfo "${CMD}" "${source} ${name} recvd, data = ${data}\", inScreenSaverMode = ${inScreenSaverMode}, charging = ${charging}, battLevel = ${battLevel}") 2>> "${logfile}"; fi
case "${event}" in
"com.lab126.powerd powerButtonPressed"*)
# This event is never dispatched for some reason.
;;
"com.lab126.powerd charging"*)
charging=true
;;
"com.lab126.powerd notCharging"*)
charging=false
;;
"com.lab126.powerd battLevelChanged"*)
battLevel=$(lipc-get-prop com.lab126.powerd battLevel 2>/dev/null)
;;
"com.lab126.powerd goingToScreenSaver"*)
${CMDPATH}/startstop.sh start
inScreenSaverMode=true
;;
"com.lab126.powerd outOfScreenSaver"*)
${CMDPATH}/startstop.sh stop
inScreenSaverMode=false
;;
"com.lab126.powerd readyToSuspend"*)
# Retrieve the current battery level in case the kindle is delayed in
# posting an update in its current value.
battLevel=$(lipc-get-prop com.lab126.powerd battLevel 2>/dev/null)
# busyBox's bash does not support the following:
#
#if (( "${inScreenSaverMode}" == true && ( "${charging}" == true || "${battLevel}" >= "${BATTLEVELTHRESHOLD}" ) ))
#
if [[ "${inScreenSaverMode}" == true ]] && [[ "${charging}" == true || "${battLevel}" -ge "${BATTLEVELTHRESHOLD}" ]]
then
# Don't let the device go to sleep.
#
# Older kindles do this already. If charging they never
# suspend even while the screen saver is visible. My
# Kindle Touch behaved this way; however, my Kindle
# Signature 12th Gen does not ... it will eventually
# suspend, even when charging.
if [[ "${DEBUG}" == 1 ]]; then (fn_loginfo "${CMD}" "deferring suspend") 2>> "${logfile}"; fi
# When the screen saver is visible, the device's framework dispatches
# a readyToSuspend event in 60 seconds. Aborting the suspend
# causes the device to dispatch another readyToSuspend in
# 60 seconds.
#
# Not doing anything (i.e., not aborting the suspension)
# results in the device suspending in 5 seconds.
#
# Setting deferSuspend (in seconds) can delay when the device
# goes into a suspend state (and a "suspending" event
# is dispatched).
#
# By default, the deferSuspend value is 5 seconds and
# this property is only available during the
# readyToSuspend event.
#
# The device resets deferSuspend to its default of 5 seconds
# each time it dispatches a readyTosuspend event.
#
# Increasing deferSuspend and then aborting the suspend has
# no effect. The device will dispatch another readyToSuspend
# event in 60 seconds instead of in deferSuspend seconds.
#
# Setting deferSuspend causes the device to dispatch
# another readyToSuspend event at the end of the given
# interval. Therefore, we use the deferSuspend property
# to reduce the number of readyToSuspend events that
# we see.
#
# We don't want to use a large value for this though, because
# we cannot change it outside of the readyToSuspend event
# processing. We can't, for example, decrease the value to
# allow for a more immediate suspension in the case the user
# removes the device from its charger and the battery level is
# low, or if the device is already not charging and the battery
# level decreases to a low level.
lipc-set-prop com.lab126.powerd deferSuspend "${DEFERSUSPEND}"
# If we were playing media at the time we received this event
# media playback was may have been interrupted. Repeat it if so.
if [[ ! -z "${mediafile}" ]]
then
if [[ "${DEBUG}" == 1 ]]; then (fn_loginfo "${CMD}" "replaying media, mediafile = \"$mediafile\"") 2>> "${logfile}"; fi
"${CMDPATH}/../bin/playMedia.sh" "${mediafile}"
fi
fi
;;
"com.lab126.powerd suspending"*)
lipc-set-prop com.lab126.powerd wakeUp 1
;;
"com.lab126.btfd Disconnect_Result"*)
# Force the kindle to reconnect to the bluetooth device so
# it is ready for the next time we want to use it and so
# the device itself does not go into a deep sleep. Battery powered
# speakers tend to go into a deep sleep if nothing is connected to
# them, even when plugged in.
#
# ${data} for this event will look like:
#
# 0 "EWA Audio A106Pro" "49:41:7E:DB:AD:F3"
#
status=$(echo "${data}" | sed -e 's/^\(.*\) "\(.*\)" "\(.*\)"$/\1/')
btdevname=$(echo "${data}" | sed -e 's/^\(.*\) "\(.*\)" "\(.*\)"$/\2/')
btdevaddr=$(echo "${data}" | sed -e 's/^\(.*\) "\(.*\)" "\(.*\)"$/\3/')
"${CMDPATH}/../bin/btconnect.sh" "${btdevname}" "${btdevaddr}"
;;
"com.daddo.media playingmedia"*)
playingMedia=true
mediafile="${data}"
;;
"com.daddo.media notplayingmedia"*)
playingMedia=false
mediafile=""
;;
*)
if [[ "${DEBUG}" == 1 ]]; then (fn_loginfo "${CMD}" "unsupported event (${event}) recvd") 2>> "${logfile}"; fi
;;
esac
done
The processDeviceEvents.sh script above is invoked by the following upstart script.
daddo_screensave.conf:
Code:
start on started lab126
script
(exec /bin/bash -c "/mnt/us/daddo/screensaver/processDeviceEvents.sh") &
return 0
end script