Customers

you can see some of alephgsm good customers list here that we cooperate with them about source codes, solutions (some private)

Toturial

MTK’s NVRAM realizes data backup and recovery

In 2017, there was such a customized requirement: write a file data, and the file data also needs to be restored after restoring the factory settings.

Step 1: nvram lib id definition

vendor/mediatek/proprietary/custom/project/cgen/inc/Custom_NvRam_LID.h
typedef enum
{
    AP_CFG_RDCL_FILE_AUDIO_LID=AP_CFG_CUSTOM_BEGIN_LID, //AP_CFG_CUSTOM_BEGIN_LID: this lid must not be changed, it is reserved for system.
    AP_CFG_RDCL_FILE_AUDIO_MAGI_CONFERENCE_LID,
    AP_CFG_RDCL_FILE_AUDIO_HAC_PARAM_LID,
    AP_CFG_CUSTOM_TEST_CUSTOM1_LID, //zrx add defines lib id
    AP_CFG_CUSTOM_FILE_MAX_LID,
} CUSTOM_CFG_FILE_LID;

//zrx add Add LID version information
#define AP_CFG_CUSTOM_TEST_CUSTOM1_LID_VERNO "000"

Step 2: declare the data structure and version number of nvram lib id

vendor/mediatek/proprietary/custom/project/cgen/inc/Custom_NvRam_data_item.h
//zrx add
LID_BIT VER_LID(AP_CFG_CUSTOM_TEST_CUSTOM1_LID)
Test_Custom1_Struct *CFG_TEST_CUSTOM1_REC_TOTAL
{

};

Step 3: nvram lib data structure definition

vendor/mediatek/proprietary/custom/project/cgen/cfgfileinc/CFG_Custom1_File.h
//zrx add start
typedef struct
{
    unsigned char Array[1024];
}Test_Custom1_Struct;
//zrx add end

//zrx add start
#define CFG_TEST_CUSTOM1_REC_SIZE sizeof(Test_Custom1_Struct)
#define CFG_TEST_CUSTOM1_REC_TOTAL 1
//zrx add end

Step 4: nvram lib default value definition

vendor/mediatek/proprietary/custom/project/cgen/cfgdefault/CFG_Custom1_Default.h
Test_Custom1_Struct stCustom2Default =
{

    0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
    
};

Step 5: Add the contents of nvram lib to the nvram array

vendor/mediatek/proprietary/custom/m107/cgen/inc/CFG_file_info_custom.h
#include "../cfgfileinc/CFG_Custom1_File.h"
#include "../cfgdefault/CFG_Custom1_Default.h"

 const TCFG_FILE g_akCFG_File_Custom[]=
    {

    { "/data/nvram/APCFG/APRDCL/Test_Custom1", VER(AP_CFG_CUSTOM_TEST_CUSTOM1_LID), CFG_TEST_CUSTOM1_REC_SIZE,
            CFG_TEST_CUSTOM1_REC_TOTAL, SIGNLE_DEFUALT_REC, (char *)&stCustom2Default, DataReset, NULL
        },
    };

Step 6: nvram lib id needs to be backed up to BinRegion

vendor/mediatek/proprietary/external/nvram/libcustom_nvram/CFG_file_info.c
FileName aBackupToBinRegion[]=
{
  {"CUSTOM_TEST",AP_CFG_CUSTOM_TEST_CUSTOM1_LID},
}

pfConvertFunc aNvRamConvertFuncTable[]=
{
  NULL, //AP_CFG_CUSTOM_TEST_CUSTOM1_LID
}

const TABLE_FOR_SPECIAL_LID g_new_nvram_lid[] =
{
    {AP_CFG_CUSTOM_TEST_CUSTOM1_LID, 1024 * 1024, 1024 * 1024},
};

Step 7: Upper layer read and write nvram data interface

NvRAMAgent.java
package com.example.nvram_test;

import android.os.IBinder;

public interface NvRAMAgent extends android.os.IInterface
{
    /** Local-side IPC implementation stub class. */
    public static abstract class Stub extends android.os.Binder implements NvRAMAgent
    {
        private static final java.lang.String DESCRIPTOR = "NvRAMAgent";
        /** Construct the stub at attach it to the interface. */
        public Stub()
        {
            this.attachInterface(this, DESCRIPTOR);
        }
        /**
         * Cast an IBinder object into an NvRAMAgent interface,
         * generating a proxy if needed.
         */
        public static NvRAMAgent asInterface(android.os.IBinder obj)
        {
            if ((obj == null)) {
                return null;
            }

            android.os.IInterface iin = (android.os.IInterface) obj.queryLocalInterface(DESCRIPTOR);

            if (((iin != null) && (iin instanceof NvRAMAgent))) {
                return ((NvRAMAgent) iin);
            }

            return new NvRAMAgent.Stub.Proxy(obj);
        }
        public android.os.IBinder asBinder()
        {
            return this;
        }
        public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
        {
            switch (code)
            {
            case INTERFACE_TRANSACTION:
            {
                reply.writeString(DESCRIPTOR);
                return true;
            }
            case TRANSACTION_READFILE:
            {
                data.enforceInterface(DESCRIPTOR);
                int _arg0;
                _arg0 = data.readInt();
                byte[] _result = this.readFile(_arg0);
                reply.writeNoException();
                reply.writeByteArray(_result);
                return true;
            }
            case TRANSACTION_WRITEFILE:
            {
                data.enforceInterface(DESCRIPTOR);
                int _arg0;
                _arg0 = data.readInt();
                byte[] _arg1;
                _arg1 = data.createByteArray();
                int _result = this.writeFile(_arg0, _arg1);
                reply.writeNoException();
                reply.writeInt(_result);
                return true;
            }
            default:
            {
                break;
            }
            }

            return super.onTransact(code, data, reply, flags);
        }
        private static class Proxy implements NvRAMAgent
        {
            private android.os.IBinder mRemote;
            Proxy(android.os.IBinder remote)
            {
                mRemote = remote;
            }
            public android.os.IBinder asBinder()
            {
                return mRemote;
            }
            public java.lang.String getInterfaceDescriptor()
            {
                return DESCRIPTOR;
            }
            public byte[] readFile(int file_lid) throws android.os.RemoteException
            {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                byte[] _result;

                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeInt(file_lid);
                    mRemote.transact(Stub.TRANSACTION_READFILE, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.createByteArray();
                }
                finally {
                    _reply.recycle();
                    _data.recycle();
                }

                return _result;
            }
            public int writeFile(int file_lid, byte[] buff) throws android.os.RemoteException
            {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                int _result;

                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeInt(file_lid);
                    _data.writeByteArray(buff);
                    mRemote.transact(Stub.TRANSACTION_WRITEFILE, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readInt();
                }
                finally {
                    _reply.recycle();
                    _data.recycle();
                }

                return _result;
            }

            public byte[] readFileByName(String filename) throws android.os.RemoteException
            {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                byte[] _result;

                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeString(filename);
                    mRemote.transact(Stub.TRANSACTION_READFILEBYNAME, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.createByteArray();
                }
                finally {
                    _reply.recycle();
                    _data.recycle();
                }

                return _result;
            }

            public int writeFileByName(String filename, byte[] buff) throws android.os.RemoteException
            {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                int _result;

                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeString(filename);
                    _data.writeByteArray(buff);
                    mRemote.transact(Stub.TRANSACTION_WRITEFILEBYNAME, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readInt();
                }
                finally {
                    _reply.recycle();
                    _data.recycle();
                }

                return _result;
            }
        }
        static final int TRANSACTION_READFILE = (IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_WRITEFILE = (IBinder.FIRST_CALL_TRANSACTION + 1);
        static final int TRANSACTION_READFILEBYNAME = (IBinder.FIRST_CALL_TRANSACTION + 2);
        static final int TRANSACTION_WRITEFILEBYNAME = (IBinder.FIRST_CALL_TRANSACTION + 3);
    }
    public byte[] readFile(int file_lid) throws android.os.RemoteException;
    public int writeFile(int file_lid, byte[] buff) throws android.os.RemoteException;
    public byte[] readFileByName(String filepath) throws android.os.RemoteException;
    public int writeFileByName(String filepath, byte[] buff) throws android.os.RemoteException;
}

Step 8: Read and write data helper class

Utils.java
ackage com.example.nvram_test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;

import android.content.Context;
import android.os.IBinder;
import android.os.ServiceManager;
import android.util.Log;
import android.widget.Toast;

public class Utils {
    final String TAG = "Utis";
    byte[] buff;
    Context mContext;
    public Utils(Context mContext){
        this.mContext=mContext;
    }   

    /**
     * Combine multiple byte arrays into one byte array
     * @param a byte array
     * @param b byte array
     * @return byte[]
     */
    public byte[] combineBytes(byte[] a, byte[] b) {
        byte[] bytes = new byte[a.length + b.length];
        System.arraycopy(a, 0, bytes, 0, a.length);
        System.arraycopy(b, 0, bytes, a.length, b.length);
        return bytes;
    }   

    /**
     * Write files to app
     */
    public void writeOwnFile(String fileName,String message){
        try {
            FileOutputStream fout = mContext.openFileOutput(fileName,
                    mContext.MODE_PRIVATE);
            byte[] bytes = message.getBytes();
            fout.write(bytes);
            fout.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Read files from app
     * @param fileName
     * @return
     */
    public String readOwnFile(String fileName){
        try {
            FileInputStream fis=mContext.openFileInput(fileName);
            ByteArrayOutputStream bos=new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len=0;
            while((len=fis.read(buffer))!=-1){
                bos.write(buff, 0, len);
            }
            byte[] content_byte = bos.toByteArray();  
            String content = new String(content_byte);  
            return content;
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return null;
    }

    /**
     * write file
     * @param fileName file name
     * @param bytes byte array
     */
    public void writeFile(String fileName,byte[] bytes){
         try {              
                FileOutputStream fout = new FileOutputStream(fileName);            
                fout.write(bytes);
                fout.close();               
            } catch (Exception e) {
                e.printStackTrace();
            }
    }

    /**
     * Read file
     * @param fileName file name
     * @return byte[]
     */
    public byte[] readFile(String fileName){
        try {
            FileInputStream fin = new FileInputStream(fileName);
            int length = fin.available();
            byte [] buffer = new byte[length];
            fin.read(buffer);
            fin.close();
            return buffer;
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return buff;
    }

    /**
     * Write value to NvRam
     * @param file_name NvRam path
     * @param bytes byte array
     */
    public void writeData(String file_name, byte[] bytes) {
        byte[] buff = new byte[1024];
        if(bytes.length<buff.length){ for(int="" i="0;i<bytes.length;i++){" buff[i]="bytes[i];" }="" *for(int="" j="bytes.length;j<buff.length;j++){" buff[j]="(byte)0;" }*="" }else{="" ibinder="" binder="ServiceManager.getService("NvRAMAgent");" nvramagent="" agent="NvRAMAgent.Stub.asInterface(binder);" if="" (agent="" !="null)" {="" int="" flag="0;" try="" buff);="" catch="" (exception="" e)="" todo:="" handle="" exception="" e.printstacktrace();="" (flag="">0) {
                Toast.makeText(mContext, "write Success", Toast.LENGTH_SHORT).show();
            // Log.d(TAG, "zrx----write Success");
            } else {
                Toast.makeText(mContext, "write Failure", Toast.LENGTH_SHORT).show();
                Log.d(TAG, "zrx---- write Failure");
            }
        }
    }

    /**
     * Read value from NvRam
     * @param file_name NvRam path
     * @param offset starting position
     * @param byteCount number of bytes
     * @return
     */
    public byte[] readData(String file_name,int offset,int byteCount) {
        byte[] data = new byte[byteCount];
        IBinder binder = ServiceManager.getService("NvRAMAgent");
        NvRAMAgent agent = NvRAMAgent.Stub.asInterface(binder);
        if (agent != null) {
            try {
                buff = agent.readFileByName(file_name);
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
        if (buff != null) {
            try {
                for(int i=0;i<bytecount;i++){ data[i]="buff[offset+i];" }="" catch="" (exception="" e)="" {="" todo:="" handle="" exception="" e.printstacktrace();="" return="" data;="" <="" pre="">

Step 9: Verify

MainActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import com.example.nvram_test.R;

public class MainActivity extends Activity{
    String TAG="MainActivity";

    /**
     * The file name is defined in vendor/mediatek/proprietary/custom/m107/cgen/inc/CFG_file_info_custom.h
     */
    private static final String TEST_FILENAME = "/data/nvram/APCFG/APRDCL/Test_Custom1";
    Button btn1;
    Button btn2;
    Button btn3;
    Button btn4;
    Utils utils;
    /**
     * Test the path to the backup SecretKey file
     */
    private static final String secret_filename="/storage/emulated/0/SecretKey";

    /**
     * Test the path to the backup goc_database file
     */
    private static final String goc_database="/storage/emulated/0/goc_database";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        utils=new Utils(this);
        btn1=(Button)findViewById(R.id.btn1);
        btn2=(Button)findViewById(R.id.btn2);

        btn3=(Button)findViewById(R.id.btn3);
        btn4=(Button)findViewById(R.id.btn4);

        /**
         * Test the backup of the SecretKey file bytes to NvRam
         */
        btn1.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                byte[] a=utils.readFile(secret_filename); //Read SecretKey file
                utils.writeData(TEST_FILENAME, a); //Back up the bytes of the SecretKey file to NvRam

                //byte[] b=utils.readData(TEST_FILENAME, 0, a.length);
            /* if (!Arrays.equals(a, b)) {
                    utils.writeData(TEST_FILENAME, a);
                }else{
                    Toast.makeText(MainActivity.this, "SecretKey Data has existed, no need to backup!", Toast.LENGTH_SHORT).show();
                }*/
            }
        });

        /**
         * Test reading the bytes of the SecretKey file from NvRAM
         */
        btn2.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                byte[] bytes=utils.readData(TEST_FILENAME,0,27); //Test the bytes of the SecretKey file read from NvRAM
                Toast.makeText(getApplicationContext(), "data = "+new String(bytes), Toast.LENGTH_LONG).show();
            }
        });

        /**
         * Test to write bytes of goc_database file to NvRAM
         */
        btn3.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                byte[] bytes=utils.readFile(goc_database); //bytes of goc_database file
                byte[] a=utils.readData(TEST_FILENAME,0,27); //Read the bytes of the SecretKey file in NvRAM
                utils.writeData(TEST_FILENAME, utils.combineBytes(a, bytes));           
            }
        });

        /**
         * Test whether the bytes of the goc_database file written to NvRAM are the same as the original file goc_database.
         */
        btn4.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub              
                byte[] bytes=utils.readFile(goc_database); //Read goc_database file
                byte[] b=utils.readData(TEST_FILENAME, 27, bytes.length); //Read goc_database bytes under NvRAM
                utils.writeFile("/storage/emulated/0/goc_database2", b); //Write the goc_database bytes under NvRAM to the goc_database2 file. Compare the goc_database2 file with the original file goc_database and find that they are the same.                   
            }
        });
    }


}
Check Also
Close
Back to top button