Xperia Z4 TabletでFullバックアップを試す

セットアップ済み端末から、.ftf を再生成できればもしかすると… 気になって試してみたメモです。わかっていたことですが、root化できないとダメみたいです。

以下メニューがそれを示すのでしょうか? “Root access denid(拒否)“となりダメでした。

検索すると “Backup-TA” なるツールが見つかります。2010年代前半と古いものです。SUコマンド がないとダメでした。(しかしよくよくみると当ツールは Flash Tool に含まれているようです)

root化で検索すると “EASY Rooting Toolkit” が見つかります。これはソースコードだけでした。Android StduioNDK を追加し、make をかけます。コードが古く、#include漏れ、変数型不足、prototype宣言不足だらけでかなり修正しましたが Build できました。adb /data/local/tmp に転送し、実行しても無反応でした。(しかしよくよくみると当ツールは Flash Tool に含まれているようです)

これも実行ファイル、スクリプト、Superuser.apk 等を、adb /data/local/tmp に転送し実行するものでした。BusyBox(バイナリ結合コマンド)も転送しているので、bootバイナリにroot権限を埋込しそうです。しかし動作しますが成果は無しです。

あと実行するとウイルス検知されます。ヤバいやつです。


バックアップから .ftf 生成するには、root化が肝のようです。XDAで最新の手法を見ると、

  • boot loader をunlock
  • .ftf から .sin を展開し、boot.img を取出し。
  • Andeoid 上で、magisk のapkをインストール後、boot.img にroot権限を付与。
  • fastboot flash boot で、boot.img を書き込み。

実施するには実験用の SGP771 か SGP712 が必要ですね。

Javaと組込み機器Cで通信するときの留意事項

AndroidアプリなどJava言語と、組込み機器C言語で通信させるとき、せちがらい制約があります。その制約と対応方法の覚書です。

古くはVB6(VBA)C#Switf には構造体はありますが Java だけなんで?て感じです。Java側でByte配列へ編集もしくは分解するしかないようです。以下事例です。

組込み側

///  BTスレーブ要求フレーム ///
typedef struct _ST_SLAVE_REQ {
  uint8_t		head[ 4 ];	// HERAER兼パケット識別
 	uint16_t	len;		    // パケット長
 	uint16_t	req;		    // 要求コード
  uint8_t		foot[ 4 ];	// FOOTER
 	uint16_t	csum;		    // CHECKUSUM
} ST_SLAVE_REQ;
// Memo: 実際にはCPUアーキテクチャによってパウンダリ調整なし、2byte調整、4byte調整があるのでよく確認します。

Java側 :

///  BTスレーブ要求フレーム ///
short   frmLen = 14;
byte[]  buff = new byte[frmLen];

copyBytes(buff, 0, appCom.ID_SLAVE, 4 );          // 4: HERAER兼パケット識別
copyBin16(buff, 4, frmLen );            	        // 2: パケット長
copyBin16(buff, 6, appCom.REQ_START_MONITER );  	// 2: 要求コード
copyBytes(buff, 8, appCom.ID_TAIL, 4 );           // 4: HERAER兼パケット識別
short   csum = checksum(buff, frmLen - 2);        // Checksum
copyBin16(buff, 12, csum );            	           // 2: Checksum

Bundle arg = new Bundle();
arg.putByteArray( "BINARY",  buff );     // BIN DATA

WriteValueBLE( mServiceCANonNUS, mMessengerCANonNUS, arg );

byteコピー などはメソッドを追加します。web検索すると Unsafe.copyMemory なるものがでてきますが作った方が早い!

    ///////////////////////////////////////////////////
    // Byteコピー
    ///////////////////////////////////////////////////
    public boolean copyBytes(
        byte[]  to,
        int     offset,
        byte[]  from,
        int     len
    ) {
        if ( from.length < len ) {  // ちゃんと実体sizeをちぇっくしましょう。
            return false;
        }

        if ( to.length - offset < len ) {
            return false;
        }

        for( int i = 0; i < len; i ++ ) {
            to[ i + offset ] =  from[ i ];
        }
        return true;
    }

unit16変換関数を作ります。バイトオーダーは組込み機器側のCPUアーキテクチャに合せます。

///////////////////////////////////////////////////
// int16コピー
///////////////////////////////////////////////////
public boolean copyBin16(
    byte[]  to,
    int     offset,
    short   from
) {
    if ( to.length - offset < 2) {
        return false;
    }

    // ARMはリトルエンディアン
    to[ 0 + offset ] =  (byte)( from % 256 );
    to[ 1 + offset ] =  (byte)( from / 256 );
    return true;
 }


似たような言語では、C#はあり、Switf は無いようです。 (アプリだけ作ってる方々は、組込み機器ではsignedを基本使わないこと自体あまり知られていないのかもしれませんが…)

以下の場合、Java側で正しい値になりません。以下例では、frm.len は 4002( 0x9C42) となり、Java側で 0x9C がUnder Flow し -100 となります。そのまま extractBin16 で加算されると66 (0x42) + -100 * 256 = -25,534 と全く異なる値になってしまいます。

組込み側:

///  BTスレーブ応答フレーム ///
typedef struct _ST_SLAVE_RESP {
		uint16_t	len;		         // パケット長 6
    uint8_t    data[40000];    // CAN DATA部
} ST_SLAVE_RESP;

		:
	前略
		:
ST_SLAVE_RESP frm;

frm.len = sizeof(ST_SLAVE_RESP) - sizeof( uint16_t );	// パケット長 ,checksum分引く = 40,002(0x9C42)
		:
	中略
		:
 err_code = ble_nus_data_send( /*in*/    &m_nus,
			 						  /*in*/     &frm,
			  					  /*in-out*/ &sendLen,
									  /*in*/     m_conn_handle );

Java側:

/// BLEデータの取出し
byte alldata[] = characteristic.getValue();

// パケット長 6
short len = extractBin16(alldata, 4);
		:
	中略
		:

///////////////////////////////////////////////////
// int16取り出し
///////////////////////////////////////////////////
public short extractBin16(
    byte[]  from,
    int     offset
) {
    short   val  = 0;
    short    tmp;

    // QualcommはARM系なのでリトルエンディアン、Nordic もARM系なのでリトルエンディアン
    val  +=  from[ 0 + offset ];            // 0x42 → 10進 66
    val  +=  ( from[ 1 + offset ] * 256 );  // 0x9C → 10進 -100

    return val;
}

修正例は以下のとおりです。これは VB6(VBA) も同様で昔はよく引っ掛かっていたものです。

///////////////////////////////////////////////////
// int16取り出し
///////////////////////////////////////////////////
public short extractBin16(
    byte[]  from,
    int     offset
) {
    short   val  = 0;
    short    tmp;

    // ARMはリトルエンディアン
    tmp  =  from[ 0 + offset ];
    if ( tmp < 0 ) {    // Javaはunsignedがないため、1の補数で補完する
        tmp = (short)(255 + tmp + 1);
    }
    val  +=  tmp;

    tmp  =  from[ 1 + offset ];
    if ( tmp < 0 ) {    // Javaはunsignedがないため、1の補数で補完する
        tmp = (short)(255 + tmp + 1);
    }
    val  +=  ( tmp * 256 );

    return val;
}

チエックサム計算も同様にくるってしまいます。尚、shortがオーバーフローしたとき、プログラム異常になってしまうのかわかりませんが対策しておきます。

組込み側:

uint16_t CalcCheckSum(
 	 uint8_t *buf, 	// i : 対象Buffer
	 int16_t len	  // i : 対象Buffer長。
) {
	uint16_t i;
	uint16_t sum;

	sum = 0;
	for( i = 0; i < len; i ++ ) {
		sum += buf[ i ];
	}
	return	sum;
}

Java側:

 ///////////////////////////////////////////////////
 // checksum
 ///////////////////////////////////////////////////
 public short checksum(
     byte[]  to,
     int     len
 ) {
     long    sum = 0;
     short    tmp;

     for( int i = 0; i < len; i ++ ) {
         tmp = (short)to[ i ] ;
         if ( tmp < 0 ) {    // Javaはunsignedがないため補完する
             tmp = (short)(255 + tmp + 1);
         }
         sum += tmp ;
     }

     return((short)sum);
 }


組込みC側と送受信する文字列は、Stringでは渡せないです。copyValueOf(char[] data)、valueOf(char[] data) があるようですがコードもかさむんで、Byte[] でよいでしょう。

    final byte[]  ID_MASTER = {0x42,0x54,0x30,0x32};   // "BT02" MASTERから
    final byte[]  ID_TAIL   = {0x42,0x45,0x4E,0x44};   // "BEND"	 終了

SGP312:Xperia Tablet Z Wi-Fi 32GB版をAndroid 13相当にSetupする

ユーザさんから問合せがあり、Xperia Tablet Z Wi-Fi版 (SGP312) のSetupを実施した結果です。要点/固有事項だけ記載いたします。フル手順はSO-05Gの記事をみてください。


まずXperia Tablet Zのモデル展開状況を確認します。

仕様型番通称
Wi-Fi、16GBSGP311pollux_windy
Wi-Fi、32GBSGP312【今回】pollux_windy
4G、32GBSGP321pollux


LEDの位置

Xperia共通の fastbootモード時に青、flashモード時に緑に点灯するLEDはディスプレイ中央上でなく、ボディサイドにあります。何も光らないので最初は困惑します。UPボタン + USB差し込みで、 に変化し、fastbootモード に移行します。( AI がUPボタン+電源ボタン長押しといっているのはウソです)


  • やや動作はもっさり。
  • Setup後、UPボタン + 電源on でのリカバリ起動はできません。


各種用意するツールやROMデータは公開状況が日々変化します。当方は以下の構成で行いました。当方から配布はできないため、くぐって入手してください。https://androidfilehost.com/が主な入手先です。

書換用Windowsアプリflashtool-0.9.36.0-windows.exeWindows用書込みソフトのインストーラです。GUIアプリ、Xperia用USBドライバ、CUIコマンドを含んでいます。
root化イメージ不要xperiaはroot化不要。
bootイメージ適用不可
カスタムリカバリtwrp-3.7.0_9-0-pollux_windy.imgboot領域に書込む。
OSイメージlineage-20.0-20231125-UNOFFICIAL-pollux_windy.zipAndroid13互換
OpenGappMindTheGapps-13.0.0-arm-20231025_200806_Z-Tab.zipSM_T800と同様に、オリジナルからスクリプトの修正が必要。


オリジナルは And 5.1.1 でした。


手順は他Wi-Fi系 Xperia と同じです。Bootloader unlock allowedIMEI を確認するためのサービスコードの入力方法は、連絡先 -> 設定 から 画面下部を長押します。

ポイントとなる Bootloader unlock allowed の状態は Yes でした。

Bootloader unlockするための解除コードの発行するSONY Unlock Bootloader サイトで選択するDevice名は WiFiと 4G は別々になっています。もちろんWiFi側を選びます。

Bootloader unlockは、fastboot コマンドで行います。

再びサービスコードを入力し、Bootloader unlockされたか確認します。


通常どおり、recovery領域に TWRP*.img、boot領域にセットアップ対象のOSから取出した boot.img を書き込んでも TWRP が起動しません。念のため容量が同じSPG321のboot.img もNGでした。

海外のWeb記事によるとこの方法でうまく行くようです。もしかすると SGP311SGP312 でメモリレイアウトが違い、通常OSは 16GB版のSGP311 に合わせてあるのかもしれません。SGP611 と同様に boot領域 に TWRP*.img を書込みます。以下、Boot領域から TWRP を起動した様子です。


lineage-20.0*.zip をSDカードにコピーして、TRWPからインストールします。ここは特に問題なしです。コンソールメッセージを見るとOSは 16GB版SGP311 用にジェネレーションされたもののようです。

一先ず起動はOKです。WiFi、BT、カメラ、SDカード、GPS( GPSTestアプリは古いためか無反応だったがGoogleMAPはOK ) は一通りはOKでした。

しかし、ホームボタン、戻るボタン が表示されません。

これはOS初期セットアップで以下の指定する必要がありました。Samsungなどハードボタンがある機種を自動識別しないようです。

ホームボタン、戻るボタンが表示されるようになりましたが、純正OSと違い右寄せに小さく表示されます。

またOSバージョン新しくなる他、画面分割が使えるようになるメリットがあります。

しかし 本端末の場合、少し処理負荷が高いようで、ややもっさり感があります。


TWRPから lineageOS用のGoogleサービス: MindGappをインストールしましたがエラーになってしまいます。原因は SM-T800と同様です。尚、TWRP を boot領域 に書込んでいるため、LinageOS と MindGapp は一回のTWRP の起動でインストールする必要があります。

SM-T800と同様にスクリプトを修正して、新しいzipを作りインストールします。本zipは、GitHubに公開済みです。

この後、Googleサービスを自動updateさせれば、追加インストール無くGoogleサービスが利用可能になりました。今日時点での各バージョンは以下のとおりでした。

アプリ名バージョン
Google検索13.21
Google Play45.1.12
Google Play開発者サービス25.8.32

他の基本アプリは、And12以降のGoogleアプリのオープン版 NikGapps は 32bit版が無いためインストールできませんでした。取り急ぎGoogle MAPは、Google Playから通常インストールし問題なく動作しました。


以上、SGP312:Z Tablet Wi-Fi 32GB版をAndoroid13相当にUpdateする手順です。しかしながら自分でやるのはメンドクサイ、忙しい、自身が無い方は、弊方でセットアップをお受けいたします。約1.5時間の個人様向け工数+事務費で税込4,000円 。ご相談、依頼はこちらから。

nRF52840 と Android端末間で Nordic UARTを試す

前回nRF52840の開発環境を作りました。今回はAndroid端末間で Nordic UARTを試します。構想中のCANロガーのWANとの中継部になります。

弊方のBluetooh実績は以下の通りです。うまく組合せればスピーディに構築できるでしょうか?

  • nRF5810 nRF5832 間で、オリジナル基板にてNordic UART 通信。
  • Android端末から、体温計(A&D製と日本精密計測製)、血圧系(A&D製)、血中酸素濃度系(A&D製)

大抵最初はサンプルコードに肉付けするか、ある程度の部分をごっそり持ってるかです。弊方には体温計等用に 独立スレッドのインテントサービスライブラリを作ってあり、こちらを有効活用したい。まず通信仕様を確認します。

前回Nordic マイコン同士の通信では、プロトコルがカプセル化されていて見えません。Android用専用ライブラリも無いようです。公式NordicドキュメントのUUIDはココに記載されています。具体的シーケンスまでは未説明です。サンプルコードあまりな無く、Android-nRF-ToolboxAndroid-nRF-UART というのがありGitHubに置いてあります。(後者は有志の方のものかも)

Nordic UART の通信条件は以下のとおりでした。e) は .h に明確な記載はなかったため BLE_NUS_MAX_DATA_LEN をデバッグターミナルに printしてみました。

a) Service UUID 6e400001-b5a3-f393-e0a9-e50e24dcca9e
b) 受信用特性UID6e400003-b5a3-f393-e0a9-e50e24dcca9e
c) 送信用特性UID6e400002-b5a3-f393-e0a9-e50e24dcca9e
d) GATT UUID (従来通り)00002902-0000-1000-8000-00805f9b34fb
e) 一回の送信最大Byte Size (実験値)224

尚、マスターは Nordic 側、スレーブは Android 側としています。

今のところ Nordic UART に固有に依存した通信は無く、体温計等と同じシーケンスで送受信できました。ポイントを列挙します。

  • 受信だけなら受信用特性だけ使えばOK。BT接続後、相手BT機器からデータを投げてくる場合と同じです。
  • 送信は送信用特性に対して書き込みを行います。相手BT機器に対して何か設定を行う場合と同じです。
  • 時刻特性(00002A08-0000-1000-8000-00805f9b34fb) はBT共通ですが対応しいないようです。エラーになります。 Nordic 側で自分で作り込む必要があるのかもしれません。

以下テスト送信の様子です。

nRF52840 側は、SEGGER のデバッグコンソールで確認します。

Nordic 側のコードは以下のような感じです。”test”受信後、”test_ok”を送信します。

Android側の送信トリガー部は以下のような感じです。

Android側の受信表層部は以下のような感じです。

Android側の送信深層部は以下のような感じです。ここに至るまでは、インテントサービスによるメッセージと、GATT のイベントハンドラを数段介しています。

取り急ぎ体温計等と同じシーケンスで使えそうな印象です。本実装では特定時間内の複数CANフレーム一式をまとめて受信する予定です。以下が次課題です。

  • 複数CANフレーム一式のパケット分割。(これはやればできるハナシ )
  • 時間当たりの転送効率がどのくらいでるか?
  • 転送効率が芳しくない場合、他のBT プロファイルが使えないか? ( BLE: lowenergy でないBluetoothだともっと早いとどこかで見た気がする)
  • Bluetooth Long Range も気になる。(nRF52840 の機能マトリクスにはサポート有と記載があった)


nRF52840 と Android端末間で Nordic UARTを試すした結果です。何かしらベースがあれば割と簡単に通信できます。( 当方は扱い方を思出すのに一番時間を要しました)

手順とそのポイントは以上ですが、Nordic UART をAndriod端末から直ぐに動かしたい、工数がない、自身がない会社さん等はご依頼を受付けています。こちらまでご一報ください

ゆうぱっくスマホ割の注意点

ヤマト営業所ゆり郵便局の数の方が多いのと、安く送れるので、カスタムROMセットアップでよく利用しています。しかし独特の癖があります。その覚書です。

間違っていないのにログインできない

メアド と パスワード 合っていても、高い確率で不一致で蹴られます。

弊方では、端末を直接操作するのは非効率なので scrcpy にて PC からエミュレート操作しています。そのとき メアド と パスワード はコピペします。3回間違えるとログイン不能になるので、毎回パスワードを再設定しています。 scrcpy かコピペのどちらかがまずそうです。

郵料金を確認するため仮入力後再開するとき

  • 以下のように履歴を表示します。(これも直感的に連想しにくい…ずっと再入力していた)

郵便局留め発送時

  • アプリから送付先への受取住所の入力は、郵便局からではなく、端末の発送者のメールから送信される。(郵便局から案内するのが普通なような…)
  • 送付先さんが受取住所の入力後、自動メール連絡は無い。(普通はあるかな…) 入力後か確認するには以下の操作をします。(気づきにくい)

QRタグはキャプチャできない

常時、端末にsimを指しておらず、郵便局で読ませるQRタグをキャプチャして持っていこうとすると、キャプチャがNGとなります。社内wi-fi圏から離脱後、素早く郵便局で読ませる必要があります。

作成履歴が削除できない

個人情報保護に観点から履歴は削除したいのですができないです。