1

I'm trying to control a Kasa Smartplug from an Axis embedded Linux product by following what George Georgovassilis has done here: https://blog.georgovassilis.com/2016/05/07/controlling-the-tp-link-hs100-wi-fi-smart-plug/ I've managed to switch the plug on and off from the Axis box but I've come unstuck trying to query the on/off status of the Smartplug because I don't have od (or hd, hexdump or xxd) and the Smartplug output is binary. The snippet of George's code which does this is:

decode(){
    code=171
    input_num=`od $ODOPTS`
    IFS=' ' read -r -a array <<< "$input_num"
    args_for_printf=""
    for element in "${array[@]}"
    do
        output=$(( $element ^ $code ))
        args_for_printf="$args_for_printf\x$(printf %x $output)"
        code=$element
    done
    printf "$args_for_printf"
 }

Is there a way I can do this using basic shell commands instead of using od please? The Axis box says it's Linux 2.6.29 on a crisv32 I used to use Unix about 30 years ago so I'm struggling...

Prometheus
  • 11
  • 1
  • `Is there a way I can do this using basic shell commands instead of using od please?` Do what exactly? What does the code do? How is it related to the description? What is the intput (is ODOPTS the input?)? What is the output? From the name `decode` it's probably "decoding" something. What is decoding? In what format is it stored? To what format is it decoding the data into? Do you have any compiler on that box? You might want to just write a short C program that will do the job of `od`. Or perl (what version?)? Python? – KamilCuk Dec 20 '20 at 15:22
  • I think $input_num is the binary output from the Smart Plug. There is one bit of interest which says whether the plug is on or not. The decode function is taking the binary output and producing a formatted string to say whether the plug is on or off. I would like to do the same, ideally just using shell script, but without relying on od. ODOPTS is the options to the od command, I think is specifying octal. There isn’t a compliler. I do have access to a Lubuntu machine I could cross-compile on, but that’s not something I have done before. – Prometheus Dec 20 '20 at 17:01
  • so perl or not? Most linux machines have perl. `producing a formatted string` Formatted in what way? All it prints are `\x$(...)` - some unknown _bytes_. Why the code does the binary operation `element ^ code`? I'm asking, because this looks like XY question - you _don't care_ about translating bytes in file to octal numbers, the code seems to calculate some output which is _really_ what is interesting. How is the output calculated? It may happen that there are _way_ simpler way of calculating it. Do you have `awk`? `sed`? Do you have `bc`? – KamilCuk Dec 20 '20 at 17:23
  • 1
    ++ for posting some serious code, but -- for not boiling it down to an [mcve]. If you get tripped up by the general nature of that link, then read, review and take to heart the items on this page : https://stackoverflow.com/tags/bash/info . Search for "Before asking about Problematic code" and "How to turn a bad script into a good question" .Good luck. – shellter Dec 20 '20 at 20:01

2 Answers2

2

Octal dump in Linux shell without od or hd

Seems simple enough with awk. Borrowing code from this answer and splitting from this answer it's simple to:

awk -v ORS='' -v OFS='' 'BEGIN{ for(n=0;n<256;n++)ord[sprintf("%c",n)]=n }  
    { split($0, chars, "");
    chars[length($0)+1]=RS; # add the newline to output. One could check if RS is empty.
    # and print
    for (i=1;i<=length($0)+1;++i) printf("%o\n", ord[chars[i]]) }'
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • No awk I’m afraid but this is really helpful and might give me a start. Thanks for your help. I don’t properly understand the code snippet I’ve posted but I think it’s just one bit in a fixed position which I need, so I should be able to keep it simple. – Prometheus Dec 20 '20 at 21:05
0

I managed to solve this in the end: I couldn't work out how to replicate od using just the shell commands available on the target machine, so I created a very simple C program to read each byte from the binary and print it out as a readable character. That included replicating the weird XOR, which seems to be something to do with rudimentary encryption (probably). I then pulled out the value which I needed using sed. Cross-compiling this C on my Lubuntu machine for the target CRIS architecture wasn't too difficult for a simple program. Everything was much easier once I'd reduced the model code to a minimal reproducible example for myself. Thanks all.

Prometheus
  • 11
  • 1