Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Thinkpad T400S BASh Management Tools
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Unsupported Software
View previous topic :: View next topic  
Author Message
der bastler
Apprentice
Apprentice


Joined: 13 Apr 2003
Posts: 244

PostPosted: Fri Mar 30, 2012 5:04 pm    Post subject: Thinkpad T400S BASh Management Tools Reply with quote

Introduction

I feel it's time to share some scripts with the community.

Recently I reviewed the setup of my T400S notebook. NetworkManager and Powerdevil got installed, syslog-ng and vixiecron were replaced by metalog and fcron. In the end I could retire my own system monitoring daemon and userspace tray icon application (see this post; the Sys XI HQ was heavily upgraded since then).

Anyway, now I could tidy up my collection of custom scripts for Thinkpad T400S hardware and would like to share them with other Thinkpad T400S owners. Perhaps they are portable to other Thinkpad models.

Changelog

2012-03-31: tp_get_messages.sh modified (chat error handling improved)
2012-04-03: Due to the USER environment variable not necessarily being defined (e.g. when called via baselayout's local service or ), USER is now explicitly defined using /usr/bin/id -un

Scripts

Name: /usr/local/bin/tp_bluetooth.sh
Purpose: control Bluetooth interface; called via acpid if Fn+F6 is pressed
Requirements: net-wireless/rfkill, net-wireless/bluez
Code:
Code:
#!/bin/bash
#-------------------------------------------------------------------------------
# Frank Abelbeck, March 2012
# manages built-in Bluetooth interface
#-------------------------------------------------------------------------------

USER="$(/usr/bin/id -un)"

case "$1" in
   on)
      if [ "$USER" == "root" ]; then
         /usr/sbin/rfkill unblock bluetooth &> /dev/null
      else
         echo "I'm sorry, $USER. I'm afraid I can't do that."
      fi
      ;;
   off)
      if [ "$USER" == "root" ]; then
         /usr/sbin/hciconfig hci0 down &> /dev/null
         /usr/sbin/rfkill block bluetooth &> /dev/null
      else
         echo "I'm sorry, $USER. I'm afraid I can't do that."
      fi
      ;;
   state)
      RFKILL="$(/usr/sbin/rfkill list bluetooth)"
      if /bin/expr match "$RFKILL" '.*Hard\ blocked\:\ yes' &> /dev/null; then
         echo "hard-blocked"
      elif /bin/expr match "$RFKILL" '.*Soft\ blocked\:\ no' &> /dev/null; then
         echo "on"
      else
         echo "off"
      fi
      ;;
   toggle)
      case "$($(/bin/readlink -f $0) state)" in
         on)
            $(/bin/readlink -f $0) off
            ;;
         off)
            $(/bin/readlink -f $0) on
            ;;
      esac
      ;;
   *)
      NAME="$(/bin/basename $0)"
      /bin/cat <<EndOfHelp
Thinkpad Bluetooth management program
Frank Abelbeck, March 2012

Usage: $NAME [on|off|state|toggle]

   $NAME on        switch on (unblock rf killswitch)
   $NAME off       switch off (take down hci device, block rf killswitch)
   $NAME state     report current state (on|off|hard-blocked)
   $NAME toggle    toggle state (on -> off and vice versa)

EndOfHelp
      ;;
esac


Name: /usr/local/bin/tp_wlan.sh
Purpose: control WLAN interface manually; acually, if the iwlwifi module is loaded, Fn+F5 controls the software killswitch without bothering acpid
Requirements: net-wireless/rfkill
Code:
Code:
#!/bin/bash
#-------------------------------------------------------------------------------
# Frank Abelbeck, March 2012
# manages built-in WLAN interface
#
# notice: if iwlwifi module is not loaded, wlan won't show up in rfkill
#         therefore we need to check module state via sysfs
#-------------------------------------------------------------------------------

USER="$(/usr/bin/id -un)"

case "$1" in
   on)
      if [ "$USER" == "root" ]; then
         if [ ! -e "/sys/module/iwlwifi/refcnt" ]; then
            /sbin/modprobe --quiet iwlwifi &> /dev/null
         fi
         /usr/sbin/rfkill unblock wlan &> /dev/null
      else
         echo "I'm sorry, $USER. I'm afraid I can't do that."
      fi
      ;;
   off)
      if [ "$USER" == "root" ]; then
         /usr/sbin/rfkill block wlan &> /dev/null
      else
         echo "I'm sorry, $USER. I'm afraid I can't do that."
      fi
      ;;
   state)
      RFKILL="$(/usr/sbin/rfkill list wlan)"
      if /bin/expr match "$RFKILL" '.*Hard\ blocked\:\ yes' &> /dev/null; then
         echo "hard-blocked"
      elif /bin/expr match "$RFKILL" '.*Soft\ blocked\:\ no' &> /dev/null; then
         echo "on"
      else
         echo "off"
      fi
      ;;
   toggle)
      case "$($(/bin/readlink -f $0) state)" in
         on)
            $(/bin/readlink -f $0) off
            ;;
         off)
            $(/bin/readlink -f $0) on
            ;;
      esac
      ;;
   *)
      NAME="$(/bin/basename $0)"
      /bin/cat <<EndOfHelp
Thinkpad WLAN management program
Frank Abelbeck, March 2012

Usage: $NAME [on|off|state|toggle]

   $NAME on        switch on (load module, unblock rf killswitch)
   $NAME off       switch off (unload module, block rf killswitch)
   $NAME state     report current state (on|off|hard-blocked)
   $NAME toggle    toggle state (on -> off and vice versa)

EndOfHelp
      ;;
esac


Name: /usr/local/bin/tp_wwan.sh
Purpose: control WWAN (UMTS) interface; called via acpid if ThinkVantage is pressed
Requirements: net-wireless/rfkill
Code:
Code:
#!/bin/bash
#-------------------------------------------------------------------------------
# Frank Abelbeck, March 2012
# manages built-in WWAN interface
#-------------------------------------------------------------------------------

USER="$(/usr/bin/id -un)"

case "$1" in
   on)
      if [ "$USER" == "root" ]; then
         /usr/sbin/rfkill unblock wwan &> /dev/null
      else
         echo "I'm sorry, $USER. I'm afraid I can't do that."
      fi
      ;;
   off)
      if [ "$USER" == "root" ]; then
         /usr/sbin/rfkill block wwan &> /dev/null
      else
         echo "I'm sorry, $USER. I'm afraid I can't do that."
      fi
      ;;
   state)
      RFKILL="$(/usr/sbin/rfkill list wwan)"
      if /bin/expr match "$RFKILL" '.*Hard\ blocked\:\ yes' &> /dev/null; then
         echo "hard-blocked"
      elif /bin/expr match "$RFKILL" '.*Soft\ blocked\:\ no' &> /dev/null; then
         echo "on"
      else
         echo "off"
      fi
      ;;
   toggle)
      case "$($(/bin/readlink -f $0) state)" in
         on)
            $(/bin/readlink -f $0) off
            ;;
         off)
            $(/bin/readlink -f $0) on
            ;;
      esac
      ;;
   *)
      NAME="$(/bin/basename $0)"
      /bin/cat <<EndOfHelp
Thinkpad WWAN management program
Frank Abelbeck, March 2012

Usage: $NAME [on|off|state|toggle]

   $NAME on        switch on (unblock rf killswitch)
   $NAME off       switch off (block rf killswitch)
   $NAME state     report current state (on|off|hard-blocked)
   $NAME toggle    toggle state (on -> off and vice versa)

EndOfHelp
      ;;
esac


Name: /usr/local/bin/tp_gps.sh
Purpose: control GPS module of WWAN device
Requirements: sci-geosciences/gpsd, net-dialup/ppp, tp_wwan.sh
Code:
Code:
#!/bin/bash
#-------------------------------------------------------------------------------
# Frank Abelbeck, March 2012
#-------------------------------------------------------------------------------
# Thinkpad GPS module management
#-------------------------------------------------------------------------------

USER="$(/usr/bin/id -un)"

if /bin/ps -eo "%a" | /bin/grep "^/usr/sbin/gpsd" &> /dev/null; then
   STATE="on"
else
   STATE="off"
fi

case "$1" in
   on)
      WWANSTATE="$(/usr/local/bin/tp_wwan.sh state)"
      if [ "$STATE" == "off" ] && [ "$WWANSTATE" != "hard-blocked" ]; then
         if [ "$USER" == "root" ]; then
            if [ "$WWANSTATE" == "off" ]; then
               /usr/local/bin/tp_wwan.sh on
               for ((i=0;i<10;i++)); do
                  if [ -c /dev/ttyACM1 -a -c /dev/ttyACM2 ]; then
                     break
                  else
                     /bin/sleep 1
                  fi
               done
            fi
            if [ -c /dev/ttyACM1 ] && [ -c /dev/ttyACM2 ]; then
               /usr/sbin/chat -V -t 3 '' 'AT*E2GPSCTL=1,1,0' 'OK' > /dev/ttyACM1 < /dev/ttyACM1 2> /dev/null && \
               /usr/sbin/chat -V -t 3 '' 'AT*E2GPSNPD' 'GPGGA' > /dev/ttyACM2 < /dev/ttyACM2 2> /dev/null && \
               /sbin/start-stop-daemon --start --exec /usr/sbin/gpsd -- -P /var/run/gpsd.pid /dev/ttyACM2 &> /dev/null
               if [ $? != 0 ]; then
                  echo "GPS activation failed."
               fi
            else
               echo "Could not activate WWAN device!"
            fi
         else
            echo "I'm sorry, $USER. I'm afraid I can't do that."
         fi
      fi
      ;;
   off)
      if [ "$USER" == "root" ]; then
         if [ $STATE == on ]; then
            /sbin/start-stop-daemon --stop --pidfile /var/run/gpsd.pid &> /dev/null
            /bin/rm -f /var/run/gpsd.pid &> /dev/null
            if [ -c /dev/ttyACM1 ]; then
               /usr/sbin/chat -V -t 3 '' 'AT*E2GPSCTL=0,0,0' 'OK' > /dev/ttyACM1 < /dev/ttyACM1 2> /dev/null
            fi
         fi
      else
         echo "I'm sorry, $USER. I'm afraid I can't do that."
      fi
      ;;
   state)
      echo "$STATE"
      ;;
   toggle)
      case "$STATE" in
         on)
            $(readlink -f $0) off
            ;;
         off)
            $(readlink -f $0) on
            ;;
      esac
      ;;
   *)
      NAME="$(/bin/basename $0)"
      /bin/cat <<EndOfHelp
Thinkpad GPS management program
Frank Abelbeck, March 2012

Usage: $NAME [on|off|state|toggle]

   $NAME on        switch on (start GPS device, start GPS daemon)
   $NAME off       switch off (stop GPS daemon, stop GPS device)
   $NAME state     report current state (on|off)
   $NAME toggle    toggle state (on -> off and vice versa)

EndOfHelp
      ;;
esac

_________________
Tempus fugit.


Last edited by der bastler on Tue Apr 03, 2012 6:05 am; edited 6 times in total
Back to top
View user's profile Send private message
der bastler
Apprentice
Apprentice


Joined: 13 Apr 2003
Posts: 244

PostPosted: Fri Mar 30, 2012 5:30 pm    Post subject: Reply with quote

Name: /usr/local/bin/tp_get_messages.sh
Purpose: download and convert text messages received via WWAN device; stores them in /var/spool/tp_messages
Requirements: net-dialup/ppp, tp_decode_pdu.sh (see below)
Code:
Code:
#!/bin/bash
#-------------------------------------------------------------------------------
# Frank Abelbeck, March 2012
#-------------------------------------------------------------------------------
# Thinkpad UMTS Modem text messages management
#-------------------------------------------------------------------------------

USER="$(/usr/bin/id -un)"
CURRDATE="$(date "+%s")"
MSGDIR="/var/spool/tp_messages"
RAWFILE="$MSGDIR/tp_wwan_messages.$CURRDATE.raw"
MBXFILE="$MSGDIR/tp_wwan_messages.$CURRDATE.txt"
TMPFILE="$MSGDIR/tmp.msg"

function do_it () {
   # check if device is up and not blocked; if it is: get message list
   if [ -c /dev/ttyACM1 ] && [ -z "$(/usr/bin/lsof /dev/ttyACM1)" ]; then
      for ((i=0; i<10; i++)); do
         RESULT="$(/usr/sbin/chat -V -t 3 '' 'AT+CMGL=4' 'OK' 2>&1 > /dev/ttyACM1 < /dev/ttyACM1)"
         if [ $? == 0 ]; then
            break
         else
            RESULT=""
         fi
      done
   else
      RESULT=""
   fi
   
   # process message list
   if [[ "$RESULT" == AT+CMGL=4*OK ]]; then
      echo "#index,state,alpha,length,pdu" > "$RAWFILE"
      PROCESSED=0
      while read LINE; do
         if [[ "$LINE" == +CMGL:* ]]; then
            MSG_HEADER="$(expr match "$LINE" '\+CMGL\:\ \(.*\)')"
            IFS=, read MSGINDEX MSGHDRREST <<<"$MSG_HEADER"
         else
            if [[ -n "$LINE" ]]; then
               echo "processing message at index $MSGINDEX"
               echo "$MSG_HEADER,$LINE" >> "$RAWFILE"
               /usr/local/bin/tp_decode_pdu.sh "$MSG_HEADER,$LINE" > "$TMPFILE"
               TIMESTAMP="$( date --date="$(sed -n 's/.*Date:\s*\([:graph:]*\)/\1/p' "$TMPFILE")" "+%s" )"
               MD5="$(/usr/bin/md5sum "$TMPFILE")"
               FILENAME="$MSGDIR/$TIMESTAMP.${MD5:0:32}.txt"
               if [ ! -e "$FILENAME" ]; then
                  /bin/mv "$TMPFILE" "$FILENAME"
                  echo "message at index "$MSGINDEX" written to file $FILENAME"
                  let "PROCESSED++"
               else
                  echo "message already stored, skipping..."
                  /bin/rm "$TMPFILE"
               fi
               if [ "$1" == "move" ]; then
                  DUMPRESULT="$(/usr/sbin/chat -V -t 1 '' 'AT+CMGD='$MSGINDEX',0' 'OK' 2>&1 > /dev/ttyACM1 < /dev/ttyACM1)"
                  echo "message at index "$MSGINDEX" deleted"
               fi
            fi
         fi
      done <<< "$(expr match "$RESULT" 'AT+CMGL=4\(.*\)OK')"
      case "$PROCESSED" in
         0)
            echo "There were no messages."
            ;;
         1)
            echo "One message was processed."
            ;;
         *)
            echo "$PROCESSED messages were processed."
            ;;
      esac
   else
      echo -e "Could not retrieve messages.\nEither WWAN device is deactivated or blocked by another program."
   fi
}

case "$1" in
   copy|move)
      if [ "$USER" == "root" ]; then
         do_it "$1"
      else
         echo "I'm sorry, $USER. I'm afraid I can't do that."
      fi
      ;;
   *)
      NAME="$(/bin/basename $0)"
      /bin/cat <<EndOfHelp
Thinkpad WWAN short messages reading program
Frank Abelbeck, March 2012

Usage: $NAME [copy|move]

   $NAME copy   copy messages from modem to $MSGDIR
   $NAME move   move messages from modem to $MSGDIR

EndOfHelp
      ;;
esac


The next one is actually quite ugly in code. As ugly as the PDU format. 8O

Name: /usr/local/bin/tp_decode_pdu.sh
Purpose: convert a message from PDU format into human-readable form; tool for tp_get_messages.sh (see above).
Requirements: --
Code:
Code:
#!/bin/bash
#-------------------------------------------------------------------------------
# Frank Abelbeck, March 2012
#-------------------------------------------------------------------------------
# Thinkpad UMTS Modem text messages management: PDU decoding
#-------------------------------------------------------------------------------

#
# char table source:
# http://www.dreamfabric.com/sms/default_alphabet.html
#
CHARTAB[0]="@"
CHARTAB[1]="£"
CHARTAB[2]="$"
CHARTAB[3]="¥"
CHARTAB[4]="è"
CHARTAB[5]="é"
CHARTAB[6]="ù"
CHARTAB[7]="ì"
CHARTAB[8]="ò"
CHARTAB[9]="Ç"
CHARTAB[10]="\n"
CHARTAB[11]="Ø"
CHARTAB[12]="ø"
CHARTAB[13]="\r"
CHARTAB[14]="Å"
CHARTAB[15]="å"
CHARTAB[16]="Δ"
CHARTAB[17]="_"
CHARTAB[18]="Φ"
CHARTAB[19]="Γ"
CHARTAB[20]="Λ"
CHARTAB[21]="Ω"
CHARTAB[22]="Π"
CHARTAB[23]="Ψ"
CHARTAB[24]="Σ"
CHARTAB[25]="Θ"
CHARTAB[26]="Ξ"
CHARTAB[27]=""
CHARTAB[28]="Æ"
CHARTAB[29]="æ"
CHARTAB[30]="ß"
CHARTAB[31]="É"
CHARTAB[32]=" "
CHARTAB[33]="!"
CHARTAB[34]="\""
CHARTAB[35]="#"
CHARTAB[36]="¤"
CHARTAB[37]="%"
CHARTAB[38]="&"
CHARTAB[39]="'"
CHARTAB[40]="("
CHARTAB[41]=")"
CHARTAB[42]="*"
CHARTAB[43]="+"
CHARTAB[44]=","
CHARTAB[45]="-"
CHARTAB[46]="."
CHARTAB[47]="/"
CHARTAB[48]="0"
CHARTAB[49]="1"
CHARTAB[50]="2"
CHARTAB[51]="3"
CHARTAB[52]="4"
CHARTAB[53]="5"
CHARTAB[54]="6"
CHARTAB[55]="7"
CHARTAB[56]="8"
CHARTAB[57]="9"
CHARTAB[58]=":"
CHARTAB[59]=";"
CHARTAB[60]="<"
CHARTAB[61]="="
CHARTAB[62]=">"
CHARTAB[63]="?"
CHARTAB[64]="¡"
CHARTAB[65]="A"
CHARTAB[66]="B"
CHARTAB[67]="C"
CHARTAB[68]="D"
CHARTAB[69]="E"
CHARTAB[70]="F"
CHARTAB[71]="G"
CHARTAB[72]="H"
CHARTAB[73]="I"
CHARTAB[74]="J"
CHARTAB[75]="K"
CHARTAB[76]="L"
CHARTAB[77]="M"
CHARTAB[78]="N"
CHARTAB[79]="O"
CHARTAB[80]="P"
CHARTAB[81]="Q"
CHARTAB[82]="R"
CHARTAB[83]="S"
CHARTAB[84]="T"
CHARTAB[80]="U"
CHARTAB[86]="V"
CHARTAB[87]="W"
CHARTAB[88]="X"
CHARTAB[89]="Y"
CHARTAB[90]="Z"
CHARTAB[91]="Ä"
CHARTAB[92]="Ö"
CHARTAB[93]="Ñ"
CHARTAB[94]="Ü"
CHARTAB[95]="§"
CHARTAB[96]="¿"
CHARTAB[97]="a"
CHARTAB[98]="b"
CHARTAB[99]="c"
CHARTAB[100]="d"
CHARTAB[101]="e"
CHARTAB[102]="f"
CHARTAB[103]="g"
CHARTAB[104]="h"
CHARTAB[105]="i"
CHARTAB[106]="j"
CHARTAB[107]="k"
CHARTAB[108]="l"
CHARTAB[109]="m"
CHARTAB[110]="n"
CHARTAB[111]="o"
CHARTAB[112]="p"
CHARTAB[113]="q"
CHARTAB[114]="r"
CHARTAB[115]="s"
CHARTAB[116]="t"
CHARTAB[117]="u"
CHARTAB[118]="v"
CHARTAB[119]="w"
CHARTAB[120]="x"
CHARTAB[121]="y"
CHARTAB[122]="z"
CHARTAB[123]="ä"
CHARTAB[124]="ö"
CHARTAB[125]="ñ"
CHARTAB[126]="ü"
CHARTAB[127]="à"

EXTCHARTAB[10]="\f"
EXTCHARTAB[20]="^"
EXTCHARTAB[40]="{"
EXTCHARTAB[41]="}"
EXTCHARTAB[47]="\\"
EXTCHARTAB[60]="["
EXTCHARTAB[61]="~"
EXTCHARTAB[62]="]"
EXTCHARTAB[64]="|"
EXTCHARTAB[101]="€"

STATE_UNREAD=0
STATE_READ=1
STATE_UNSENT=2
STATE_SENT=3
STATE_TEMPLATE=16

# helper function: swap pairs of characters in a string and remove trailing 'F' (filler)
function swap_chars () {
   TMP=""
   for ((k=0;k<2*$SC_ADDR_LEN;k+=2)); do
      TMP="$TMP${1:$k+1:1}${1:$k:1}"
   done
   echo "${TMP%F}"
}


# helper function: decode 7bit text
# (hex -> bits -> 7 bit per character as well as bit swapping...)
function decode_7bit_text () {
   CONTENT_HEX="$1"
   CONTENT_LENGTH="${#CONTENT_HEX}"
   CONTENT_BITS=""
   for ((k=0;k<$CONTENT_LENGTH;k+=2)); do
      CONTENT_BITS="$(printf "%08i" $(echo "ibase=16; obase=2; ${CONTENT_HEX:$k:2}" | bc))$CONTENT_BITS"
   done
   for ((k=${#CONTENT_BITS}-7;k>=0;k-=7)); do
      CHARBIT6="${CONTENT_BITS:k:1}"
      CHARBIT5="${CONTENT_BITS:k+1:1}"
      CHARBIT4="${CONTENT_BITS:k+2:1}"
      CHARBIT3="${CONTENT_BITS:k+3:1}"
      CHARBIT2="${CONTENT_BITS:k+4:1}"
      CHARBIT1="${CONTENT_BITS:k+5:1}"
      CHARBIT0="${CONTENT_BITS:k+6:1}"
      let "CHARACTER = 64*$CHARBIT6 + 32*$CHARBIT5 + 16*$CHARBIT4 + 8*$CHARBIT3 + 4*$CHARBIT2 + 2*$CHARBIT1 + $CHARBIT0"
      if [ "$CHARACTER" == "27" ]; then
         CHARBIT6="${CONTENT_BITS:k+7:1}"
         CHARBIT5="${CONTENT_BITS:k+8:1}"
         CHARBIT4="${CONTENT_BITS:k+9:1}"
         CHARBIT3="${CONTENT_BITS:k+10:1}"
         CHARBIT2="${CONTENT_BITS:k+11:1}"
         CHARBIT1="${CONTENT_BITS:k+12:1}"
         CHARBIT0="${CONTENT_BITS:k+13:1}"
         let "CHARACTER = 64*$CHARBIT6 + 32*$CHARBIT5 + 16*$CHARBIT4 + 8*$CHARBIT3 + 4*$CHARBIT2 + 2*$CHARBIT1 + $CHARBIT0"
         echo -n "${EXTCHARTAB[$CHARACTER]}"
      else
         echo -n "${CHARTAB[$CHARACTER]}"
      fi
   done
}

# split comma-separated AT+CMGL command output
IFS=, read MSG_INDEX MSG_STATE MSG_ALPHA MSG_LENGTH PDU <<<"$*"

case "$MSG_STATE" in
   0) MSG_STATE="unread" ;;
   1) MSG_STATE="read" ;;
   2) MSG_STATE="unsent" ;;
   3) MSG_STATE="sent" ;;
   4) MSG_STATE="dontcare" ;;
   *) MSG_STATE="unknown" ;;
esac

#
# extract service center address: get length, read address, swap digits (9471 -> 4917)
#
SC_ADDR_LEN=$(printf "%d" "0x${PDU:0:2}")
SC_ADDR_TYPE=${PDU:2:2}
SC_ADDR="${PDU:4:2*$SC_ADDR_LEN-2}"
case "$SC_ADDR_TYPE" in
   D0)
      SC_ADDR="$(decode_7bit_text "$SC_ADDR")"
      ;;
   *)
      SC_ADDR="$(swap_chars "$SC_ADDR")"
      ;;
esac
let "I = 4 + 2*$SC_ADDR_LEN"

#
# extract sender address: get length, read address, swap digits (9471 -> 4917)
# length describes number of digits of address; if it's odd, we need to round it up to be able to fetch pairs...
#
FROM_ADDR_LEN="$(printf "%d" "0x${PDU:$I:2}")"
FROM_ADDR_TYPE="${PDU:$I+2:2}"
let "FROM_ADDR_LEN += $FROM_ADDR_LEN % 2"
FROM_ADDR="${PDU:$I+4:$FROM_ADDR_LEN}"
case "$FROM_ADDR_TYPE" in
   D0)
      FROM_ADDR="$(decode_7bit_text "$FROM_ADDR")"
      ;;
   *)
      FROM_ADDR="$(swap_chars "$FROM_ADDR")"
      ;;
esac
let "I = $I + 4 + $FROM_ADDR_LEN + 4"

#
# extract timestamp
#
TIMESTAMP="${PDU:$I:14}"
YEAR="${TIMESTAMP:1:1}${TIMESTAMP:0:1}"
MONTH="${TIMESTAMP:3:1}${TIMESTAMP:2:1}"
DAY="${TIMESTAMP:5:1}${TIMESTAMP:4:1}"
HOUR="${TIMESTAMP:7:1}${TIMESTAMP:6:1}"
MINUTE="${TIMESTAMP:9:1}${TIMESTAMP:8:1}"
SECOND="${TIMESTAMP:11:1}${TIMESTAMP:10:1}"
TZ="$(printf "%d" "0x${TIMESTAMP:13:1}${TIMESTAMP:12:1}")"
if [ $TZ -ge 128 ]; then
   let "TZ -= 128"
   TZ_SIGN="-"
else
   TZ_SIGN="+"
fi
let "TZ_HOUR = $TZ / 4"
let "TZ_MINUTE = $TZ % 4"
TIMESTAMP="$(printf "20%s-%s-%s %s:%s:%s%s%02i%02i" $YEAR $MONTH $DAY $HOUR $MINUTE $SECOND $TZ_SIGN $TZ_HOUR $TZ_MINUTE)"

CONTENT_LEN="$(printf "%d" 0x"${PDU:$I+14:2}")"
let "CONTENT_LEN = ($CONTENT_LEN * 7 + 7) / 8" # bash truncates integer divs, so add denominator-1 to numerator
CONTENT_STR=$(decode_7bit_text "${PDU:$I+16:2*$CONTENT_LEN}")

echo "Header: i=$MSG_INDEX, state=$MSG_STATE, alpha=$MSG_ALPHA, length=$MSG_LENGTH"
echo "Service Center: $SC_ADDR"
echo "From: $FROM_ADDR"
echo "Date: $TIMESTAMP"
echo ""
echo "$CONTENT_STR"


Name: /usr/local/bin/tp_battery_charge_mode.sh
Purpose: configure battery charge mode via tp_smapi. Three profiles are defined: charge, discharge and normal mode, with the latter keeping the battery idle at about 2/3 of her capacity. That's quite good when you are connected to AC most of the time, it extends the battery's lifetime.
Requirements: app-laptop/tp_smapi
Code:
Code:
#!/bin/bash
#-------------------------------------------------------------------------------
# Frank Abelbeck, March 2012
# manages battery behaviour by manipulating SMAPI values
#-------------------------------------------------------------------------------

USER="$(/usr/bin/id -un)"

function print_help () {
NAME="$(/bin/basename $0)"
/bin/cat <<EndOfHelp
Thinkpad Battery management program
Frank Abelbeck, March 2012

Usage: $NAME [main|ultrabay] [charge|discharge|normal]

   $NAME main charge      charge main battery if capacity < 90 %
   $NAME main discharge   force discharge of main battery if capacity > 10 %
   $NAME ultrabay state   report state of UltraBay battery (if installed)

EndOfHelp
}

function set_values () {
   if [ "$USER" == "root" ]; then
      echo $2 > "$1/start_charge_thresh"
      echo $3 > "$1/stop_charge_thresh"
      echo $4 > "$1/force_discharge"
   else
      echo "I'm sorry, $USER. I'm afraid I can't do that."
   fi
}

case "$1" in
   main)
      BATDIR=/sys/devices/platform/smapi/BAT0
      ;;
   ultrabay)
      BATDIR=/sys/devices/platform/smapi/BAT1
      ;;
   *)
      print_help
      BATDIR=""
      ;;
esac

if [ -n "$BATDIR" ] && [ -e "$BATDIR" ]; then
   if [ "$(<"$BATDIR/installed")" == "0" ]; then
      echo "The battery is not installed."
   else
      case "$2" in
         fill|charge)
            set_values "$BATDIR" 90 100 0
            ;;
         drain|discharge)
            set_values "$BATDIR" 10 100 1
            ;;
         normal)
            set_values "$BATDIR" 40 70 0
            ;;
         state)
            echo "$1 $(<"$BATDIR/start_charge_thresh") $(<"$BATDIR/stop_charge_thresh") $(<"$BATDIR/force_discharge")"
            ;;
         *)
            print_help
            ;;
      esac
   fi
fi

_________________
Tempus fugit.
Back to top
View user's profile Send private message
der bastler
Apprentice
Apprentice


Joined: 13 Apr 2003
Posts: 244

PostPosted: Fri Apr 20, 2012 6:23 pm    Post subject: Reply with quote

Well, after some weeks of testing I've unmerged NetworkManager and Powerdevil. Too big, too black-boxy.

I'll continue with some of my old scripts to bring the modem up/down, get modem information, manage A/C plug events, hibernate, keep UMTS up even when carrier gets lost once in a while...

But instead of using my custom bash daemon (i.e. polling unnecessarily), they will be hooked into metalog. This way I can create a stateless event-based automation of my Thinkpad -- a good testbed for my PhD thesis topic... :-)
_________________
Tempus fugit.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Unsupported Software All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum