duhow / xiaoai-patch

Patching for XiaoAi Speakers, add custom binaries and open source software. Tested on LX06, LX01, LX05, L09A
GNU General Public License v3.0
191 stars 30 forks source link

L09A - Xiaoai Speaker Art #2

Closed mah8050 closed 3 years ago

mah8050 commented 3 years ago

To add more details on L09A Xiaoai Speaker Art which speaks in chinese. Model number: L09A Firmware Version: 1.64.4 updated to 1.68.1 Boot: boot.txt If failed to boot several times rolls back to 1.64.4 which doesn't need magic number to log in

duhow commented 3 years ago

Ok, first of all do a backup of flash memory and store it in two different places (just ensure don't lose the original files).

pc# for N in $(seq 0 6); do ncat -vlp 8888 > mtd${N}; done
mico# for N in $(seq 0 6); do dd if=/dev/mtdblock${N} | nc YOUR_COMPUTER_IP 8888; done

Clone this repo to your computer, on patches folder delete all files except 10_ssh.patch, on scripts folder delete all files except:

00_start.sh
10_apply_patches.sh
94_copy_bin.sh
99_end.sh

No need to run packages.sh at the moment, we want to ensure this patching works, so this basic changes should just enable SSH login and copy few scripts.

Next, by logs it shows that the current boot is boot0, hence you're using mtd2 (boot0) and mtd4 (system0). Since you say you have the other version 1.64.4 available, it means mtd3 (boot1) and mtd5 (system1) are not empty. Check file xxd mtd3 | less and see if it has content or not (all FF FF).

You may want to keep this lower version for the moment since it's not very protected, but you can test whichever you want, it will be used to patch and pack.

So assuming we use mtd5 (which should be 1.64.4):

sudo make extract FILE=mtd5
sudo make patch
sudo make build

This will generate a new squashfs image in release folder, check the type is exactly the same:

file mtd5 release/image-*
binwalk mtd5 release/image-*

With the squashfs-root folder, ensure the SSH service is patched to allow running the service. Otherwise you can manually change the file/s and run sudo make build again.

We want to ensure compression and blocksize is equal (defaults compression xz and blocksize 131072 bytes). If blocksize is 262144 bytes, then run:

sudo make build MODEL=lx01

If L09A behaves similar to LX06, then you should be able to run this:

fw_env -g boot_part

And this would return boot0 - your current boot. Change to boot1 and reboot.

df  # check current mtdblock partition
fw_env -s boot_part boot1
sync
reboot

Upon reboot check if the root partition changed with df again.

Last, in order to flash the content: We want a copy of the current boot mtd3 to the other boot partition mtd2, to use same kernel.

dd if=/dev/mtdblock3 of=/dev/mtdblock2 bs=4096

Let's flash the patched image and check we have SSH working and enabled! Remember you have to flash the system partition that is not in use, so if currently you're using mtd5, we want to flash mtd4.

pc# ncat -vlp 8888 < release/latest

mico#
nc YOUR_COMPUTER_IP 8888 > /tmp/update.img
dd if=/tmp/update.img of=/dev/mtdblock4 bs=4096
fw_env -s boot_part boot0
sync
reboot

If all went successfully, you should have the new content available. Remember to have Uboot available in emergency case to change the misc / environment values.

mah8050 commented 3 years ago

Nice. everything went smoothly. docker worked very well without even an error thanks for that I compiled all scripts and backed up all partitions but patched just partition mtd4 which was not active at that moment. in u-boot instead, I just changed env variable using setenv boot_part boot0 and the board booted up with SSH enabled. I had a problem using nc to copy image back to the board so I used scp on board and worked. until now root password isn't working keys are confused and no audio, but wifi is ok Root password seems to be changed. I cannot login to both serial and SSH. It seems to be my fault for applying all patches.

duhow commented 3 years ago

You may try changing the boot partition to previous one via Uboot: env set boot_part bootX; env save. LX06 allows to change with buttons by pressing [-] volume button while booting (check that content in /init file). /etc/shadow password may be mounted on the ubifs partition and defaults to the same as in system (squashfs). I don't think password is tina as in the old speakers...

mah8050 commented 3 years ago

Solved. I dont know but may have patched newer firmware (1.68.1) by mistake and because of that magic number thing ssh password didn't work. but it didn't spit that magic number. now I did everything again and have SSH access. i think my next step would be geting rid of that chinese voice in the speaker Thanks man

duhow commented 3 years ago

Now it's just a matter of testing the patches and scripts, prepare the full packages in Docker, then make clean, extract, patch and build. Maybe some patches won't work because each speaker has different configuration, so I'd appreciate if you provide changes in PR :)

mah8050 commented 3 years ago

ok after some playing around: there are lots of differences in L09A, just SSH patch works fine . it maybe because of different firmware versions. tried many changes in scripts but no luck and in all situations after patching i cannot login and volume + button brings orange light. I can't find out what happened to shadow file that doesn't let me login.

duhow commented 3 years ago

@mah8050 if you can share with me the mtd partitions except mtd6 (data) I may try do some checks from code available. I've ordered another Xiaoai Art Speaker - hopefully it is not updated and I can test as well physically.

mah8050 commented 3 years ago

Yes sure mtd1-2-3.zip

mtd4 is 1.68.1 : https://drive.google.com/file/d/1DSmBLOmfniefIUYxb-19D2ea47yZIciL/view?usp=sharing mtd5 is 1.64.4 : https://drive.google.com/file/d/1VDFZHQoylkb06dHGc8izldiDLo0clQgb/view?usp=sharing

duhow commented 3 years ago

Recovery key code seems to have changed. After power on, instead of just pressing the [-] button, you need to keep pressing [-], then confirm with pressing [+] within two seconds, otherwise it continues normal booting and Red LED turns off.

Regarding password magic, in old version there's still the mi_console so you can generate the password hash with it. New firmware contains an MD5 password, I'll try to see if I can recover it...

duhow commented 3 years ago

Password authentication comes from /lib/security/libmico-pam.so and /etc/pam.d/common-auth, it is also forced in sshd auth login. Lib also contains a public DSA key... Sounds interesting, but I'd rather remove it instead of investigating further. :joy:

So in order to unlock you, maybe you can try setting the Uboot bootargs to run /bin/sh with serial cable, and having a functional shell in there, update the /data shadow password.

mah8050 commented 3 years ago

but I simply copied shadow file from /etc/shadow of working one into patched files and solved and after running df I understood where the problem was. in working one I have:

root@L09A:/etc# df                                                                                           
Filesystem           1K-blocks      Used Available Use% Mounted on                                           
/dev/mtdblock4           28544     28544         0 100% /                                                    
tmpfs                    59308      1152     58156   2% /tmp                                                 
tmpfs                      512         0       512   0% /dev                                                 
/dev/ubi0_0              13760      1888     11132  15% /data                                                
/dev/ubi0_0              13760      1888     11132  15% /etc/shadow   

and in pached one which is now booted into I have:

root@L09A-9738:/etc/init.d# df                                                                               
Filesystem           1K-blocks      Used Available Use% Mounted on                                           
/dev/mtdblock5           38528     38528         0 100% /                                                    
tmpfs                    59308       100     59208   0% /tmp                                                 
tmpfs                      512         0       512   0% /dev                                                 
/dev/ubi0_0              13760      1948     11076  15% /data

See the last line is not mounted, which seems to be a symlink to somewhere hidden in data partition

mah8050 commented 3 years ago

After some days I had time to work on the speaker again. The first and most important is that ALSA records faster and with higher pitch so porcupine and speak to text are not able to recognize voice. it's about 3 times faster than normal what I know about it till now is that aplay command works normally, it can play any other voice like normal but with arecord or even ffmpeg there is a problem in recording that leads to voice being recorded faster than normal I've tried any configuration and any bit rate and no difference. do you have any solution? I tested the word alexa , by recording 'Alexa' on my phone and playing back in 1/3x with lower pitch and it worked! PS: Is it possible for you to send me example of config files that are placed on /data partition?

duhow commented 3 years ago

If you check /etc/asound.conf, you'll see a lot of PCM devices. Default playback audio passes through dtsaudio > dtsladspa filter and finally plays at dmixer with hardware hw:0,2. Microphone on the other way is mico_record, which records in noop and finally to hardware hw:0,3.

I remember also having this problem but I'm not sure if it was because of the speaker which did this conversion, or the microphone. Can you share the command you're using to record audio? You should be recording by using -D mico_record.

Also, did you try the following patches?

patches/24_alsa_change_default.patch
patches/25_alsa_remove_dts.patch

/data files are for Xiaoai and other program config (MPD, Upmpdcli) and also to customize the scripts to listen (KEY=value) if you want to change to other values, not really used for ALSA, although you can copy the asound.conf file and do mount --bind to apply that customized file to read-only /etc partition.

mah8050 commented 3 years ago

Record using this command: arecord -N -D mico_record -d 5 -f S16_LE -c 8 -r 16000 /tmp/rec.wav And also tried: ffmpeg -i mico-record -f wav -ac 1 -ar 16000 -y /tmp/rec.wav This is my asound.conf

------------------------------------------------
root@L09A-9738:~# cat /etc/asound.conf
pcm.!default {
  type asym
  playback.pcm "general"
  capture.pcm "mico_record"
}

pcm.general {
  type plug
  slave {
    pcm {
      type softvol
      slave.pcm dmixer
      control{
        name "mysoftvol"
        card 0
      }
      min_dB -51.0
      max_dB 0.0
    }
    channels 2
    format S16_LE
    rate 48000
  }
}

pcm.bluetooth {
  type plug
  slave {
    pcm {
      type softvol
      slave.pcm dmixer
      control{
        name "bluetooth"
        card 0
      }
      min_dB -51.0
      max_dB 0.0
    }
    channels 2
    format S16_LE
    rate 48000
  }
}

pcm.notify {
  type plug
  slave {
    pcm {
      type softvol
      slave.pcm dmixer
      control{
        name "notifyvol"
        card 0
      }
      min_dB -51.0
      max_dB 0.0
    }
    channels 2
    format S16_LE
    rate 48000
  }
}

pcm.dtsaudio {
        type plug
        slave.pcm "dtsladspa"
}

pcm.dtsladspa {
        type ladspa
        slave.pcm plug:dmixer
        channels 2
        path "/usr/lib/"
        playback_plugins [{
        label dts_process
                input {
                        controls [4]
                }
        }]
}

pcm.dmixer  {
   type dmix
   ipc_key 1024
   slave {
      pcm "hw:0,2"
      format S16_LE
          period_size 1920
          buffer_size 7680
      rate 48000
   }
   bindings {
      0 0
      1 1
   }
}

ctl.dmixer {
   type hw
   card 0
   device 1
}

pcm.dsp {
    type plug
    slave.pcm "dmixer"     # use our new PCM here
}

ctl.mixer {
    type hw
    card 0
}

pcm.dis {
        type plug
        slave.pcm noop
}
pcm.mico_record {
        type plug
        slave.pcm noop
}

pcm.noop {
   type dsnoop
   ipc_key 1024
   slave {
     pcm "hw:0,3"
         format S32_LE
         rate 48000
         channels 8
         period_size 4096
   }
}

defaults.pcm.rate_converter "speexrate_medium"
root@L09A-9738:~#
duhow commented 3 years ago

Ok, in that case seems that the default device should be mico_record. Maybe the problem is the playback command itself. You're recording at 16k, while playing at 48k (1/3) . Did you check if the audio recorded sounds ok in your computer? Does other audio playback have this same issue? With mpd or mpg123?

mah8050 commented 3 years ago

Yes I copied recorded file from device to my pc and it's recorded in 3x speed I've tried all kinds of different settings but no luck Even tried recording in 48k and nothing changed I'm sure it's record problem, not playback problem. When I use -d 5 in record command line to indicate record duration instead of 5 seconds the record takes 15 seconds to end!

duhow commented 3 years ago

I added an ALSA patch for L09A, try pulling changes and see if it does any change. Also I bought one L09A, hopefully will arrive this week and I'll do some tests as well.

mah8050 commented 3 years ago

applied the patch to asound.conf and no difference, but just after reducing channel count to 4 in asound.conf everything is normal again change from:

pcm.noop {                
   type dsnoop            
   ipc_key 1024           
   slave {                
     pcm "hw:0,3"         
         format S32_LE    
         rate 48000       
         channels 8       
         period_size 4096 
   }                      
}                 

To:

pcm.noop {                
   type dsnoop            
   ipc_key 1024           
   slave {                
     pcm "hw:0,3"         
         format S32_LE    
         rate 48000       
         channels 4       
         period_size 4096 
   }                      
}                 

I think there may be a hardware thing like buffering or file system problem. but with this change me and porcupine are happy :)) PS: when listener service is running the problem appears again even with channel count 4 and some extra info here: again I've changed asound.conf due to gettin 'snd_pcm_readi' failed with 'Broken pipe' error randomly

pcm.noop {
   type dsnoop
   ipc_key 1024
   slave {
     pcm "hw:0,3"
         format S32_LE
         rate 16000
         channels 4
         period_size 4096
   }
}
duhow commented 3 years ago

Just got my L09A, my version is 1.54.10, way too "old" than yours - 2020-06-16 lol Let me do some tests and I'll try to update shortly!

duhow commented 3 years ago

BTW - swap boot partition buttons are [-] and [Play].

duhow commented 3 years ago

https://github.com/duhow/xiaoai-patch/commit/a67d3b39e476545272360f3643b41fb7417cd96b now this works :)

mah8050 commented 3 years ago

Confirmed. :100: