diff --git a/app_main/build.gradle b/app_main/build.gradle
index d79e7afb..f5c9d2b3 100644
--- a/app_main/build.gradle
+++ b/app_main/build.gradle
@@ -52,14 +52,11 @@ dependencies {
annotationProcessor 'com.github.bumptech.glide:compiler:4.5.0'
- // This my project maven from github release!
- implementation 'com.github.xianglin1998:IORedirector:1.0'
- implementation 'com.github.xianglin1998:Crapto1:1.3'
- implementation 'com.github.xianglin1998:nfctag:1.0'
- implementation 'com.github.xianglin1998:nfc_console:1.0'
-
- implementation 'com.github.xianglin1998:ComBridge:1.0.7'
- // implementation project(path: ':iobridges')
+ implementation project(path: ':iobridges')
+ implementation project(path: ':crapto1')
+ implementation project(path: ':nfctag')
+ implementation project(path: ':console')
+ implementation project(path: ':redirector')
implementation project(':utils')
implementation project(':libnfc_pn53x')
@@ -68,7 +65,6 @@ dependencies {
implementation project(path: ':pm3flasher')
implementation project(':pm3rdv4rrg')
- implementation project(path: ':xmodem')
// The dep from TERMUX(A FullTerminal implements.)
implementation project(":termux-app")
diff --git a/app_main/src/main/AndroidManifest.xml b/app_main/src/main/AndroidManifest.xml
index 3d84091b..17c27157 100644
--- a/app_main/src/main/AndroidManifest.xml
+++ b/app_main/src/main/AndroidManifest.xml
@@ -35,9 +35,7 @@
-
-
diff --git a/app_main/src/main/assets/help.html b/app_main/src/main/assets/help.html
deleted file mode 100644
index 790b7618..00000000
--- a/app_main/src/main/assets/help.html
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-
-
-
- 使用帮助
-
-
-前言
-本APP支持哪些设备?
-
- - 1、恩智浦_自带(免费)
- - 2、恩智浦_PN532(付费)
- - 3、龙杰_ACR122U(付费)
- - 4、Proxmark3CDC(付费)
- - 5、ChameleonCDC(付费)
- - 6、Proxmark3SPP(付费)
-
-本APP支持哪些连接方式?
-
-APP注意事项正文
-
- 1、Miui系统可能需要前往权限管理打开“后台弹出窗口”,否则一键重启不可用!
-
-
- 2、没有购买权限是无法发现相关设备的,请有需要的用户联系管理员购买!
-
-
- 3、为了您的数据安全,APP不允许您以Wifi代理或者VPN之类的方式联网!
-
-
- 4、很多权限都是谷歌附加强调的,但APP本身并未使用,比如定位,此链接可证实:cnblogs!
- 如果您没有使用蓝牙相关的设备,您完全可以禁止本APP的定位权限,身正不怕影子斜!
-
-
- 5、目前已知的问题是后台一段时间后会被回收内存,导致程序出错,所以在处理任务时请不要轻易切换后台!
-
-
- 6、出现问题请在“加入Q群”中进群反馈,必要时提供log文件,在“发送log”选项中,
- 选择log时请选择发送最顶端的带有数字的比如“log_1557477240504”,最好是多发几个。
-
-APP使用帮助正文
-
- 本APP在线帮助与免责声明已经整理好一部分,本APP涉及到的开源库将被共享到此链接,如果未发现,可能是操作未更新,可联系dev要求更新。跳转观看
-
-
\ No newline at end of file
diff --git a/app_main/src/main/assets/pm3_version.txt b/app_main/src/main/assets/pm3_version.txt
new file mode 100644
index 00000000..1a81daa1
--- /dev/null
+++ b/app_main/src/main/assets/pm3_version.txt
@@ -0,0 +1,10 @@
+20201026_5
+
+pattern: *_*
+
+frist *: date
+second: number
+
+example: 20201026_1
+example: 20201026_2
+example: 20201027_1
\ No newline at end of file
diff --git a/app_main/src/main/assets/proxmark3.zip b/app_main/src/main/assets/proxmark3.zip
index 31fc32cd..bd4fee51 100644
Binary files a/app_main/src/main/assets/proxmark3.zip and b/app_main/src/main/assets/proxmark3.zip differ
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/chameleon/ChameleonGUIActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/chameleon/ChameleonGUIActivity.java
index d6907cd6..512ce7b8 100644
--- a/app_main/src/main/java/cn/rrg/rdv/activities/chameleon/ChameleonGUIActivity.java
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/chameleon/ChameleonGUIActivity.java
@@ -18,7 +18,7 @@ import android.widget.ListView;
import android.widget.TextView;
import com.iobridges.com.Communication;
-import com.proxgrind.xmodem.XModem128;
+import cn.rrg.chameleon.xmodem.XModem128;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3NewTerminalInitActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3NewTerminalInitActivity.java
index adcf4048..cb03170f 100644
--- a/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3NewTerminalInitActivity.java
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/proxmark3/rdv4_rrg/Proxmark3NewTerminalInitActivity.java
@@ -80,10 +80,12 @@ public class Proxmark3NewTerminalInitActivity extends BaseActivity {
box.setChecked(Commons.getAutoGoToTerminal());
// Must have init pm3 client and check auto go and have the terminal type selected!
- if (Commons.getAutoGoToTerminal()
- && Commons.isPM3ClientDecompressed()
- && Commons.getTerminalType() != -1) {
- go();
+ if (Commons.getAutoGoToTerminal() && Commons.getTerminalType() != -1) {
+ if (Proxmark3Installer.isCanInstall(activity)) {
+ Proxmark3Installer.installIfNeed(activity, this::go);
+ } else {
+ go();
+ }
}
}
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/tools/AboutActicity.java b/app_main/src/main/java/cn/rrg/rdv/activities/tools/AboutActicity.java
index 2a694fe1..d6779a51 100644
--- a/app_main/src/main/java/cn/rrg/rdv/activities/tools/AboutActicity.java
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/tools/AboutActicity.java
@@ -1,42 +1,22 @@
package cn.rrg.rdv.activities.tools;
-import android.content.DialogInterface;
-import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.net.Uri;
import android.os.Bundle;
+
import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
import android.view.View;
-import android.webkit.WebView;
import android.widget.Button;
import android.widget.TextView;
-import android.widget.Toast;
-import java.io.File;
-
-import cn.dxl.common.util.AppUtil;
-import cn.dxl.common.util.FileUtils;
-import cn.dxl.common.widget.FilesSelectorDialog;
import cn.rrg.rdv.R;
import cn.rrg.rdv.activities.main.BaseActivity;
import cn.rrg.rdv.util.Commons;
-import cn.rrg.rdv.util.Paths;
-import cn.dxl.common.util.RestartUtils;
-import cn.dxl.common.widget.ToastUtil;
public class AboutActicity extends BaseActivity {
- private TextView txtUserHelp = null;
- private TextView txtDisclaimer = null;
- private TextView txtJoinGroup = null;
- private TextView txtContactDev = null;
private TextView txtShowVersion = null;
- private TextView txtSendLogFile = null;
- private TextView txtCleanData = null;
-
private Button btnGo2ProxgrindWebsite;
private Button btnGo2RRGWebsite;
@@ -51,105 +31,13 @@ public class AboutActicity extends BaseActivity {
}
private void initViews() {
- txtUserHelp = findViewById(R.id.txtUserHelp);
- txtDisclaimer = findViewById(R.id.txtDisclaimer);
- txtJoinGroup = findViewById(R.id.txtJoinQQGroup);
- txtContactDev = findViewById(R.id.txtContactDev);
txtShowVersion = findViewById(R.id.txtShowAppVersion);
- txtSendLogFile = findViewById(R.id.txtSendLogFile);
- txtCleanData = findViewById(R.id.txtCleanData);
btnGo2ProxgrindWebsite = findViewById(R.id.btnGo2ProxgrindWebsite);
btnGo2RRGWebsite = findViewById(R.id.btnGo2RRGWebsite);
}
private void initActions() {
- txtUserHelp.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- //建立视图
- WebView wv = new WebView(AboutActicity.this);
- //加载文件
- wv.loadUrl("file:///android_asset/help.html");
- //加载进对话框中
- new AlertDialog.Builder(AboutActicity.this)
- .setView(wv).show();
- }
- });
-
- txtDisclaimer.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- }
- });
-
- txtJoinGroup.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- boolean result = joinQQGroup("4QQrqUHKMNZDNWLvi4kEWeEDHYMekp7x");
- if (!result) {
- Toast.makeText(AboutActicity.this, "未安装手Q或安装的版本不支持!", Toast.LENGTH_SHORT).show();
- }
- }
- });
-
- txtContactDev.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Commons.callQQ(AboutActicity.this, "64101226", new Runnable() {
- @Override
- public void run() {
- ToastUtil.show(context, getString(R.string.error), false);
- }
- });
- }
- });
-
- txtSendLogFile.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- new FilesSelectorDialog.Builder(AboutActicity.this)
- .setPathOnLoad(Paths.LOG_DIRECTORY)
- .setTitle(R.string.logList)
- .setOnSelectListener(new FilesSelectorDialog.OnSelectListener() {
- @Override
- public void selected(File file) {
- FileUtils.shareFile(file);
- }
- })
- .create().show();
- }
- });
-
- txtCleanData.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- new AlertDialog.Builder(AboutActicity.this)
- .setTitle(R.string.warning)
- .setMessage(R.string.tipls_clearData)
- .setPositiveButton(getString(R.string.clear), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Toast.makeText(AboutActicity.this, getString(R.string.cleaning), Toast.LENGTH_SHORT).show();
- FileUtils.delete(new File(Paths.TOOLS_DIRECTORY));
- Toast.makeText(AboutActicity.this, getString(R.string.clearFinish), Toast.LENGTH_SHORT).show();
- //必须重启APP
- RestartUtils.restartAPP(AboutActicity.this, 1000, new RestartUtils.OnExitAction() {
- @Override
- public boolean usingSystemExit() {
- //调用act管理器结束所有的活动!
- AppUtil.getInstance().finishAll();
- return false;
- }
- });
- AppUtil.getInstance().finishAll();
- }
- })
- .setNegativeButton(R.string.cancel, null)
- .show();
- }
- });
-
btnGo2ProxgrindWebsite.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -177,27 +65,6 @@ public class AboutActicity extends BaseActivity {
}
}
- /****************
- *
- * 发起添加群流程。群号:NFC PN532 计算机 单片机(573359551) 的 key 为: 4QQrqUHKMNZDNWLvi4kEWeEDHYMekp7x
- * 调用 joinQQGroup(4QQrqUHKMNZDNWLvi4kEWeEDHYMekp7x) 即可发起手Q客户端申请加群 NFC PN532 计算机 单片机(573359551)
- *
- * @param key 由官网生成的key
- * @return 返回true表示呼起手Q成功,返回fals表示呼起失败
- ******************/
- public boolean joinQQGroup(String key) {
- Intent intent = new Intent();
- intent.setData(Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D" + key));
- // 此Flag可根据具体产品需要自定义,如设置,则在加群界面按返回,返回手Q主界面,不设置,按返回会返回到呼起产品界面 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- try {
- startActivity(intent);
- return true;
- } catch (Exception e) {
- // 未安装手Q或安装的版本不支持
- return false;
- }
- }
-
@Override
protected void onDestroy() {
super.onDestroy();
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/tools/DumpEqualActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/tools/DumpEqualActivity.java
deleted file mode 100644
index 661c5e64..00000000
--- a/app_main/src/main/java/cn/rrg/rdv/activities/tools/DumpEqualActivity.java
+++ /dev/null
@@ -1,220 +0,0 @@
-package cn.rrg.rdv.activities.tools;
-
-import android.content.Intent;
-import android.os.Bundle;
-import androidx.annotation.Nullable;
-import android.view.View;
-import android.widget.ListView;
-import android.widget.RadioGroup;
-import android.widget.TextView;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import cn.dxl.common.widget.FilesSelectorDialog;
-import cn.rrg.rdv.R;
-import cn.rrg.rdv.activities.main.BaseActivity;
-import cn.rrg.rdv.adapter.DumpEqualAdapter;
-import cn.rrg.rdv.javabean.M1Bean;
-import cn.rrg.rdv.presenter.FileReadLinePresenter;
-import cn.rrg.rdv.view.FileReadLineView;
-import cn.rrg.rdv.util.Commons;
-import cn.rrg.rdv.util.LineEqualUtil;
-import cn.rrg.rdv.util.Paths;
-import cn.dxl.common.util.ArrayUtils;
-import cn.dxl.common.widget.ToastUtil;
-
-public class DumpEqualActivity extends BaseActivity implements FileReadLineView {
-
- private RadioGroup radioGroupPathSelect = null;
- private TextView txtSelectData1 = null;
- private TextView txtSelectData2 = null;
- private TextView txtShowEqualMsg = null;
- private DumpEqualAdapter adapter = null;
- private ArrayList mData1 = new ArrayList<>();
- private ArrayList mData2 = new ArrayList<>();
- private FilesSelectorDialog mSelector = null;
- private int fileId = 1;
- private FileReadLinePresenter presenter = null;
- //初始化给两个必须要的参数!
- private boolean[] states = {false, false};
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- setContentView(R.layout.act_dump_equal);
- super.onCreate(savedInstanceState);
-
- presenter = new FileReadLinePresenter();
- presenter.attachView(this);
-
- //初始化视图
- initViews();
- //初始化动作!
- initActions();
-
- //看看能否取得传递过来的数据!
- Intent intent = getIntent();
- //取出数据进行转换!
- ArrayList dataList = (ArrayList) intent.getSerializableExtra("dataList");
- //进行判断!
- if (dataList != null) {
- //取出数据名字!
- String name = intent.getStringExtra("dataName");
- if (name != null) {
- txtSelectData1.setText(name);
- } else {
- txtSelectData1.setText(R.string.data_name_dafault);
- }
- ArrayList data = new ArrayList<>(128);
- //进行拼接!
- for (M1Bean bean : dataList) {
- //进行拼接!
- data.addAll(Arrays.asList(bean.getDatas()));
- }
- //设置ID
- fileId = 1;
- onReadFinish(ArrayUtils.list2Arr(data));
- }
- }
-
- private void initViews() {
- radioGroupPathSelect = findViewById(R.id.rdoGroupDataPath);
- txtSelectData1 = findViewById(R.id.txtDumpEqualData1);
- txtSelectData2 = findViewById(R.id.txtDumpEqualData2);
- txtShowEqualMsg = findViewById(R.id.txtShowEqualMsg);
- ListView lvShowEqualResult = findViewById(R.id.lvShowEqualResult);
- adapter = new DumpEqualAdapter(this, R.layout.dump_equal_result_item);
- lvShowEqualResult.setAdapter(adapter);
- mSelector = new FilesSelectorDialog.Builder(this).setPathOnLoad(Paths.DUMP_DIRECTORY).create();
- }
-
- private void initActions() {
- txtSelectData1.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- String path = Commons.getCustomerPath(radioGroupPathSelect);
- mSelector.setPathOnLoad(path);
- mSelector.setOnSelectListener(new FilesSelectorDialog.OnSelectListener() {
- @Override
- public void selected(File file) {
- fileId = 1;
- txtSelectData1.setText(file.getName());
- presenter.load(file);
- }
- });
- mSelector.show();
- }
- });
- txtSelectData2.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- String path = Commons.getCustomerPath(radioGroupPathSelect);
- mSelector.setPathOnLoad(path);
- mSelector.setOnSelectListener(new FilesSelectorDialog.OnSelectListener() {
- @Override
- public void selected(File file) {
- fileId = 2;
- txtSelectData2.setText(file.getName());
- presenter.load(file);
- }
- });
- mSelector.show();
- }
- });
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- }
-
- @Override
- protected void onDestroy() {
- presenter.detachView();
- //清除数据,帮助回收!
- mData1.clear();
- mData2.clear();
- adapter.clear();
- super.onDestroy();
- }
-
- @Override
- public void onReadFinish(String[] line) {
- //加载成功了,需要进行判断当前是哪个文件加载出来的!
- switch (fileId) {
- //进行处理!
- case 1:
- //第一个数据!
- mData1.clear();
- mData1.addAll(Arrays.asList(line));
- states[0] = true;
- break;
-
- case 2:
- //第二个数据!
- mData2.clear();
- mData2.addAll(Arrays.asList(line));
- states[1] = true;
- break;
- default:
- break;
- }
- //进行判断,如果两个数据皆正常,则直接开始计算判断!
- boolean canStart = true;
- for (boolean state : states) {
- if (!state) {
- canStart = false;
- break;
- }
- }
- if (canStart) {
- //已经可以进行对比!
- LineEqualUtil leu = new LineEqualUtil();
- leu.putData(ArrayUtils.list2Arr(mData1), ArrayUtils.list2Arr(mData2));
- String[] result = leu.finalResult();
- int blockDiffCount = leu.getBlockDiffCount();
- int allDiffCount = leu.getAllDiffCount();
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- String msg = getString(R.string.data_block_diff_count) + blockDiffCount + getString(R.string.data_char_diff_count) + allDiffCount;
- txtShowEqualMsg.setText(msg);
- //显示一些必要的弹窗
- if (blockDiffCount == 0 && allDiffCount == 0) {
- showToast(getString(R.string.data_identical));
- }
- //必须先清除之前的数据
- adapter.clear();
- adapter.addAll(result);
- adapter.notifyDataSetChanged();
- }
- });
- }
- }
-
- @Override
- public void onReadFail(String msg) {
- showToast(msg);
- }
-
- @Override
- public void showToast(String msg) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- ToastUtil.show(DumpEqualActivity.this, msg, false);
- }
- });
- }
-
- @Override
- public void showDialog(String title, String msg) {
-
- }
-
- @Override
- public void hideDialog() {
-
- }
-}
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/tools/FormatCovertActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/tools/FormatCovertActivity.java
deleted file mode 100644
index 5436768e..00000000
--- a/app_main/src/main/java/cn/rrg/rdv/activities/tools/FormatCovertActivity.java
+++ /dev/null
@@ -1,289 +0,0 @@
-package cn.rrg.rdv.activities.tools;
-
-import android.app.AlertDialog;
-import android.os.Bundle;
-import androidx.annotation.Nullable;
-import androidx.appcompat.widget.Toolbar;
-import android.view.View;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.RadioGroup;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import cn.dxl.common.widget.FilesSelectorDialog;
-import cn.rrg.rdv.R;
-
-import java.io.File;
-
-import cn.rrg.rdv.activities.main.BaseActivity;
-import cn.rrg.rdv.presenter.FormatConvertPresenter;
-import cn.rrg.rdv.view.FormatConvertView;
-import cn.rrg.rdv.util.Commons;
-import cn.rrg.rdv.util.Paths;
-import cn.dxl.common.util.StringUtil;
-
-public class FormatCovertActivity extends BaseActivity implements FormatConvertView {
-
- private int mType = 0;
- //中介者对象持有
- private FormatConvertPresenter presenter = null;
- //文件选择器对象
- private FilesSelectorDialog mSelector = null;
-
- private RadioGroup radioGroupPathSelect = null;
-
- private Button btnSelectFromQQ = null;
- private Button btnSelectFromWecat = null;
- private Button btnSelectFromSdcard = null;
- private Button btnSelectFromThiz = null;
- private Button btnSelectFromMCT = null;
- private Button btnSelectFromMTools = null;
- private Button btnCovert2Bin = null;
- private Button btnCovert2Txt = null;
-
- private TextView txtSelectFormAnywhere = null;
- private TextView txtShowFormatDiffrences = null;
-
- private EditText edtInputSaveName = null;
-
- private String mSourceFilePath = null;
- private String mSaveFileName = null;
- private String mSavePath = null;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- setContentView(R.layout.act_format_convert);
- super.onCreate(savedInstanceState);
-
- //初始化中介者对象
- presenter = new FormatConvertPresenter();
- //绑定视图
- presenter.attachView(this);
-
- //初始化视图
- initViews();
- //初始化文件选择器
- initSelector();
- //初始化动作!
- initActions();
- }
-
- private void initViews() {
- radioGroupPathSelect = findViewById(R.id.rdoGroupDataPath);
-
- btnSelectFromQQ = findViewById(R.id.btnDumpSelectFromQQ);
- btnSelectFromSdcard = findViewById(R.id.btnDumpSelectFromSdcard);
- btnSelectFromWecat = findViewById(R.id.btnDumpSelectFromWecat);
- btnSelectFromThiz = findViewById(R.id.btnDumpSelectFromThis);
- btnSelectFromMCT = findViewById(R.id.btnDumpSelectFromMCT);
- btnSelectFromMTools = findViewById(R.id.btnDumpSelectFromMTools);
- btnCovert2Bin = findViewById(R.id.btnConvert2Bin);
- btnCovert2Txt = findViewById(R.id.btnConvert2Txt);
-
- TextView txtSaveToAnywhere = findViewById(R.id.txtSaveToAnywhere);
- txtSelectFormAnywhere = findViewById(R.id.txtSelectFormAnywhere);
- txtShowFormatDiffrences = findViewById(R.id.txtShowFormatDiffences);
-
- edtInputSaveName = findViewById(R.id.edtInputFileName);
-
- Toolbar mToolbar = findViewById(R.id.toolbar_act_format_convert);
- mToolbar.setTitle(R.string.title_format_convert);
- setSupportActionBar(mToolbar);
- }
-
- private void initActions() {
- btnSelectFromThiz.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mSelector.setPathOnLoad(Paths.DUMP_DIRECTORY);
- initSourceFileSelector();
- }
- });
- btnSelectFromSdcard.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mSelector.setPathOnLoad(Paths.EXTERNAL_STORAGE_DIRECTORY);
- initSourceFileSelector();
- }
- });
- btnSelectFromQQ.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mSelector.setPathOnLoad(Paths.QQ_DIRECTORY);
- initSourceFileSelector();
- }
- });
- btnSelectFromWecat.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mSelector.setPathOnLoad(Paths.WECAT_DIRECTORY);
- initSourceFileSelector();
- }
- });
- btnSelectFromMCT.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mSelector.setPathOnLoad(Paths.MCT_DUMP_DIRECTORY);
- initSourceFileSelector();
- }
- });
- btnSelectFromMTools.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mSelector.setPathOnLoad(Paths.MTools_PATH);
- initSourceFileSelector();
- }
- });
- btnCovert2Bin.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- checkSavePath();
- if (mSourceFilePath == null) {
- showToast(getString(R.string.tisp_select_convert_target));
- return;
- }
- if (mSaveFileName == null || mSavePath == null) {
- showToast(getString(R.string.tisp_select_convert_save_path));
- return;
- }
- mType = 0;
- presenter.convert2Bin(mSourceFilePath);
- }
- });
- btnCovert2Txt.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- checkSavePath();
- if (mSourceFilePath == null) {
- showToast(getString(R.string.tisp_select_convert_target));
- return;
- }
- if (mSaveFileName == null || mSavePath == null) {
- showToast(getString(R.string.tisp_select_convert_save_path));
- return;
- }
- mType = 1;
- presenter.convert2Txt(mSourceFilePath);
- }
- });
-
- txtShowFormatDiffrences.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- new AlertDialog.Builder(FormatCovertActivity.this).setTitle("Format distinction")
- .setMessage("1.Binary file is a general tag data format, which is the same as\". dump\", and compatible with most software.\n2.The tag data format in text format. is easy to view and can also be used in standard MCT programs.").show();
- }
- });
- }
-
- private void initSelector() {
- FilesSelectorDialog.Builder builder = new FilesSelectorDialog.Builder(this);
- builder.setTitle(R.string.title_file_select)
- .setCancelable(false)
- .setCanMultiple(false)
- .setPathOnLoad(Paths.DUMP_DIRECTORY);
- mSelector = builder.create();
- }
-
- private void checkSavePath() {
- String path = Commons.getCustomerPath(radioGroupPathSelect);
- String name = edtInputSaveName.getText().toString();
- if (!StringUtil.isEmpty(name)) {
- //非空文件名。检查是否有/字符,有则为非法!
- if (name.contains("/")) {
- return;
- }
- //进行最终的拼接!
- mSavePath = path;
- mSaveFileName = name;
- } else {
- // FIXME: 2019/5/31 修复空指针闪退!
- if (mSourceFilePath != null) {
- File file = new File(mSourceFilePath);
- mSavePath = file.getParent();
- mSaveFileName = file.getName();
- }
- }
- }
-
- private void initSourceFileSelector() {
- mSelector.setCanGetPath(false);
- mSelector.setOnSelectListener(new FilesSelectorDialog.OnSelectListener() {
- @Override
- public void selected(File file) {
- mSourceFilePath = file.getAbsolutePath();
- txtSelectFormAnywhere.setText((getString(R.string.res) + file.getName()));
- showToast(getString(R.string.success));
- }
- });
- mSelector.show();
- }
-
- @Override
- protected void onDestroy() {
- //销毁视图绑定!
- presenter.detachView();
- super.onDestroy();
- }
-
- @Override
- public void onConvertSucess(byte[] result) {
- //判断结果有效性!
- if (result == null) {
- showToast(getString(R.string.tips_convert_result_null));
- return;
- }
- if (mSavePath == null) {
- showToast(getString(R.string.tips_convert_save_path_null));
- return;
- }
- if (mSaveFileName == null) {
- showToast(getString(R.string.tips_convert_save_name_null));
- return;
- }
- switch (mType) {
- case 0:
- presenter.save2BIN(result, mSavePath, mSaveFileName);
- break;
- case 1:
- presenter.save2TXT(result, mSavePath, mSaveFileName);
- break;
- default:
- break;
- }
- }
-
- @Override
- public void onConvertFail(String errorMsg) {
- showToast(errorMsg);
- }
-
- @Override
- public void onSaveSuccess() {
- showToast(getString(R.string.success));
- }
-
- @Override
- public void onSaveFail(String msg) {
- if (msg != null)
- runOnUiThread(() -> {
- showToast(msg);
- });
- }
-
- @Override
- public void showToast(String msg) {
- runOnUiThread(() -> {
- Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
- });
- }
-
- @Override
- public void showDialog(String title, String msg) {
- }
-
- @Override
- public void hideDialog() {
- }
-}
\ No newline at end of file
diff --git a/app_main/src/main/java/cn/rrg/rdv/activities/tools/Proxmark3FirmwareActivity.java b/app_main/src/main/java/cn/rrg/rdv/activities/tools/Proxmark3FirmwareActivity.java
index 1b854fa8..3c75b320 100644
--- a/app_main/src/main/java/cn/rrg/rdv/activities/tools/Proxmark3FirmwareActivity.java
+++ b/app_main/src/main/java/cn/rrg/rdv/activities/tools/Proxmark3FirmwareActivity.java
@@ -90,9 +90,7 @@ public class Proxmark3FirmwareActivity extends BaseActivity implements DevCallba
proDialog1 = new ProDialog1(context);
- if (!Commons.isElfDecompressed()) {
- Proxmark3Installer.installIfNeed(this, null);
- }
+ Proxmark3Installer.installIfNeed(this, null);
initViews();
initActions();
diff --git a/app_main/src/main/java/cn/rrg/rdv/fragment/tools/MainSettingsFragment.java b/app_main/src/main/java/cn/rrg/rdv/fragment/tools/MainSettingsFragment.java
index e8d3297a..6f351964 100644
--- a/app_main/src/main/java/cn/rrg/rdv/fragment/tools/MainSettingsFragment.java
+++ b/app_main/src/main/java/cn/rrg/rdv/fragment/tools/MainSettingsFragment.java
@@ -4,9 +4,6 @@ import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -21,11 +18,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import com.termux.app.TermuxService;
-
import cn.dxl.common.util.AppUtil;
-import cn.dxl.common.util.FileUtils;
-import cn.dxl.common.util.LogUtils;
import cn.dxl.common.util.RestartUtils;
import cn.rrg.rdv.R;
import cn.rrg.rdv.binder.ItemSingleTextBean;
@@ -41,8 +34,6 @@ import cn.rrg.rdv.util.Proxmark3Installer;
import me.drakeet.multitype.Items;
import me.drakeet.multitype.MultiTypeAdapter;
-import static android.app.Activity.RESULT_OK;
-
/*
* 主设置活动!
* */
@@ -50,9 +41,8 @@ public class MainSettingsFragment
extends BaseFragment {
private RecyclerView rvSettingsList;
- private SharedPreferences preferences;
private MultiTypeAdapter multiTypeAdapter;
- private Items items = new Items();
+ private final Items items = new Items();
@Nullable
@Override
@@ -62,7 +52,6 @@ public class MainSettingsFragment
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- preferences = Commons.getPrivatePreferences();
multiTypeAdapter = new MultiTypeAdapter();
initViews(view);
@@ -127,7 +116,7 @@ public class MainSettingsFragment
pm3Res.setMessage(Commons.isPM3ResInitialled() ? getString(R.string.initialized) : getString(R.string.uninitialized));
items.add(pm3Res);
- // 只有SDK版本大于等于24的时候才使能PM3的高级视图
+ // PM3 Full terminal only run on sdk > 23
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ItemToggleBean pm3AutoGo = new ItemToggleBean(getString(R.string.title_pm3_autogo_setting)) {
@@ -192,32 +181,6 @@ public class MainSettingsFragment
multiTypeAdapter.notifyDataSetChanged();
}
- @Override
- public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == 0x77 && resultCode == RESULT_OK && data != null) {
- Uri uri = data.getData();
- if (uri != null) {
- // get file path
- String path = FileUtils.getFilePathByUri(uri);
- // save
- LogUtils.d("获取到的路径: " + path);
- }
- }
- }
-
- public static String getVersion(Context context) {
- if (context == null) return "unknown";
- try {
- PackageInfo pi = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
- return pi.versionName;
- } catch (PackageManager.NameNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- return context.getString(R.string.unknown);
- }
- }
-
private String languageTran() {
String currentLanguage = Commons.getLanguage();
diff --git a/app_main/src/main/java/cn/rrg/rdv/fragment/tools/ToolsAccessFragment.java b/app_main/src/main/java/cn/rrg/rdv/fragment/tools/ToolsAccessFragment.java
index a9ad6234..cdbaa975 100644
--- a/app_main/src/main/java/cn/rrg/rdv/fragment/tools/ToolsAccessFragment.java
+++ b/app_main/src/main/java/cn/rrg/rdv/fragment/tools/ToolsAccessFragment.java
@@ -12,13 +12,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
-import com.proxgrind.pm3flasher.Proxmark3Flasher;
-
import cn.rrg.rdv.R;
-import cn.rrg.rdv.activities.tools.DumpEqualActivity;
import cn.rrg.rdv.activities.tools.DumpListActivity;
import cn.rrg.rdv.activities.tools.FileListActivity;
-import cn.rrg.rdv.activities.tools.FormatCovertActivity;
import cn.rrg.rdv.activities.tools.KeyFileListActivity;
import cn.rrg.rdv.activities.tools.Proxmark3FirmwareActivity;
import cn.rrg.rdv.fragment.base.BaseFragment;
@@ -28,8 +24,6 @@ public class ToolsAccessFragment
private Button btnDataEditor = null;
private Button btnKeyEditor = null;
- private Button btnFormatCovert = null;
- private Button btnDiffTools = null;
private Button btnPM3Flasher;
@Nullable
@@ -49,8 +43,6 @@ public class ToolsAccessFragment
private void initViews(View view) {
btnDataEditor = view.findViewById(R.id.btnDumpEditor);
btnKeyEditor = view.findViewById(R.id.btnKeyEditor);
- btnFormatCovert = view.findViewById(R.id.btnConvertFormat);
- btnDiffTools = view.findViewById(R.id.btnDiffTool);
btnPM3Flasher = view.findViewById(R.id.btnPM3Flasher);
}
@@ -59,10 +51,6 @@ public class ToolsAccessFragment
startActivity(new Intent(context, DumpListActivity.class).putExtra("mode", DumpListActivity.MODE.EDIT));
});
- btnDiffTools.setOnClickListener(v -> startActivity(new Intent(context, DumpEqualActivity.class)));
-
- btnFormatCovert.setOnClickListener(v -> startActivity(new Intent(context, FormatCovertActivity.class)));
-
btnKeyEditor.setOnClickListener(v -> startActivity(
new Intent(context, KeyFileListActivity.class).putExtra("mode", FileListActivity.MODE.EDIT))
);
diff --git a/app_main/src/main/java/cn/rrg/rdv/util/Commons.java b/app_main/src/main/java/cn/rrg/rdv/util/Commons.java
index 620412dd..10c1f616 100644
--- a/app_main/src/main/java/cn/rrg/rdv/util/Commons.java
+++ b/app_main/src/main/java/cn/rrg/rdv/util/Commons.java
@@ -39,18 +39,6 @@ public class Commons {
private Commons() {
}
- //呼叫QQ
- public static void callQQ(Context context, String qq, Runnable onFaild) {
- //这里的228451878是自己指定的QQ号码,可以自己更换
- String url = "mqqwpa://im/chat?chat_type=wpa&uin=" + qq;
- try {
- context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
- } catch (Exception e) {
- onFaild.run();
- }
- }
-
- //打开浏览器,链接到指定的链接
public static void openUrl(Context context, String url) {
try {
Uri uri = Uri.parse(url);
@@ -63,32 +51,9 @@ public class Commons {
}
}
- //根据单选返回地址!
- public static String getCustomerPath(RadioGroup group) {
- if (group == null) return Paths.DUMP_DIRECTORY;
- int id = group.getCheckedRadioButtonId();
- String path;
- if (id == R.id.rdoBtnWriteDataDefaultPath) {
- path = Paths.DUMP_DIRECTORY;
- } else if (id == R.id.rdoBtnWriteDataMCTPath) {
- path = Paths.MCT_DUMP_DIRECTORY;
- } else if (id == R.id.rdoBtnWriteDataWecatPath) {
- path = Paths.WECAT_DIRECTORY;
- } else if (id == R.id.rdoBtnWriteDataSdcardPath) {
- path = Paths.EXTERNAL_STORAGE_DIRECTORY;
- } else if (id == R.id.rdoBtnWriteDataQQPath) {
- path = Paths.QQ_DIRECTORY;
- } else if (id == R.id.rdoBtnWriteDataMToolsPath) {
- return Paths.MTools_DUMP_DIRECTORY;
- } else if (id == R.id.rdoBtnWriteDataPM3Path) {
- return Paths.PM3_DIRECTORY;
- } else {
- path = Paths.DUMP_DIRECTORY;
- }
- return path;
- }
-
- //移除设备对象从集合中!
+ /**
+ * Remove the device from a list
+ */
public static boolean removeDevByList(DevBean devBean, List list) {
if (devBean != null) {
String addr = devBean.getMacAddress();
@@ -107,14 +72,18 @@ public class Commons {
return true;
}
- //判断两个设备是否是一致的
+ /**
+ * Check device is equal
+ */
public static boolean equalDebBean(DevBean a, DevBean b) {
if (a == b) return true;
if (a == null || b == null) return false;
return a.getMacAddress().equals(b.getMacAddress());
}
- //从蓝牙适配器中取出历史连接的设备列表!
+ /**
+ * Get all device from bluetooth adapter
+ */
public static DevBean[] getDevsFromBTAdapter(BluetoothAdapter btAdapter) {
ArrayList devList = new ArrayList<>();
Set pairedDevices = btAdapter.getBondedDevices();
@@ -131,10 +100,12 @@ public class Commons {
return ArrayUtils.list2Arr(devList);
}
- //设备是否是USB设备!
+ /**
+ * Check is a usb device
+ * the usb no valid mac!
+ */
public static boolean isUsbDevice(String address) {
if (address == null) return false;
- //这三种mac是开发者定义的用于区分USB设备和蓝牙设备的特征符!
switch (address) {
case "00:00:00:00:00:00":
case "00:00:00:00:00:01":
diff --git a/app_main/src/main/java/cn/rrg/rdv/util/InitUtil.java b/app_main/src/main/java/cn/rrg/rdv/util/InitUtil.java
index 42d76239..2c0fb5c3 100644
--- a/app_main/src/main/java/cn/rrg/rdv/util/InitUtil.java
+++ b/app_main/src/main/java/cn/rrg/rdv/util/InitUtil.java
@@ -20,16 +20,15 @@ public class InitUtil {
public static final String LOG_TAG = InitUtil.class.getSimpleName();
public static void initApplicationResource(Context context) {
- AssetsUtil au = new AssetsUtil(context);
File dump_dir = new File(Paths.DUMP_DIRECTORY);
if (!dump_dir.exists()) {
if (!dump_dir.mkdirs()) {
Log.d(LOG_TAG, "init dumps dir fail!");
} else {
- initDumpFile(au);
+ initDumpFile(context);
}
} else {
- initDumpFile(au);
+ initDumpFile(context);
}
File driver_dir = new File(Paths.DRIVER_DIRECTORY);
if (!driver_dir.exists()) {
@@ -42,20 +41,20 @@ public class InitUtil {
if (!keys_dir.mkdirs()) {
Log.d(LOG_TAG, "init keys dir fail!");
} else {
- initKeysFile(au);
+ initKeysFile(context);
}
} else {
- initKeysFile(au);
+ initKeysFile(context);
}
File common_dir = new File(Paths.COMMON_DIRECTORY);
if (!common_dir.exists()) {
if (common_dir.mkdirs()) {
initCommonInFile();
- initMfInfoMapsFile(au);
+ initMfInfoMapsFile(context);
}
} else {
initCommonInFile();
- initMfInfoMapsFile(au);
+ initMfInfoMapsFile(context);
}
File pn53x_dir = new File(Paths.PN53X_DIRRECTORY);
if (!pn53x_dir.exists()) {
@@ -71,11 +70,11 @@ public class InitUtil {
if (!pm3_dir.mkdirs()) {
Log.d(LOG_TAG, "init pm3 dir fail!");
} else {
- initEasyButtonFile(au);
+ initEasyButtonFile(context);
initPM3ForwardFile();
}
} else {
- initEasyButtonFile(au);
+ initEasyButtonFile(context);
initPM3ForwardFile();
}
Commons.updatePM3Cwd();
@@ -95,45 +94,45 @@ public class InitUtil {
}
}
- private static void initMfInfoMapsFile(AssetsUtil au) {
+ private static void initMfInfoMapsFile(Context context) {
File f1 = new File(Paths.COMMON_DIRECTORY + "/" + "template_mifare_info_en.html");
File f2 = new File(Paths.COMMON_DIRECTORY + "/" + "template_tag_info_en.html");
//移动两个标签信息HTML文件到指定目录!
- au.copyFile("template_mifare_info_en.html",
+ AssetsUtil.copyFile(context, "template_mifare_info_en.html",
new File(Paths.COMMON_DIRECTORY + "/" + "template_mifare_info_en.html").getAbsolutePath());
- au.copyFile("template_tag_info_en.html",
+ AssetsUtil.copyFile(context, "template_tag_info_en.html",
new File(Paths.COMMON_DIRECTORY + "/" + "template_tag_info_en.html").getAbsolutePath());
}
- private static void initDumpFile(AssetsUtil au) {
+ private static void initDumpFile(Context context) {
File target = new File(Paths.DEFAULT_DUMP_FILE);
//目标文件夹里是否有这个文件!
if (!(target.exists() && target.isFile())) {
//包里面是否有这个资源文件!
- if (au.copyFile(Paths.DEFAULT_DUMP_NAME, Paths.DEFAULT_DUMP_FILE)) {
+ if (AssetsUtil.copyFile(context, Paths.DEFAULT_DUMP_NAME, Paths.DEFAULT_DUMP_FILE)) {
Log.d(LOG_TAG, "创建默认的空白数据文件成功!");
}
}
}
- private static void initKeysFile(AssetsUtil au) {
+ private static void initKeysFile(Context context) {
File target = new File(Paths.DEFAULT_KEYS_FILE);
//目标文件夹里是否有这个文件!
if (!(target.exists() && target.isFile())) {
//包里面是否有这个资源文件!
- if (au.copyFile(Paths.DEFAULT_KEYS_NAME, Paths.DEFAULT_KEYS_FILE)) {
+ if (AssetsUtil.copyFile(context, Paths.DEFAULT_KEYS_NAME, Paths.DEFAULT_KEYS_FILE)) {
Log.d(LOG_TAG, "创建默认的空白数据文件成功!");
}
}
}
- private static void initEasyButtonFile(AssetsUtil au) {
+ private static void initEasyButtonFile(Context context) {
File target = new File(Paths.PM3_CMD_FILE);
//目标文件夹里是否有这个文件!
if (!(target.exists() && target.isFile())) {
//包里面是否有这个资源文件!
- if (au.copyFile(Paths.DEFAULT_CMD_NAME, Paths.PM3_CMD_FILE)) {
+ if (AssetsUtil.copyFile(context, Paths.DEFAULT_CMD_NAME, Paths.PM3_CMD_FILE)) {
Log.d(LOG_TAG, "创建默认的动态按钮文件成功!");
}
}
diff --git a/app_main/src/main/java/cn/rrg/rdv/util/Proxmark3Installer.java b/app_main/src/main/java/cn/rrg/rdv/util/Proxmark3Installer.java
index 0290921c..9b74b055 100644
--- a/app_main/src/main/java/cn/rrg/rdv/util/Proxmark3Installer.java
+++ b/app_main/src/main/java/cn/rrg/rdv/util/Proxmark3Installer.java
@@ -3,15 +3,45 @@ package cn.rrg.rdv.util;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
+import android.content.Context;
import com.termux.app.TermuxService;
import java.io.File;
import cn.dxl.common.util.AssetsUtil;
+import cn.dxl.common.util.FileUtils;
+import cn.dxl.common.util.LogUtils;
import cn.rrg.rdv.R;
public class Proxmark3Installer {
+ static String zipName = "proxmark3.zip";
+ static String verName = "pm3_version.txt";
+ static String zipFile = TermuxService.HOME_PATH + File.separator + zipName;
+ static String verFile = TermuxService.HOME_PATH + File.separator + verName;
+
+ public static boolean isCanInstall(Context context) {
+ try {
+ String version_assets = AssetsUtil.readLines(context, verName);
+
+ // read version for res installed
+ String version_installed = FileUtils.readLine(new File(verFile));
+ // check version
+ if (version_installed.length() == 0) {
+ // no file found or file have some problem, we need reinstall
+ return true;
+ }
+ if (version_installed.equals(version_assets)) {
+ // if version same, we can stop install
+ LogUtils.d("Proxmark3Installer->installIfNeed(): version same, we can stop install.");
+ return false;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
/**
* Install the pm3 client and resource if need!
@@ -29,10 +59,23 @@ public class Proxmark3Installer {
new Thread(new Runnable() {
@Override
public void run() {
- String zipName = "proxmark3.zip";
- String zipFile = TermuxService.HOME_PATH + File.separator + zipName;
- new AssetsUtil(activity).copyFile(zipName, zipFile);
try {
+ if (!isCanInstall(activity)) {
+ if (whenDone != null) activity.runOnUiThread(whenDone);
+ progress.cancel();
+ return;
+ }
+
+ // before install, we need delete all old res
+ FileUtils.delete(new File(TermuxService.HOME_PATH));
+ // and recreate path
+ FileUtils.createPaths(new File(TermuxService.HOME_PATH));
+
+ // copy zip file from apk to local
+ AssetsUtil.copyFile(activity, zipName, zipFile);
+ AssetsUtil.copyFile(activity, verName, verFile);
+
+ // unzip to home path
ZipUtils.UnZipFolder(zipFile, TermuxService.HOME_PATH, new ZipUtils.Progress() {
@Override
public void onProgress(int max, int current, String file) {
@@ -45,37 +88,49 @@ public class Proxmark3Installer {
});
}
});
+
+ LogUtils.d("PM3 Resource install finish.");
+
} catch (Exception e) {
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- new AlertDialog.Builder(activity)
- .setTitle(R.string.error)
- .setMessage(e.getMessage())
- .show();
- activity.runOnUiThread(() -> {
- try {
- progress.dismiss();
- } catch (RuntimeException e) {
- // Activity already dismissed - ignore.
- }
- });
- if (whenDone != null)
- whenDone.run();
- }
- });
+ showDialogOnErr(activity, progress, e.getMessage(), whenDone);
e.printStackTrace();
}
+ showDialogOnOk(activity, progress);
+ if (whenDone != null) activity.runOnUiThread(whenDone);
+ }
+ }).start();
+ }
+
+ // show dialog if task execute success
+ public static void showDialogOnOk(Activity activity, ProgressDialog dialog) {
+ activity.runOnUiThread(() -> {
+ try {
+ dialog.dismiss();
+ } catch (RuntimeException e) {
+ // Activity already dismissed - ignore.
+ }
+ });
+ }
+
+ // show dialog if has err
+ public static void showDialogOnErr(Activity activity, ProgressDialog dialog, String errMsg, Runnable call) {
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ new AlertDialog.Builder(activity)
+ .setTitle(R.string.error)
+ .setMessage(errMsg)
+ .show();
activity.runOnUiThread(() -> {
try {
- progress.dismiss();
+ dialog.dismiss();
} catch (RuntimeException e) {
// Activity already dismissed - ignore.
}
});
- if (whenDone != null)
- activity.runOnUiThread(whenDone);
+ if (call != null)
+ call.run();
}
- }).start();
+ });
}
}
diff --git a/app_main/src/main/java/cn/rrg/rdv/util/ZipUtils.java b/app_main/src/main/java/cn/rrg/rdv/util/ZipUtils.java
index c6c67ede..3b48ffef 100644
--- a/app_main/src/main/java/cn/rrg/rdv/util/ZipUtils.java
+++ b/app_main/src/main/java/cn/rrg/rdv/util/ZipUtils.java
@@ -1,12 +1,13 @@
package cn.rrg.rdv.util;
-import android.util.Log;
-
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
@@ -14,6 +15,8 @@ import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
+import cn.dxl.common.util.LogUtils;
+
/**
* @author: lijuan
* @description: 解压ZIP文件
@@ -225,4 +228,32 @@ public class ZipUtils {
inZip.close();
return fileList;
}
+
+ /**
+ * @author dxl
+ * read a file from zip file(no unzip)
+ */
+ public static String readZipFile(File zipFile, String readFileName) throws Exception {
+ ZipFile zf = new ZipFile(zipFile);
+ InputStream in = new BufferedInputStream(new FileInputStream(zipFile));
+ ZipInputStream zin = new ZipInputStream(in);
+ ZipEntry ze;
+ StringBuilder sb = new StringBuilder();
+ String line;
+ while ((ze = zin.getNextEntry()) != null) {
+ LogUtils.d("项目名: " + ze.getName());
+ if (!ze.isDirectory()) {
+ if (ze.getName().contains(readFileName)) {
+ BufferedReader br = new BufferedReader(new InputStreamReader(zf.getInputStream(ze)));
+ while ((line = br.readLine()) != null) {
+ sb.append(line);
+ }
+ br.close();
+ }
+ }
+ }
+ zin.closeEntry();
+ in.close();
+ return sb.toString();
+ }
}
diff --git a/app_main/src/main/res/layout-land/act_app_about.xml b/app_main/src/main/res/layout-land/act_app_about.xml
index 94d2e1ab..34c96779 100644
--- a/app_main/src/main/res/layout-land/act_app_about.xml
+++ b/app_main/src/main/res/layout-land/act_app_about.xml
@@ -72,149 +72,4 @@
android:gravity="center"
android:padding="6dp" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app_main/src/main/res/layout/act_app_about.xml b/app_main/src/main/res/layout/act_app_about.xml
index dea8c5f4..0391d996 100644
--- a/app_main/src/main/res/layout/act_app_about.xml
+++ b/app_main/src/main/res/layout/act_app_about.xml
@@ -79,149 +79,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app_main/src/main/res/layout/act_common_tools.xml b/app_main/src/main/res/layout/act_common_tools.xml
index 811cebed..26ea819e 100644
--- a/app_main/src/main/res/layout/act_common_tools.xml
+++ b/app_main/src/main/res/layout/act_common_tools.xml
@@ -63,52 +63,6 @@
android:text="@string/title_pm3_firmware_flasher"
android:textAllCaps="false" />
-
-
-
-
-
-
diff --git a/app_main/src/main/res/layout/act_dump_equal.xml b/app_main/src/main/res/layout/act_dump_equal.xml
deleted file mode 100644
index 9d04bfac..00000000
--- a/app_main/src/main/res/layout/act_dump_equal.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app_main/src/main/res/layout/act_format_convert.xml b/app_main/src/main/res/layout/act_format_convert.xml
deleted file mode 100644
index 66d8e301..00000000
--- a/app_main/src/main/res/layout/act_format_convert.xml
+++ /dev/null
@@ -1,192 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app_main/src/main/res/values-en/strings.xml b/app_main/src/main/res/values-en/strings.xml
index 37816397..f9cea0e7 100644
--- a/app_main/src/main/res/values-en/strings.xml
+++ b/app_main/src/main/res/values-en/strings.xml
@@ -330,5 +330,6 @@
请稍等
select
Proxmark3 External Work Directory
+ The version for proxmark3 resource read failed.
\ No newline at end of file
diff --git a/app_main/src/main/res/values-zh/strings.xml b/app_main/src/main/res/values-zh/strings.xml
index c5fa6597..2258b991 100644
--- a/app_main/src/main/res/values-zh/strings.xml
+++ b/app_main/src/main/res/values-zh/strings.xml
@@ -336,5 +336,6 @@
请稍等。
选择
Proxmark3 外部工作目录
+ 读取PM3的资源版本失败
\ No newline at end of file
diff --git a/app_main/src/main/res/values/strings.xml b/app_main/src/main/res/values/strings.xml
index 9335ef84..57050480 100644
--- a/app_main/src/main/res/values/strings.xml
+++ b/app_main/src/main/res/values/strings.xml
@@ -329,5 +329,6 @@
Please wait.
select
Proxmark3 External Work Directory
+ The version for proxmark3 resource read failed.
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index cc4b1fd5..501b4b07 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ buildscript {
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.6.3'
+ classpath 'com.android.tools.build:gradle:4.1.0'
classpath('com.github.dcendents:android-maven-gradle-plugin:1.5')
}
}
diff --git a/chameleon/build.gradle b/chameleon/build.gradle
index 6b0d5224..b252785c 100644
--- a/chameleon/build.gradle
+++ b/chameleon/build.gradle
@@ -21,12 +21,13 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'com.github.xianglin1998:mfkey:1.1'
- implementation 'com.github.xianglin1998:nfctag:1.0'
+
implementation 'com.github.felHR85:UsbSerial:6.1.0'
- implementation 'com.github.xianglin1998:ComBridge:1.0.7'
- // implementation project(path: ':iobridges')
+ implementation project(path: ':iobridges')
+ implementation project(path: ':mfkey')
+ implementation project(path: ':nfctag')
+ implementation project(path: ':iobridges')
implementation project(path: ':utils')
implementation project(path: ':communication')
diff --git a/xmodem/src/main/java/com/proxgrind/xmodem/AbstractXModem.java b/chameleon/src/main/java/cn/rrg/chameleon/xmodem/AbstractXModem.java
similarity index 98%
rename from xmodem/src/main/java/com/proxgrind/xmodem/AbstractXModem.java
rename to chameleon/src/main/java/cn/rrg/chameleon/xmodem/AbstractXModem.java
index a8a3c06f..1f0a0370 100644
--- a/xmodem/src/main/java/com/proxgrind/xmodem/AbstractXModem.java
+++ b/chameleon/src/main/java/cn/rrg/chameleon/xmodem/AbstractXModem.java
@@ -1,4 +1,4 @@
-package com.proxgrind.xmodem;
+package cn.rrg.chameleon.xmodem;
import java.io.IOException;
import java.io.InputStream;
diff --git a/xmodem/src/main/java/com/proxgrind/xmodem/XModem1024.java b/chameleon/src/main/java/cn/rrg/chameleon/xmodem/XModem1024.java
similarity index 93%
rename from xmodem/src/main/java/com/proxgrind/xmodem/XModem1024.java
rename to chameleon/src/main/java/cn/rrg/chameleon/xmodem/XModem1024.java
index f6d8f312..15dd8457 100644
--- a/xmodem/src/main/java/com/proxgrind/xmodem/XModem1024.java
+++ b/chameleon/src/main/java/cn/rrg/chameleon/xmodem/XModem1024.java
@@ -1,4 +1,4 @@
-package com.proxgrind.xmodem;
+package cn.rrg.chameleon.xmodem;
import java.io.IOException;
import java.io.InputStream;
diff --git a/xmodem/src/main/java/com/proxgrind/xmodem/XModem128.java b/chameleon/src/main/java/cn/rrg/chameleon/xmodem/XModem128.java
similarity index 99%
rename from xmodem/src/main/java/com/proxgrind/xmodem/XModem128.java
rename to chameleon/src/main/java/cn/rrg/chameleon/xmodem/XModem128.java
index 32fe107d..8aec876b 100644
--- a/xmodem/src/main/java/com/proxgrind/xmodem/XModem128.java
+++ b/chameleon/src/main/java/cn/rrg/chameleon/xmodem/XModem128.java
@@ -1,4 +1,4 @@
-package com.proxgrind.xmodem;
+package cn.rrg.chameleon.xmodem;
import java.io.IOException;
import java.io.InputStream;
diff --git a/communication/build.gradle b/communication/build.gradle
index 2deecff1..f0115f0f 100644
--- a/communication/build.gradle
+++ b/communication/build.gradle
@@ -25,6 +25,5 @@ dependencies {
implementation 'com.github.felHR85:UsbSerial:6.1.0'
implementation 'androidx.annotation:annotation:1.1.0'
- implementation 'com.github.xianglin1998:ComBridge:1.0.7'
- // implementation project(path: ':iobridges')
+ implementation project(path: ':iobridges')
}
diff --git a/console/.gitignore b/console/.gitignore
new file mode 100644
index 00000000..3889eda0
--- /dev/null
+++ b/console/.gitignore
@@ -0,0 +1,62 @@
+# Built application files
+*.apk
+*.ap_
+
+# Files for the ART/Dalvik VM
+*.dex
+
+# Java class files
+*.class
+
+# Generated files
+bin/
+gen/
+out/
+
+# Cmake gen
+.cxx/
+
+# Gradle files
+.gradle/
+build/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Proguard folder generated by Eclipse
+proguard/
+
+# Log Files
+*.log
+
+# Android Studio Navigation editor temp files
+.navigation/
+
+# Android Studio captures folder
+captures/
+
+# IntelliJ
+*.iml
+.idea/
+
+# Keystore files
+# Uncomment the following line if you do not want to check your keystore files in.
+#*.jks
+
+# External native build folder generated in Android Studio 2.2 and later
+.externalNativeBuild
+
+# Google Services (e.g. APIs or Firebase)
+google-services.json
+
+# Freeline
+freeline.py
+freeline/
+freeline_project_description.json
+
+# fastlane
+fastlane/report.xml
+fastlane/Preview.html
+fastlane/screenshots
+fastlane/test_output
+fastlane/readme.md
diff --git a/console/build.gradle b/console/build.gradle
new file mode 100644
index 00000000..deea0a6e
--- /dev/null
+++ b/console/build.gradle
@@ -0,0 +1,33 @@
+apply plugin: 'com.android.library'
+apply plugin: 'com.github.dcendents.android-maven'
+group = 'com.github.xianglin1998'
+version = '1.0'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.3"
+
+ defaultConfig {
+ minSdkVersion 19
+ targetSdkVersion 29
+ versionCode 1
+ versionName "1.0"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ debug {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+}
diff --git a/xmodem/proguard-rules.pro b/console/proguard-rules.pro
similarity index 100%
rename from xmodem/proguard-rules.pro
rename to console/proguard-rules.pro
diff --git a/xmodem/src/main/AndroidManifest.xml b/console/src/main/AndroidManifest.xml
similarity index 64%
rename from xmodem/src/main/AndroidManifest.xml
rename to console/src/main/AndroidManifest.xml
index 3514a0eb..cab5590f 100644
--- a/xmodem/src/main/AndroidManifest.xml
+++ b/console/src/main/AndroidManifest.xml
@@ -1,2 +1,2 @@
+ package="cn.rrg.console" />
diff --git a/console/src/main/java/cn/rrg/console/define/ICommandTools.java b/console/src/main/java/cn/rrg/console/define/ICommandTools.java
new file mode 100644
index 00000000..b29fce4d
--- /dev/null
+++ b/console/src/main/java/cn/rrg/console/define/ICommandTools.java
@@ -0,0 +1,24 @@
+package cn.rrg.console.define;
+
+/*
+ * 定义命令行程序的接口!
+ * */
+public interface ICommandTools {
+ /**
+ * 执行一个命令,根据传入的参数!
+ * @param cmd 命令行,需要被执行的命令
+ * @return 程序执行命令可能返回的值
+ * */
+ int startExecute(String cmd);
+
+ /*
+ * 当前是否在执行当中!
+ * @return 是否在运行当中,true or false
+ * */
+ boolean isExecuting();
+
+ /*
+ * 停止一个当前正在执行的命令!
+ * */
+ void stopExecute();
+}
diff --git a/console/src/main/java/cn/rrg/console/define/ICommandType.java b/console/src/main/java/cn/rrg/console/define/ICommandType.java
new file mode 100644
index 00000000..1c9f15d9
--- /dev/null
+++ b/console/src/main/java/cn/rrg/console/define/ICommandType.java
@@ -0,0 +1,24 @@
+package cn.rrg.console.define;
+
+/*
+ * 类型,对于控制台输出,可能有,1、密钥,2、数据,3、普通文本
+ * */
+public interface ICommandType {
+ //是一个密钥
+ boolean isKey(String output);
+
+ //该怎么解析
+ String parseKey(String output);
+
+ //是一段数据
+ boolean isData(String output);
+
+ //该怎么解析
+ String parseData(String output);
+
+ //是普通文本
+ boolean isText(String output);
+
+ //该怎么解析
+ Runnable parseText(String output);
+}
diff --git a/console/src/main/res/values/strings.xml b/console/src/main/res/values/strings.xml
new file mode 100644
index 00000000..19df965e
--- /dev/null
+++ b/console/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ console
+
diff --git a/crapto1/.gitignore b/crapto1/.gitignore
new file mode 100644
index 00000000..3889eda0
--- /dev/null
+++ b/crapto1/.gitignore
@@ -0,0 +1,62 @@
+# Built application files
+*.apk
+*.ap_
+
+# Files for the ART/Dalvik VM
+*.dex
+
+# Java class files
+*.class
+
+# Generated files
+bin/
+gen/
+out/
+
+# Cmake gen
+.cxx/
+
+# Gradle files
+.gradle/
+build/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Proguard folder generated by Eclipse
+proguard/
+
+# Log Files
+*.log
+
+# Android Studio Navigation editor temp files
+.navigation/
+
+# Android Studio captures folder
+captures/
+
+# IntelliJ
+*.iml
+.idea/
+
+# Keystore files
+# Uncomment the following line if you do not want to check your keystore files in.
+#*.jks
+
+# External native build folder generated in Android Studio 2.2 and later
+.externalNativeBuild
+
+# Google Services (e.g. APIs or Firebase)
+google-services.json
+
+# Freeline
+freeline.py
+freeline/
+freeline_project_description.json
+
+# fastlane
+fastlane/report.xml
+fastlane/Preview.html
+fastlane/screenshots
+fastlane/test_output
+fastlane/readme.md
diff --git a/crapto1/build.gradle b/crapto1/build.gradle
new file mode 100644
index 00000000..c47af817
--- /dev/null
+++ b/crapto1/build.gradle
@@ -0,0 +1,41 @@
+apply plugin: 'com.android.library'
+apply plugin: 'com.github.dcendents.android-maven'
+group = 'com.github.xianglin1998'
+version = '1.3'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.2"
+
+ defaultConfig {
+ minSdkVersion 19
+ targetSdkVersion 29
+ externalNativeBuild {
+ cmake {
+ arguments '-DANDROID_STL=c++_static'
+ abiFilters "x86", "x86_64", "armeabi-v7a", "arm64-v8a"
+ }
+ //abiFilters "armeabi"
+ /*abiFilters "arm64-v8a"*/
+ /*abiFilters "x86_64"*/
+ /*abiFilters "arm64-v8a"
+ abiFilters "mips"
+ abiFilters "mips64"
+ abiFilters "x86"
+ abiFilters "x86_64"*/
+ }
+ }
+ externalNativeBuild {
+ cmake {
+ version '3.10.2'
+ path 'src/main/cpp/CMakeLists.txt'
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+}
\ No newline at end of file
diff --git a/crapto1/proguard-rules.pro b/crapto1/proguard-rules.pro
new file mode 100644
index 00000000..f1b42451
--- /dev/null
+++ b/crapto1/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/crapto1/src/main/AndroidManifest.xml b/crapto1/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..fd120117
--- /dev/null
+++ b/crapto1/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/crapto1/src/main/cpp/CMakeLists.txt b/crapto1/src/main/cpp/CMakeLists.txt
new file mode 100644
index 00000000..07d048bf
--- /dev/null
+++ b/crapto1/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,19 @@
+#需要的最cmake版本
+cmake_minimum_required(VERSION 3.4.1)
+
+#进行库(动态)的添加,在之后的参数中引入cpp/c文件
+add_library(
+ crapto1 SHARED
+ crapto1.c
+ crypto1.c
+ main.c)
+
+#进行头文件的添加!
+target_include_directories(crapto1 PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+#进行最终动态库的链接!
+target_link_libraries(
+ crapto1
+ android
+ log)
\ No newline at end of file
diff --git a/crapto1/src/main/cpp/crapto1.c b/crapto1/src/main/cpp/crapto1.c
new file mode 100644
index 00000000..5e03c1df
--- /dev/null
+++ b/crapto1/src/main/cpp/crapto1.c
@@ -0,0 +1,251 @@
+#include
+#include "crapto1.h"
+#include "crypto1.h"
+
+#pragma package(smart_init)
+#if !defined LOWMEM && defined __GNUC__
+static uint8_t filterlut[1 << 20];
+
+static void __attribute__((constructor)) fill_lut() {
+ uint32_t i;
+ for (i = 0; i < 1 << 20; ++i)
+ filterlut[i] = filter(i);
+}
+
+#define filter(x) (filterlut[(x) & 0xfffff])
+#endif
+
+/* quicksort
+ * in place quicksort of table
+ */
+static void
+quicksort(uint32_t *const start, uint32_t *const stop) {
+ uint32_t *it = start + 1, *rit = stop;
+
+ if (it > rit)
+ return;
+
+ while (it < rit)
+ if (*it < *start)
+ ++it;
+ else if (*rit >= *start)
+ --rit;
+ else
+ *it ^= (*it ^= *rit, *rit ^= *it);
+
+ if (*rit >= *start)
+ --rit;
+ if (rit != start)
+ *rit ^= (*rit ^= *start, *start ^= *rit);
+
+ quicksort(start, rit - 1);
+ quicksort(rit + 1, stop);
+}
+
+/* binsearch
+ * Binary search for the first occurence of *stop's MSB in sorted [start,stop]
+ */
+static inline uint32_t *
+binsearch(uint32_t *start, uint32_t *stop) {
+ uint32_t mid, val = *stop & 0xff000000;
+ while (start != stop)
+ if (start[mid = (stop - start) >> 1] > val)
+ stop = &start[mid];
+ else
+ start += mid + 1;
+
+ return start;
+}
+
+/* update_contribution
+ * helper, calculates the partial linear feedback contributions and puts in MSB
+ */
+static inline void
+update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2) {
+ uint32_t p = *item >> 25;
+
+ p = p << 1 | parity(*item & mask1);
+ p = p << 1 | parity(*item & mask2);
+ *item = p << 24 | (*item & 0xffffff);
+}
+
+/* extend_table
+ * using a bit of the keystream extend the table of possible lfsr states
+ */
+static inline void
+extend_table(uint32_t *tbl, uint32_t **end, int bit, uint32_t m1, uint32_t m2) {
+ for (; tbl <= *end; tbl++)
+ if (filter(*tbl <<= 1) == bit) {
+ if (filter(*tbl | 1) == bit) {
+ *++*end = tbl[1];
+ tbl[1] = tbl[0] | 1;
+ update_contribution(tbl++, m1, m2);
+ }
+ update_contribution(tbl, m1, m2);
+ } else if (filter(*tbl |= 1) == bit)
+ update_contribution(tbl, m1, m2);
+ else
+ *tbl-- = *(*end)--;
+}
+
+
+/* recover
+ * recursively narrow down the search space, 4 bits of keystream at a time
+ */
+static uint32_t *
+recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
+ uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem) {
+ uint32_t *o, *e, i;
+
+ if (rem == -1) {
+ o_head[1] = *e_head << 1;
+ *e_head &= LF_POLY_EVEN;
+ o_head[1] |= parity(*e_head ^ *o_head & LF_POLY_ODD);
+ return o_head;
+ }
+
+ for (i = 0; i < 4 && rem--; i++) {
+ extend_table(o_head, &o_tail, (oks >>= 1) & 1, LF_POLY_ODD * 2, LF_POLY_EVEN * 2 + 1);
+ extend_table(e_head, &e_tail, (eks >>= 1) & 1, LF_POLY_EVEN * 2 + 1, LF_POLY_ODD);
+ }
+
+ quicksort(o_head, o_tail);
+ quicksort(e_head, e_tail);
+
+ while (o_tail >= o_head && e_tail >= e_head)
+ if ((*o_tail ^ *e_tail) >> 24 == 0) {
+ o_tail = binsearch(o_head, o = o_tail);
+ e_tail = binsearch(e_head, e = e_tail);
+ if (e = recover(o_tail--, o, oks, e_tail--, e, eks, rem))
+ return e;
+ } else if (*o_tail > *e_tail)
+ --o_tail;
+ else
+ --e_tail;
+
+ return 0;
+}
+
+/* lfsr_recovery
+ * recover the state of the lfsr given a part of the keystream
+ */
+struct Crypto1State *lfsr_recovery(uint32_t ks2, uint32_t ks3) {
+ uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;
+ uint32_t *even_head = 0, *even_tail = 0, eks = 0, *res;
+
+ struct Crypto1State *state = crypto1_create(-1);
+ int i;
+
+ for (i = 31; i >= 0; i -= 2)
+ oks = oks << 1 | BEBIT(ks2, i) | BEBIT(ks3, i) << 16;
+ for (i = 30; i >= 0; i -= 2)
+ eks = eks << 1 | BEBIT(ks2, i) | BEBIT(ks3, i) << 16;
+
+
+ odd_head = odd_tail = (uint32_t *) malloc(sizeof(uint32_t) << 21);
+ even_head = even_tail = (uint32_t *) malloc(sizeof(uint32_t) << 21);
+ if (!odd_tail-- || !even_tail--)
+ goto out;
+
+ for (i = 1 << 20; i >= 0; --i) {
+ if (filter(i) == (oks & 1))
+ *++odd_tail = i;
+ if (filter(i) == (eks & 1))
+ *++even_tail = i;
+ }
+
+ for (i = 0; i < 4; i++) {
+ extend_table(odd_head, &odd_tail, (oks >>= 1) & 1, 0, 0);
+ extend_table(even_head, &even_tail, (eks >>= 1) & 1, 0, 0);
+ }
+
+ res = recover(odd_head, odd_tail, oks, even_head, even_tail, eks, 27);
+
+ if (res) {
+ state->odd = res[1];
+ state->even = res[0];
+ }
+ out:
+ free(odd_head);
+ free(even_head);
+ return state;
+}
+
+/* Variation mentioned in the paper. Borked due to omitted constants.
+ * comform the above version given 64 bits of keystream, it returns a possible
+ * cipher state if any.
+ * It can be optimized dramatically but since it was borked a somewhat readable
+ * and above all short version is included.
+ */
+#define MAGIX1 (0)
+#define MAGIX2 (0) /* Well this number isn't that magical ... */
+
+struct Crypto1State *lfsr_recovery_borked(uint32_t ks2, uint32_t ks3) {
+ struct Crypto1State *state = crypto1_create(-1);
+ uint32_t win = 0, oks = 0, eks = 0, tes, tos;
+ uint64_t cmb, *table = (uint64_t *) malloc(1 << 25), *tail = table - 1, *tbl;
+ int i;
+
+ for (i = 0; i < 32; i += 2)
+ oks = oks << 1 | BEBIT(ks3, i) | BEBIT(ks2, i) << 16;
+ for (i = 1; i < 32; i += 2)
+ eks = eks << 1 | BEBIT(ks3, i) | BEBIT(ks2, i) << 16;
+
+ for (i = 0; i < 1 << 20; ++i)
+ if (filter(i) == BIT(oks, 31))
+ *++tail = i;
+
+ for (i = 30; i > 2; --i)
+ for (*(tbl = table) <<= 1; tbl <= tail; *++tbl <<= 1)
+ if (filter(*tbl) ^ filter(*tbl | 1))
+ *tbl |= (filter(*tbl) != BIT(oks, i));
+ else if (filter(*tbl) == BIT(oks, i)) {
+ *++tail = *++tbl;
+ *tbl = tbl[-1] | 1;
+ } else
+ *tbl-- = *tail--;
+
+ for (; tail >= table; --tail) {
+ cmb = MAGIX1;
+ for (i = 0; i < 51; ++i) {
+ win = win << 1 ^ par64(*tail & cmb);
+ tes = tes << 1 ^ filter(win);
+ cmb = cmb >> 1 ^ -(cmb & 1) & MAGIX2;
+ }
+
+ for (i = 2; i >= 0; --i) {
+ *tail = *tail << 1 | par64(*tail & MAGIX2);
+ tos = tos << 1 | filter(*tail);
+ }
+
+ if (tes == eks && (tos & 7) == (oks & 7)) {
+ state->odd = *tail << 1 | par64(*tail & MAGIX2);
+ state->even = win;
+ }
+ }
+
+ free(table);
+ return state;
+}
+
+/* lfsr_rollback
+ * Rollback the shift register in order to get previous states
+ */
+void lfsr_rollback(struct Crypto1State *s, uint32_t in, int fb) {
+ int i, out;
+
+ s->odd &= 0xffffff;
+ s->even &= 0xffffff;
+ for (i = 31; i >= 0; --i) {
+ s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);
+
+ out = s->even & 1;
+ out ^= LF_POLY_EVEN & (s->even >>= 1);
+ out ^= LF_POLY_ODD & s->odd;
+ out ^= BEBIT(in, i);
+ out ^= filter(s->odd) & !!fb;
+
+ s->even |= parity(out) << 23;
+ }
+}
+
diff --git a/crapto1/src/main/cpp/crypto1.c b/crapto1/src/main/cpp/crypto1.c
new file mode 100644
index 00000000..a772a99a
--- /dev/null
+++ b/crapto1/src/main/cpp/crypto1.c
@@ -0,0 +1,90 @@
+/* crypto1.c
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, US
+
+ Copyright (C) 2008-2008 bla
+*/
+#include "crapto1.h"
+#include
+
+#define SWAPENDIAN(x)\
+ (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
+
+struct Crypto1State *crypto1_create(uint64_t key) {
+ struct Crypto1State *s = malloc(sizeof(*s));
+ int i;
+ for (i = 47; s && i > 0; i -= 2) {
+ s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
+ s->even = s->even << 1 | BIT(key, i ^ 7);
+ }
+ return s;
+}
+
+void crypto1_destroy(struct Crypto1State *state) {
+ free(state);
+}
+
+void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr) {
+ int i;
+ for (*lfsr = 0, i = 23; i >= 0; --i) {
+ *lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
+ *lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
+ }
+}
+
+uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted) {
+ uint32_t feedin;
+ uint8_t ret = filter(s->odd);
+
+ feedin = ret & !!is_encrypted;
+ feedin ^= !!in;
+ feedin ^= LF_POLY_ODD & s->odd;
+ feedin ^= LF_POLY_EVEN & s->even;
+ s->even = s->even << 1 | parity(feedin);
+
+ s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);
+
+ return ret;
+}
+
+uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted) {
+ uint8_t i, ret = 0;
+
+ for (i = 0; i < 8; ++i)
+ ret |= crypto1_bit(s, BIT(in, i), is_encrypted) << i;
+
+ return ret;
+}
+
+uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted) {
+ uint32_t i, ret = 0;
+
+ for (i = 0; i < 32; ++i)
+ ret |= crypto1_bit(s, BEBIT(in, i), is_encrypted) << (i ^ 24);
+
+ return ret;
+}
+
+/* prng_successor
+ * helper used to obscure the keystream during authentication
+ */
+uint32_t prng_successor(uint32_t x, uint32_t n) {
+ SWAPENDIAN(x);
+ while (n--)
+ x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
+
+ return SWAPENDIAN(x);
+}
diff --git a/crapto1/src/main/cpp/include/crapto1.h b/crapto1/src/main/cpp/include/crapto1.h
new file mode 100644
index 00000000..78cd493f
--- /dev/null
+++ b/crapto1/src/main/cpp/include/crapto1.h
@@ -0,0 +1,57 @@
+//---------------------------------------------------------------------------
+
+#ifndef crapto1H
+#define crapto1H
+//---------------------------------------------------------------------------
+#include "crypto1.h"
+#include
+
+struct Crypto1State {
+ unsigned int odd, even;
+};
+
+struct Crypto1State *crypto1_create(uint64_t key);
+
+void crypto1_destroy(struct Crypto1State *state);
+
+void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr);
+
+unsigned int crypto1_word(struct Crypto1State *state, unsigned int in_word, int fb);
+
+unsigned int prng_successor(unsigned int x, unsigned int n);
+
+struct Crypto1State *lfsr_recovery(unsigned int ks2, unsigned int ks3);
+
+struct Crypto1State *lfsr_recovery_borked(unsigned int ks2, unsigned int ks3);
+
+void lfsr_rollback(struct Crypto1State *s, unsigned int in, int fb);
+
+#define LF_POLY_ODD (0x29CE5C)
+#define LF_POLY_EVEN (0x870804)
+#define BIT(x, n) ((x) >> (n) & 1)
+#define BEBIT(x, n) ((x) >> ((n) ^ 24) & 1)
+
+static inline int parity(unsigned int x) {
+ x ^= x >> 16;
+ x ^= x >> 8;
+ x ^= x >> 4;
+ return BIT(0x6996, x & 0xf);
+}
+
+static inline int par64(uint64_t x) {
+ return parity(x ^ x >> 32);
+}
+
+static inline int filter(unsigned int const x) {
+ unsigned int f;
+
+ f = 0xf22c0 >> (x & 0xf) & 16;
+ f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8;
+ f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4;
+ f |= 0x1e458 >> (x >> 12 & 0xf) & 2;
+ f |= 0x0d938 >> (x >> 16 & 0xf) & 1;
+ return BIT(0xEC57E80A, f);
+}
+
+#endif
+
diff --git a/crapto1/src/main/cpp/include/crypto1.h b/crapto1/src/main/cpp/include/crypto1.h
new file mode 100644
index 00000000..d99a56d3
--- /dev/null
+++ b/crapto1/src/main/cpp/include/crypto1.h
@@ -0,0 +1,19 @@
+//---------------------------------------------------------------------------
+#ifndef crypto1H
+#define crypto1H
+//---------------------------------------------------------------------------
+#include "crapto1.h"
+#include
+
+struct Crypto1State *crypto1_create(uint64_t key);
+
+void crypto1_destroy(struct Crypto1State *state);
+
+void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr);
+
+unsigned int crypto1_word(struct Crypto1State *s, unsigned int in_word, int fb);
+
+unsigned int prng_successor(unsigned int x, unsigned int n);
+
+#endif
+
diff --git a/crapto1/src/main/cpp/main.c b/crapto1/src/main/cpp/main.c
new file mode 100644
index 00000000..bb1ed3f5
--- /dev/null
+++ b/crapto1/src/main/cpp/main.c
@@ -0,0 +1,183 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+//转为小写字符串!
+char *strupr(char *str) {
+ char *ret = str;
+ char *tmp = ret;
+ //测试长度!
+ size_t len = strlen(tmp);
+ while (len != 0 && tmp != NULL) {
+ *str = (char) toupper(*tmp);
+ --len;
+ ++tmp;
+ ++str;
+ }
+ return ret;
+}
+
+struct CHexMap {
+ char chr;
+ int value;
+};
+const int HexMapL = 16;
+struct CHexMap HexMap[HexMapL] = {
+ {'0', 0},
+ {'1', 1},
+ {'2', 2},
+ {'3', 3},
+ {'4', 4},
+ {'5', 5},
+ {'6', 6},
+ {'7', 7},
+ {'8', 8},
+ {'9', 9},
+ {'A', 10},
+ {'B', 11},
+ {'C', 12},
+ {'D', 13},
+ {'E', 14},
+ {'F', 15}
+};
+
+//16进制字符串转整形!
+uint32_t httoi(const char *value) {
+ //拷贝一份新的!
+ char *newCs = strdup(value);
+ char *s = strupr(newCs);;
+ uint32_t result = 0;
+ if (*s == '0' && *(s + 1) == 'X') s += 2;
+ bool firsttime = true;
+ while (*s != '\0') {
+ bool found = false;
+ for (int i = 0; i < HexMapL; i++) {
+ if (*s == HexMap[i].chr) {
+ if (!firsttime) result <<= 4;
+ result |= HexMap[i].value;
+ found = true;
+ break;
+ }
+ }
+ if (!found) break;
+ s++;
+ firsttime = false;
+ }
+ //LOGD("尝试输出字符值: %s", mstr);
+ free(newCs);
+ return result;
+}
+
+//主函数,进行最终的线性反馈寄存器算法回滚!
+uint64_t finalKey(const char *id, const char *tc, const char *rc, const char *rr, const char *tr) {
+ struct Crypto1State *revstate;
+ uint64_t lfsr;
+ //获得输入框得UID
+ uint32_t uid = httoi(id);
+ //LOGD("测试输出ID : %u", uid);
+ //获得TAG得收集信息!
+ uint32_t tag_challenge = httoi(tc);
+ //LOGD("测试输出TC : %u", tag_challenge);
+ //获得ENC
+ uint32_t nr_enc = httoi(rc);
+ //LOGD("测试输出RC : %u", nr_enc);
+ //获得来自于读卡器得应答
+ uint32_t reader_response = httoi(rr);
+ //LOGD("测试输出RR : %u", reader_response);
+ //获得来自于标签得应答
+ uint32_t tag_response = httoi(tr);
+ //LOGD("测试输出TR : %u", tag_response);
+ //进行ks计算
+ uint32_t ks2 = reader_response ^prng_successor(tag_challenge, 64);
+ uint32_t ks3 = tag_response ^prng_successor(tag_challenge, 96);
+ //调用线性反馈寄存器关键函数进行计算
+ revstate = lfsr_recovery(ks2, ks3);
+ //尝试回滚
+ lfsr_rollback(revstate, 0, 0);
+ //第二次尝试回滚
+ lfsr_rollback(revstate, 0, 0);
+ //通过nr尝试回滚
+ lfsr_rollback(revstate, nr_enc, 1);
+ //通过uid与关键信息进行回滚
+ lfsr_rollback(revstate, uid ^ tag_challenge, 0);
+ //得到关键密钥
+ crypto1_get_lfsr(revstate, &lfsr);
+ //回收内存!
+ crypto1_destroy(revstate);
+ //返回最终结果
+ return lfsr;
+}
+
+//映射函数,两端映射,类型转换!
+jstring
+final(JNIEnv *env, jobject instance, jstring hexID, jstring hexTC, jstring hexRC, jstring hexRR,
+ jstring hexTR) {
+ if (hexID == NULL || hexTC == NULL || hexRC == NULL || hexRR == NULL || hexTR == NULL) {
+ return NULL;
+ }
+ jboolean isCopy = false;
+ //获得字符数组!
+ const char *id = (*env)->GetStringUTFChars(env, hexID, &isCopy);
+ //const jint idLen = (*env)->GetStringUTFLength(env, hexID);
+ // LOGD("final ID: %s", id);
+ const char *tc = (*env)->GetStringUTFChars(env, hexTC, &isCopy);
+ //const jint tcLen = (*env)->GetStringUTFLength(env, hexTC);
+ //LOGD("final TC: %s", tc);
+ const char *rc = (*env)->GetStringUTFChars(env, hexRC, &isCopy);
+ //const jint rcLen = (*env)->GetStringUTFLength(env, hexRC);
+ //LOGD("final RC: %s", rc);
+ const char *rr = (*env)->GetStringUTFChars(env, hexRR, &isCopy);
+ //const jint rrLen = (*env)->GetStringUTFLength(env, hexRR);
+ //LOGD("final RR: %s", rr);
+ const char *tr = (*env)->GetStringUTFChars(env, hexTR, &isCopy);
+ //const jint trLen = (*env)->GetStringUTFLength(env, hexTR);
+ //LOGD("final TR: %s", tr);
+ //调用主要的逻辑函数,进行计算!
+ uint64_t key = finalKey(id, tc, rc, rr, tr);
+ //谨记释放!
+ (*env)->ReleaseStringUTFChars(env, hexID, id);
+ (*env)->ReleaseStringUTFChars(env, hexTC, tc);
+ (*env)->ReleaseStringUTFChars(env, hexRC, rc);
+ (*env)->ReleaseStringUTFChars(env, hexRR, rr);
+ (*env)->ReleaseStringUTFChars(env, hexTR, tr);
+ //进行格式化转换!
+ char keyChars[13] = {0};
+ memset(keyChars, 0, sizeof(keyChars));
+ sprintf(keyChars, "%012"PRIX64, key);
+ //LOGD("输出测试的64位值: %lu", key);
+ //LOGD("输出测试的密钥: %s", keyChars);
+ return (*env)->NewStringUTF(env, keyChars);
+}
+
+/*
+ * jvm加载so时的映射回调
+ * */
+JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+ JNIEnv *jniEnv = NULL;
+ //得到当前的jvm环境指针
+ if ((*vm)->GetEnv(vm, (void **) &jniEnv, JNI_VERSION_1_4) != JNI_OK) {
+ return -1;
+ }
+ //得到native函数的定义类
+ jclass clazz = (*jniEnv)->FindClass(jniEnv, "cn/dxl/crapto1/Crapto1");
+ if (clazz == NULL) {
+ return -1;
+ }
+ //构建和初始化函数结构体,分别是java层的函数名称,签名,对应的函数指针
+ JNINativeMethod methods[] = {
+ {"finalKeyNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void *) final},
+ };
+ //注册函数
+ if ((*jniEnv)->RegisterNatives(jniEnv, clazz, methods,
+ sizeof(methods) / sizeof(methods[0])) !=
+ JNI_OK) {
+ return -1;
+ }
+ //最后一定要返回jni的版本。
+ return JNI_VERSION_1_4;
+}
\ No newline at end of file
diff --git a/crapto1/src/main/java/cn/dxl/crapto1/Crapto1.java b/crapto1/src/main/java/cn/dxl/crapto1/Crapto1.java
new file mode 100644
index 00000000..e9d18d41
--- /dev/null
+++ b/crapto1/src/main/java/cn/dxl/crapto1/Crapto1.java
@@ -0,0 +1,62 @@
+package cn.dxl.crapto1;
+
+/*
+ * 此class用于crapto1算法的回滚计算!
+ * */
+public class Crapto1 {
+
+ static {
+ //加载动态库!
+ System.loadLibrary("crapto1");
+ }
+
+ private String mHexId = null;
+ private String mHexTC = null;
+ private String mHexRC = null;
+ private String mHexRR = null;
+ private String mHexTR = null;
+
+ public Crapto1 setUid(String hexID) {
+ mHexId = hexID;
+ return this;
+ }
+
+ public Crapto1 setTagChallenge(String hexTC) {
+ mHexTC = hexTC;
+ return this;
+ }
+
+ public Crapto1 setReaderChallenge(String hexRC) {
+ mHexRC = hexRC;
+ return this;
+ }
+
+ public Crapto1 setReaderResponse(String hexRR) {
+ mHexRR = hexRR;
+ return this;
+ }
+
+ public Crapto1 setTagResponse(String hexTR) {
+ mHexTR = hexTR;
+ return this;
+ }
+
+ public String finalKey() {
+ //非空判定!
+ if (mHexId == null || mHexTC == null ||
+ mHexRC == null || mHexRR == null || mHexTR == null)
+ return null;
+ //格式判定!
+ if (invailV(mHexId) || invailV(mHexTC)
+ || invailV(mHexRC) || invailV(mHexRR) || invailV(mHexTR)) {
+ return null;
+ }
+ return finalKeyNative(mHexId, mHexTC, mHexRC, mHexRR, mHexTR);
+ }
+
+ private boolean invailV(String v) {
+ return v.length() != 8 || !v.matches("[A-Za-z0-9]+");
+ }
+
+ private native String finalKeyNative(String id, String tc, String rc, String rr, String tr);
+}
diff --git a/crapto1/src/main/res/values/strings.xml b/crapto1/src/main/res/values/strings.xml
new file mode 100644
index 00000000..6fe96e97
--- /dev/null
+++ b/crapto1/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Crapto1
+
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 11596900..68a5564b 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Feb 26 18:00:31 CST 2020
+#Fri Oct 23 15:04:20 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
diff --git a/xmodem/.gitignore b/iobridges/.gitignore
similarity index 100%
rename from xmodem/.gitignore
rename to iobridges/.gitignore
diff --git a/xmodem/build.gradle b/iobridges/build.gradle
similarity index 86%
rename from xmodem/build.gradle
rename to iobridges/build.gradle
index 631889a0..caf614e2 100644
--- a/xmodem/build.gradle
+++ b/iobridges/build.gradle
@@ -1,4 +1,7 @@
apply plugin: 'com.android.library'
+apply plugin: 'com.github.dcendents.android-maven'
+group = 'com.github.xianglin1998'
+version = '1.0.7'
android {
compileSdkVersion 29
@@ -8,7 +11,7 @@ android {
minSdkVersion 19
targetSdkVersion 29
versionCode 1
- versionName "1.0"
+ versionName "1.0.7"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
diff --git a/xmodem/consumer-rules.pro b/iobridges/consumer-rules.pro
similarity index 100%
rename from xmodem/consumer-rules.pro
rename to iobridges/consumer-rules.pro
diff --git a/iobridges/proguard-rules.pro b/iobridges/proguard-rules.pro
new file mode 100644
index 00000000..f1b42451
--- /dev/null
+++ b/iobridges/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/xmodem/src/androidTest/java/com/proxgrind/xmodem/ExampleInstrumentedTest.java b/iobridges/src/androidTest/java/com/dxl/iobridges/ExampleInstrumentedTest.java
similarity index 85%
rename from xmodem/src/androidTest/java/com/proxgrind/xmodem/ExampleInstrumentedTest.java
rename to iobridges/src/androidTest/java/com/dxl/iobridges/ExampleInstrumentedTest.java
index 3effb2cd..48061e3c 100644
--- a/xmodem/src/androidTest/java/com/proxgrind/xmodem/ExampleInstrumentedTest.java
+++ b/iobridges/src/androidTest/java/com/dxl/iobridges/ExampleInstrumentedTest.java
@@ -1,4 +1,4 @@
-package com.proxgrind.xmodem;
+package com.dxl.iobridges;
import android.content.Context;
@@ -22,6 +22,6 @@ public class ExampleInstrumentedTest {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
- assertEquals("com.proxgrind.xmodem.test", appContext.getPackageName());
+ assertEquals("com.dxl.iobridges.test", appContext.getPackageName());
}
}
diff --git a/iobridges/src/main/AndroidManifest.xml b/iobridges/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..5d3fad28
--- /dev/null
+++ b/iobridges/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/iobridges/src/main/java/com/iobridges/bulkio/BulkInputStream.java b/iobridges/src/main/java/com/iobridges/bulkio/BulkInputStream.java
new file mode 100644
index 00000000..cfee7660
--- /dev/null
+++ b/iobridges/src/main/java/com/iobridges/bulkio/BulkInputStream.java
@@ -0,0 +1,56 @@
+package com.iobridges.bulkio;
+
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbEndpoint;
+
+import androidx.annotation.NonNull;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BulkInputStream extends InputStream {
+ private int timeout;
+ private UsbDeviceConnection connection;
+ private UsbEndpoint endpoint;
+
+ public BulkInputStream(UsbDeviceConnection connection, UsbEndpoint endpoint) {
+ this.connection = connection;
+ this.endpoint = endpoint;
+ }
+
+ @Override
+ public int read() throws IOException {
+ byte[] bs = new byte[1];
+ int len = connection.bulkTransfer(endpoint, bs, 1, timeout);
+ if (len > 0) {
+ return bs[0];
+ }
+ if (len < 0) {
+ return -1;
+ }
+ return 0;
+ }
+
+ @Override
+ public int read(@NonNull byte[] b) throws IOException {
+ return connection.bulkTransfer(endpoint, b, b.length, timeout);
+ }
+
+ @Override
+ public int read(@NonNull byte[] b, int off, int len) throws IOException {
+ return connection.bulkTransfer(endpoint, b, off, len, timeout);
+ }
+
+ public int getTimeout() {
+ return timeout;
+ }
+
+ public void setTimeout(int timeout) {
+ this.timeout = timeout;
+ }
+
+ @Override
+ public void close() throws IOException {
+ connection.close();
+ }
+}
diff --git a/iobridges/src/main/java/com/iobridges/bulkio/BulkOutputStream.java b/iobridges/src/main/java/com/iobridges/bulkio/BulkOutputStream.java
new file mode 100644
index 00000000..f0d2faf0
--- /dev/null
+++ b/iobridges/src/main/java/com/iobridges/bulkio/BulkOutputStream.java
@@ -0,0 +1,48 @@
+package com.iobridges.bulkio;
+
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbEndpoint;
+
+import androidx.annotation.NonNull;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class BulkOutputStream extends OutputStream {
+ private int timeout = 2333;
+ private UsbDeviceConnection connection;
+ private UsbEndpoint endpoint;
+
+ public BulkOutputStream(UsbDeviceConnection connection, UsbEndpoint endpoint) {
+ this.connection = connection;
+ this.endpoint = endpoint;
+ }
+
+ public int getTimeout() {
+ return timeout;
+ }
+
+ public void setTimeout(int timeout) {
+ this.timeout = timeout;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ connection.bulkTransfer(endpoint, new byte[]{(byte) b}, 0, 1, timeout);
+ }
+
+ @Override
+ public void write(@NonNull byte[] b, int off, int len) throws IOException {
+ connection.bulkTransfer(endpoint, b, off, len, timeout);
+ }
+
+ @Override
+ public void write(@NonNull byte[] b) throws IOException {
+ connection.bulkTransfer(endpoint, b, 0, b.length, timeout);
+ }
+
+ @Override
+ public void close() throws IOException {
+ connection.close();
+ }
+}
diff --git a/iobridges/src/main/java/com/iobridges/com/Communication.java b/iobridges/src/main/java/com/iobridges/com/Communication.java
new file mode 100644
index 00000000..da7a26e8
--- /dev/null
+++ b/iobridges/src/main/java/com/iobridges/com/Communication.java
@@ -0,0 +1,22 @@
+package com.iobridges.com;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+
+/**
+ * author DXL
+ *
+ * @version 1.0
+ */
+public interface Communication extends Serializable {
+ /**
+ * Get OutputStream implement!
+ */
+ OutputStream getOutput();
+
+ /**
+ * Get InputStream implement!
+ */
+ InputStream getInput();
+}
\ No newline at end of file
diff --git a/iobridges/src/main/java/com/iobridges/com/DeviceChecker.java b/iobridges/src/main/java/com/iobridges/com/DeviceChecker.java
new file mode 100644
index 00000000..13a99909
--- /dev/null
+++ b/iobridges/src/main/java/com/iobridges/com/DeviceChecker.java
@@ -0,0 +1,55 @@
+package com.iobridges.com;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+
+/**
+ * Abstract device check base class, can judge whether the device and communication are normal!
+ *
+ * @author DXL
+ * @version 1.1
+ */
+public abstract class DeviceChecker implements Serializable, Closeable {
+ protected Communication communication;
+
+ public DeviceChecker(Communication communication) {
+ this.communication = communication;
+ }
+
+ /**
+ * Test a device is can work!
+ *
+ * @return if can work return true, if no, return false
+ */
+ public final boolean check() throws IOException {
+ if (communication == null) {
+ throw new IOException("The communication must be nonnull.");
+ }
+ InputStream is = communication.getInput();
+ OutputStream os = communication.getOutput();
+ if (is == null || os == null) {
+ throw new IOException("The inputStream and outputStream must be nonnull.");
+ }
+ // Auto init communication to mapper.
+ LocalComBridgeAdapter.getInstance().setInputStream(is).setOutputStream(os)
+ .startServer(LocalComBridgeAdapter.NAMESPACE_DEFAULT);
+ if (!checkDevice()) {
+ // if check failed, we must to close client!
+ close();
+ // and close client communication!
+ LocalComBridgeAdapter.getInstance().stopClient();
+ return false;
+ }
+ return true;
+ }
+
+ protected abstract boolean checkDevice() throws IOException;
+
+ /**
+ * Close the device(Should no close communication. only close device!)
+ */
+ public abstract void close() throws IOException;
+}
diff --git a/iobridges/src/main/java/com/iobridges/com/LocalComBridgeAdapter.java b/iobridges/src/main/java/com/iobridges/com/LocalComBridgeAdapter.java
new file mode 100644
index 00000000..089c4f21
--- /dev/null
+++ b/iobridges/src/main/java/com/iobridges/com/LocalComBridgeAdapter.java
@@ -0,0 +1,436 @@
+package com.iobridges.com;
+
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbEndpoint;
+import android.net.LocalServerSocket;
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import android.util.Log;
+
+import com.iobridges.utils.HexUtil;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.Arrays;
+
+/**
+ * @author DXL
+ * Created by DXL on 2017/8/21.
+ * Communication control mapping implementation,
+ * the realization of inter process communication!
+ */
+public final class LocalComBridgeAdapter implements Serializable {
+ /*
+ * Warning!!!
+ * If your implementation does not need to be mapped to the c/c++ (only Java exists), please do not use this tool class!
+ *
+ * 警告!!!
+ * 如果您的实现不需要映射到底层(只存在Java),请不要使用此工具类!
+ * */
+
+ // The namespace of the LocalServerSocket
+ public static final String NAMESPACE_DEFAULT = "DXL.COM.ASL";
+ // The tag of the log.
+ private final String LOG_TAG = "LocalComBridgeAdapter";
+ // 本地套接字服务!
+ private LocalServerSocket serverSocket;
+ // 单例!
+ private static LocalComBridgeAdapter instance;
+ // 设备输入流!
+ private volatile InputStream mInputStreamFromDevice;
+ // 设备输出流!
+ private volatile OutputStream mOutputStreamFromDevice;
+ // 客户端输入流
+ private volatile InputStream mInputStreamFromSocket;
+ // 客户端输出流
+ private volatile OutputStream mOutputStreamFromSocket;
+ // 是否已经连接!
+ private volatile boolean isHasClient = false;
+ // 是否关闭监听!
+ private volatile boolean listenAccept = false;
+ // 连接到转发服务的客户端!
+ private LocalSocket socket;
+ // 设备数据转发线程是否可以工作
+ private volatile boolean forwardWork = false;
+ // connection lock!
+ private static final Object LOCK = new Object();
+ // con thread status!
+ private volatile boolean isConThreadRunning = false;
+ // device thread status!
+ private volatile boolean isDeviceDataThreadRunning = false;
+ // server action timeout, default is 1000ms!
+ private int timeout = 1000;
+ // current namespace
+ private String namespace;
+ // is server stop
+ private volatile boolean isServerStopAction = false;
+ // The buffer max for the device IO, default is 16384
+ private int deviceBufferMax = 16384;
+
+ private LocalComBridgeAdapter() { /* No instantiation is required */ }
+
+ /**
+ * Data forward thread!
+ * data will from a InputStream to a OutputStream!
+ */
+ private class ConServerThread extends Thread {
+ @Override
+ public void run() {
+ while (listenAccept) {
+ try {
+ if (serverSocket != null) {
+ Log.d(LOG_TAG, "服务套接字堵塞等待连接中!");
+ isConThreadRunning = true;
+ LocalSocket socketInternal = serverSocket.accept();
+ if (isServerStopAction) throw new IOException("Server closed.");
+ Log.d(LOG_TAG, "服务套接字连接成功,将会开启一个客户端线程!");
+ mInputStreamFromSocket = socketInternal.getInputStream();
+ mOutputStreamFromSocket = socketInternal.getOutputStream();
+ socket = socketInternal;
+ isHasClient = true;
+ new SocketDataThread().start();
+ } else {
+ return;
+ }
+ } catch (IOException e) {
+ // e.printStackTrace();
+ isHasClient = false;
+ listenAccept = false;
+ Log.w(LOG_TAG, "Connection thread abort!");
+ break;
+ }
+ }
+ isConThreadRunning = false;
+ Log.d(LOG_TAG, "ConServerThread结束");
+ }
+ }
+
+ /**
+ * Data from socket to device transfer
+ * need client connect and stable communication!
+ */
+ private class SocketDataThread extends Thread {
+ private byte[] buffer = new byte[1024 * 500];
+
+ SocketDataThread() {
+ setPriority(MAX_PRIORITY);
+ }
+
+ @Override
+ public void run() {
+ Log.d(LOG_TAG, "SocketDataThread执行");
+ while (true) {
+ try {
+ int available = mInputStreamFromSocket.available();
+ if (available > 0) {
+ int len = mInputStreamFromSocket.read(buffer);
+ // Log.d(LOG_TAG, "mInputStreamFromSocket.read()->len: " + len);
+ if (len > 0) {
+ mOutputStreamFromDevice.write(Arrays.copyOf(buffer, len));
+ mOutputStreamFromDevice.flush();
+ // Log.d(LOG_TAG, "SocketDataThread数据传输: " + HexUtil.toHexString(buffer, 0, len));
+ }
+ if (len == -1) {
+ throw new IOException("Socket already disconnected.");
+ }
+ }
+ } catch (IOException e) {
+ // e.printStackTrace();
+ break;
+ } catch (Exception e) {
+ // e.printStackTrace();
+ }
+ }
+ Log.d(LOG_TAG, "SocketDataThread结束");
+ }
+ }
+
+ /**
+ * Data from device to socket client transfer
+ * default case, it is always worked at runtime!
+ */
+ private class DeviceDataThread extends Thread {
+ // 在某些机型上,这个值是无效的,会导致bulkTransfer()卡死
+ // private byte[] buffer = new byte[1024 * 500];
+ // 因此我们需要使用Usb规定的最大值
+ private final byte[] buffer = new byte[deviceBufferMax];
+
+ DeviceDataThread() {
+ setPriority(MAX_PRIORITY);
+ }
+
+ @Override
+ public void run() {
+ Log.d(LOG_TAG, "DeviceDataThread执行");
+ isDeviceDataThreadRunning = true;
+ while (forwardWork) {
+ if (isHasClient) { // 有客户端的时候才接收数据!
+ try {
+ int len = mInputStreamFromDevice.read(buffer);
+ if (len > 0) {
+ // Log.d(LOG_TAG, "mInputStreamFromDevice.read()->len: " + len);
+ mOutputStreamFromSocket.write(Arrays.copyOf(buffer, len));
+ mOutputStreamFromSocket.flush();
+ // Log.d(LOG_TAG, "DeviceDataThread数据传输: " + HexUtil.toHexString(buffer));
+ }
+ } catch (Exception e) {
+ // Empty
+ // e.printStackTrace();
+ }
+ }
+ }
+ Log.d(LOG_TAG, "DeviceDataThread结束");
+ }
+ }
+
+ public static LocalComBridgeAdapter getInstance() {
+ synchronized (LOCK) {
+ /*
+ * It is a single instance tools
+ * you can't instantiation than for once.
+ * */
+ if (instance == null) instance = new LocalComBridgeAdapter();
+ }
+ return instance;
+ }
+
+ /**
+ * get inputStream from external device
+ *
+ * @return the inputStream of device
+ */
+ public InputStream getInputStream() {
+ return mInputStreamFromDevice;
+ }
+
+ /**
+ * set inputStream from external device
+ * The adapter will automatically read bytes from this input stream
+ * and forward them to the client with socket
+ *
+ * @param mInputStream the inputStream from external device implement!
+ * @return this
+ */
+ public LocalComBridgeAdapter setInputStream(InputStream mInputStream) {
+ this.mInputStreamFromDevice = mInputStream;
+ return this;
+ }
+
+ /**
+ * get outputStream from external device
+ *
+ * @return the outputStream of device
+ */
+ public OutputStream getOutputStream() {
+ return mOutputStreamFromDevice;
+ }
+
+ /**
+ * set outputStream from external device
+ * The adapter will automatically read bytes from the socket client
+ * and write them to this output stream
+ *
+ * @param mOutputStream the outputStream from external device implement!
+ * @return this
+ */
+ public LocalComBridgeAdapter setOutputStream(OutputStream mOutputStream) {
+ this.mOutputStreamFromDevice = mOutputStream;
+ return this;
+ }
+
+ /**
+ * Turn on server on a namespace
+ * default namespace is {@link #NAMESPACE_DEFAULT }
+ * namespace only once instance at runtime
+ * namespace is unique
+ *
+ * @param namespace the namespace is also used when clients connect
+ * @return this
+ */
+ public LocalComBridgeAdapter startServer(String namespace) {
+ synchronized (LOCK) {
+ if (!listenAccept) {
+ listenAccept = true;
+ isConThreadRunning = false;
+ isServerStopAction = false;
+ try {
+ if (serverSocket == null) {
+ serverSocket = new LocalServerSocket(namespace);
+ this.namespace = namespace;
+ }
+ // 创建一个客户端连接线程
+ new ConServerThread().start();
+ } catch (IOException e) {
+ e.printStackTrace();
+ Log.e(LOG_TAG, "If you see an error message like \"Address already in use\", check that you call the stopServer function");
+ }
+ // wait con thread running...
+ long startTime = System.currentTimeMillis();
+ while (!isConThreadRunning) {
+ // Log.w(LOG_TAG, "Waiting for LocalComBridgeAdapter server start......");
+ if (System.currentTimeMillis() - startTime > timeout) {
+ Log.w(LOG_TAG, "LocalComBridgeAdapter server start timeout.");
+ return this;
+ }
+ }
+ } else {
+ Log.w(LOG_TAG, "LocalComBridgeAdapter already start!");
+ }
+ if (!forwardWork) {
+ forwardWork = true;
+ isDeviceDataThreadRunning = false;
+ // 创建一个数据转发线程
+ new DeviceDataThread().start();
+ // wait device data thread running...
+ long startTime = System.currentTimeMillis();
+ while (!isDeviceDataThreadRunning) {
+ // Log.w(LOG_TAG, "Waiting for LocalComBridgeAdapter server start......");
+ if (System.currentTimeMillis() - startTime > timeout) {
+ Log.w(LOG_TAG, "LocalComBridgeAdapter server start timeout.");
+ return this;
+ }
+ }
+ }
+ // if task is start successfully, we need sleep 100ms, ensure all resource is readied.
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ Log.d(LOG_TAG, "LocalComBridgeAdapter start!");
+ }
+ return this;
+ }
+
+ /**
+ * Stop server listen!
+ * After the service is stopped,
+ * the client will not be able to connect.
+ * In general, please do not shut down the service.
+ *
+ * @return this
+ */
+ public LocalComBridgeAdapter stopServer() {
+ synchronized (LOCK) {
+ listenAccept = false;
+ isServerStopAction = true;
+ isDeviceDataThreadRunning = false;
+ if (serverSocket != null) {
+ try {
+ simClient2CloseServer();
+ serverSocket.close();
+ } catch (IOException ignored) {
+ }
+ serverSocket = null;
+ }
+ long startTime = System.currentTimeMillis();
+ while (isConThreadRunning) {
+ // Log.w(LOG_TAG, "Waiting for LocalComBridgeAdapter server stop......");
+ if (System.currentTimeMillis() - startTime > timeout) {
+ Log.w(LOG_TAG, "LocalComBridgeAdapter server stop timeout.");
+ return this;
+ }
+ }
+ Log.d(LOG_TAG, "LocalComBridgeAdapter server stop!");
+ }
+ return this;
+ }
+
+ // Simulate the behavior of requesting a connection to close it
+ private void simClient2CloseServer() {
+ LocalSocket localSocket = new LocalSocket();
+ try {
+ localSocket.connect(new LocalSocketAddress(namespace));
+ localSocket.shutdownInput();
+ localSocket.shutdownOutput();
+ localSocket.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Stop client connection.
+ * Calling this function will close the client link from C/C++ or java or any...
+ * please call when you need to connect to a new client.
+ *
+ * @return this
+ */
+ public LocalComBridgeAdapter stopClient() {
+ synchronized (LOCK) {
+ isHasClient = false;
+ try {
+ if (socket != null) {
+ // close socket
+ socket.shutdownInput();
+ socket.shutdownOutput();
+ socket.close();
+ mInputStreamFromSocket.close();
+ mOutputStreamFromSocket.close();
+ socket = null;
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ Log.d(LOG_TAG, "LocalComBridgeAdapter client stop!");
+ }
+ return this;
+ }
+
+ /**
+ * The timeout fro start and stop server!
+ *
+ * @return timeout ms.
+ */
+ public int getTimeout() {
+ return timeout;
+ }
+
+ /**
+ * The timeout for start and stop server!
+ *
+ * @param timeout timeout ms.
+ * @return this
+ */
+ public LocalComBridgeAdapter setTimeout(int timeout) {
+ this.timeout = timeout;
+ return this;
+ }
+
+ /**
+ * Get buffer of device
+ *
+ * @return buffer size max
+ */
+ public int getDeviceBufferMax() {
+ return deviceBufferMax;
+ }
+
+ /**
+ * Set buffer size max of the device.
+ * if you are UsbDevice, the buffer size recommend use default!
+ * or less than 16384, see {@link android.hardware.usb.UsbDeviceConnection#bulkTransfer(UsbEndpoint, byte[], int, int)}
+ *
+ * @param deviceBufferMax the new size of buffer
+ * @return this
+ */
+ public LocalComBridgeAdapter setDeviceBufferMax(int deviceBufferMax) {
+ this.deviceBufferMax = deviceBufferMax;
+ return this;
+ }
+
+ /**
+ * Destroy all task and recovery all resources
+ * Warning!! this action only can run on app exit!
+ * It will destroy server and client, and adapter single instance!
+ * so, it can run on application exit only.
+ */
+ public void destroy() {
+ stopClient();
+ stopServer();
+ forwardWork = false;
+ instance = null;
+ }
+}
\ No newline at end of file
diff --git a/iobridges/src/main/java/com/iobridges/utils/HexUtil.java b/iobridges/src/main/java/com/iobridges/utils/HexUtil.java
new file mode 100644
index 00000000..b409f3e7
--- /dev/null
+++ b/iobridges/src/main/java/com/iobridges/utils/HexUtil.java
@@ -0,0 +1,260 @@
+package com.iobridges.utils;
+
+import android.util.Log;
+
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+public class HexUtil {
+ private final static char[] HEX_DIGITS = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+
+ public static String dumpHexString(byte[] array) {
+ return dumpHexString(array, 0, array.length);
+ }
+
+ public static String dumpHexString(byte[] array, int offset, int length) {
+ StringBuilder result = new StringBuilder();
+
+ byte[] line = new byte[16];
+ int lineIndex = 0;
+
+ result.append("\n0x");
+ result.append(toHexString(offset));
+
+ for (int i = offset; i < offset + length; i++) {
+ if (lineIndex == 16) {
+ result.append(" ");
+
+ for (int j = 0; j < 16; j++) {
+ if (line[j] > ' ' && line[j] < '~') {
+ result.append(new String(line, j, 1));
+ } else {
+ result.append(".");
+ }
+ }
+
+ result.append("\n0x");
+ result.append(toHexString(i));
+ lineIndex = 0;
+ }
+
+ byte b = array[i];
+ result.append(" ");
+ result.append(HEX_DIGITS[(b >>> 4) & 0x0F]);
+ result.append(HEX_DIGITS[b & 0x0F]);
+
+ line[lineIndex++] = b;
+ }
+
+ if (lineIndex != 16) {
+ int count = (16 - lineIndex) * 3;
+ count++;
+ for (int i = 0; i < count; i++) {
+ result.append(" ");
+ }
+
+ for (int i = 0; i < lineIndex; i++) {
+ if (line[i] > ' ' && line[i] < '~') {
+ result.append(new String(line, i, 1));
+ } else {
+ result.append(".");
+ }
+ }
+ }
+
+ return result.toString();
+ }
+
+ public static String toHexString(byte b) {
+ return toHexString(toByteArray(b));
+ }
+
+ public static String toHexString(byte[] array) {
+ if (array == null) return null;
+ return toHexString(array, 0, array.length);
+ }
+
+ public static String toHexString(Byte[] array) {
+ if (array == null) return null;
+ byte[] bytes = new byte[array.length];
+ for (int i = 0; i < array.length; i++) {
+ bytes[i] = array[i];
+ }
+ return toHexString(bytes, 0, array.length);
+ }
+
+ public static String toHexString(byte[] array, int offset, int length) {
+ char[] buf = new char[length * 2];
+
+ int bufIndex = 0;
+ for (int i = offset; i < offset + length; i++) {
+ byte b = array[i];
+ buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F];
+ buf[bufIndex++] = HEX_DIGITS[b & 0x0F];
+ }
+
+ return new String(buf);
+ }
+
+ public static String toHexString(int i) {
+ return toHexString(toByteArray(i));
+ }
+
+ public static String toHexString(short i) {
+ return toHexString(toByteArray(i));
+ }
+
+ public static String decorateHex(String hexStr) {
+ StringBuilder sb = new StringBuilder();
+ char[] charArr = hexStr.toCharArray();
+ for (int i = 0; i < charArr.length; i += 2) {
+ sb.append("0x").append(charArr[i])
+ .append(charArr[i + 1]).append(" ");
+ }
+ return sb.toString();
+ }
+
+ public static byte[] toByteArray(byte b) {
+ byte[] array = new byte[1];
+ array[0] = b;
+ return array;
+ }
+
+ public static byte[] toByteArray(int i) {
+ byte[] array = new byte[4];
+
+ array[3] = (byte) (i & 0xFF);
+ array[2] = (byte) ((i >> 8) & 0xFF);
+ array[1] = (byte) ((i >> 16) & 0xFF);
+ array[0] = (byte) ((i >> 24) & 0xFF);
+
+ return array;
+ }
+
+ public static byte[] toByteArray(short i) {
+ byte[] array = new byte[2];
+
+ array[1] = (byte) (i & 0xFF);
+ array[0] = (byte) ((i >> 8) & 0xFF);
+
+ return array;
+ }
+
+ private static int toByte(char c) {
+ if (c >= '0' && c <= '9')
+ return (c - '0');
+ if (c >= 'A' && c <= 'F')
+ return (c - 'A' + 10);
+ if (c >= 'a' && c <= 'f')
+ return (c - 'a' + 10);
+ Log.d("HexUtil", "The byte char is invalid: " + c);
+ //throw new RuntimeException("Invalid hex char '" + c + "'");
+ return 0;
+ }
+
+ public static int toInt(byte b) {
+ return b & 0xFF;
+ }
+
+ public static int toIntFrom2Byte(byte[] b) {
+ return Integer.parseInt(toHexString(b), 16);
+ }
+
+ /**
+ * 拆分byte数组
+ *
+ * @param bytes 要拆分的数组
+ * @param size 要按几个组成一份
+ * @return
+ */
+ public static byte[][] splitBytes(byte[] bytes, int size) {
+ double splitLength = Double.parseDouble(size + "");
+ int arrayLength = (int) Math.ceil(bytes.length / splitLength);
+ byte[][] result = new byte[arrayLength][];
+ int from, to;
+ for (int i = 0; i < arrayLength; i++) {
+ from = (int) (i * splitLength);
+ to = (int) (from + splitLength);
+ if (to > bytes.length)
+ to = bytes.length;
+ result[i] = Arrays.copyOfRange(bytes, from, to);
+ }
+ return result;
+ }
+
+ public static byte[] bytesMerge(byte[]... arrs) {
+ byte[] ret = new byte[byteArraysLength(arrs)];
+ int pos = 0;
+ for (byte[] tmp : arrs) {
+ if (tmp != null && tmp.length > 0) {
+ System.arraycopy(tmp, 0, ret, pos, tmp.length);
+ pos += tmp.length;
+ }
+ }
+ return ret;
+ }
+
+ public static int byteArraysLength(byte[]... arrs) {
+ int ret = 0;
+ for (byte[] tmp : arrs) {
+ if (tmp != null)
+ ret += tmp.length;
+ }
+ return ret;
+ }
+
+ public static int byteArrayToInt(byte[] b) {
+ return (b[3] & 0xFF) |
+ (b[2] & 0xFF) << 8 |
+ (b[1] & 0xFF) << 16 |
+ (b[0] & 0xFF) << 24;
+ }
+
+ public static int byte2Int(byte[] data, int offset) {
+ byte[] bs = new byte[4];
+ for (int i = offset, j = 0; j < bs.length; i++, j++) {
+ bs[j] = data[i];
+ }
+ return HexUtil.byteArrayToInt(bs);
+ }
+
+ public static int hexString2Int(String hexString) {
+ byte[] hexByte = hexStringToByteArray(hexString);
+ return byteArrayToInt(hexByte);
+ }
+
+ public static byte[] intToByteArray(int a) {
+ return new byte[]{
+ (byte) ((a >> 24) & 0xFF),
+ (byte) ((a >> 16) & 0xFF),
+ (byte) ((a >> 8) & 0xFF),
+ (byte) (a & 0xFF)
+ };
+ }
+
+ public static byte[] hexStringToByteArray(String hexString) {
+ if (hexString == null) return null;
+ if (hexString.length() == 0) return null;
+ int length = hexString.length();
+ byte[] buffer = new byte[length / 2];
+ for (int i = 0; i < length; i += 2) {
+ buffer[i / 2] = (byte) ((toByte(hexString.charAt(i)) << 4) | toByte(hexString
+ .charAt(i + 1)));
+ }
+ return buffer;
+ }
+
+ public static byte[] getAsciiBytes(String str) {
+ return str.getBytes(Charset.forName("ascii"));
+ }
+
+ //判断是否是十六进制格式的字符串
+ public static boolean isHexString(String str) {
+ if (str == null) return false;
+ if (str.matches("[0-9a-fA-F]+")) return true;
+ if (str.matches("0x[0-9a-fA-F]+")) return true;
+ return str.matches("0x[0-9a-fA-F] +");
+ }
+}
diff --git a/xmodem/src/test/java/com/proxgrind/xmodem/ExampleUnitTest.java b/iobridges/src/test/java/com/dxl/iobridges/ExampleUnitTest.java
similarity index 92%
rename from xmodem/src/test/java/com/proxgrind/xmodem/ExampleUnitTest.java
rename to iobridges/src/test/java/com/dxl/iobridges/ExampleUnitTest.java
index 91313efb..6aa17a86 100644
--- a/xmodem/src/test/java/com/proxgrind/xmodem/ExampleUnitTest.java
+++ b/iobridges/src/test/java/com/dxl/iobridges/ExampleUnitTest.java
@@ -1,4 +1,4 @@
-package com.proxgrind.xmodem;
+package com.dxl.iobridges;
import org.junit.Test;
diff --git a/libnfc_pn53x/build.gradle b/libnfc_pn53x/build.gradle
index ad232a3b..9b33b6e5 100644
--- a/libnfc_pn53x/build.gradle
+++ b/libnfc_pn53x/build.gradle
@@ -36,11 +36,10 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'com.github.xianglin1998:nfctag:1.0'
- implementation 'com.github.xianglin1998:nfc_console:1.0'
- implementation 'com.github.xianglin1998:ComBridge:1.0.7'
- // implementation project(path: ':iobridges')
+ implementation project(path: ':iobridges')
+ implementation project(path: ':nfctag')
+ implementation project(path: ':console')
implementation project(path: ':communication')
implementation 'androidx.appcompat:appcompat:1.1.0'
diff --git a/mfkey/.gitignore b/mfkey/.gitignore
new file mode 100644
index 00000000..796b96d1
--- /dev/null
+++ b/mfkey/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/mfkey/build.gradle b/mfkey/build.gradle
new file mode 100644
index 00000000..74f0bd8a
--- /dev/null
+++ b/mfkey/build.gradle
@@ -0,0 +1,50 @@
+apply plugin: 'com.android.library'
+apply plugin: 'com.github.dcendents.android-maven'
+group = 'com.github.xianglin1998'
+version = '1.1'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.2"
+
+ defaultConfig {
+ minSdkVersion 18
+ targetSdkVersion 29
+ externalNativeBuild {
+ cmake {
+ /*
+ * 参数必须给与-DHAVE_CONFIG_H,否则不可以把log文件附带编译!
+ * 指定以静态c++标准链接
+ * */
+ arguments '-DANDROID_STL=c++_static'
+ abiFilters "x86", "x86_64", "armeabi-v7a", "arm64-v8a"
+ }
+ //abiFilters "armeabi"
+ /*abiFilters "arm64-v8a"*/
+ /*abiFilters "x86_64"*/
+ /*abiFilters "arm64-v8a"
+ abiFilters "mips"
+ abiFilters "mips64"
+ abiFilters "x86"
+ abiFilters "x86_64"*/
+ }
+ }
+ externalNativeBuild {
+ cmake {
+ version '3.10.2'
+ path 'src/main/cpp/CMakeLists.txt'
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
diff --git a/mfkey/proguard-rules.pro b/mfkey/proguard-rules.pro
new file mode 100644
index 00000000..f1b42451
--- /dev/null
+++ b/mfkey/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/mfkey/src/main/AndroidManifest.xml b/mfkey/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..7f3f26dc
--- /dev/null
+++ b/mfkey/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/mfkey/src/main/cpp/CMakeLists.txt b/mfkey/src/main/cpp/CMakeLists.txt
new file mode 100644
index 00000000..7718f016
--- /dev/null
+++ b/mfkey/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,56 @@
+#需要的最cmake版本
+cmake_minimum_required(VERSION 3.4.1)
+
+#添加动态库定义
+add_library(mfkey32 SHARED
+ mfkey32.c
+ tools.c
+ parity.c
+ mfkey.c
+ util_posix.c
+ crypto1.c
+ crapto1.c
+ bucketsort.c
+ )
+
+#添加头文件配置
+target_include_directories(mfkey32 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/)
+
+#添加动态库链接!
+target_link_libraries(mfkey32 android log)
+
+#添加动态库定义
+add_library(mfkey64 SHARED
+ mfkey64.c
+ tools.c
+ parity.c
+ mfkey.c
+ util_posix.c
+ crypto1.c
+ crapto1.c
+ bucketsort.c
+ )
+
+#添加头文件配置
+target_include_directories(mfkey64 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/)
+
+#添加动态库链接!
+target_link_libraries(mfkey64 android log)
+
+#添加动态库定义
+add_library(mfkey32v2 SHARED
+ mfkey32v2.c
+ tools.c
+ parity.c
+ mfkey.c
+ util_posix.c
+ crypto1.c
+ crapto1.c
+ bucketsort.c
+ )
+
+#添加头文件配置
+target_include_directories(mfkey32v2 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/)
+
+#添加动态库链接!
+target_link_libraries(mfkey32v2 android log)
\ No newline at end of file
diff --git a/mfkey/src/main/cpp/at91sam7s512.h b/mfkey/src/main/cpp/at91sam7s512.h
new file mode 100644
index 00000000..2cdcbce3
--- /dev/null
+++ b/mfkey/src/main/cpp/at91sam7s512.h
@@ -0,0 +1,2296 @@
+// ----------------------------------------------------------------------------
+// ATMEL Microcontroller Software Support - ROUSSET -
+// ----------------------------------------------------------------------------
+// Copyright (c) 2006, Atmel Corporation
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the disclaimer below.
+//
+// Atmel's name may not be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+// DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// ----------------------------------------------------------------------------
+// File Name : AT91SAM7S512.h
+// Object : AT91SAM7S512 definitions
+// Generated : AT91 SW Application Group 07/07/2008 (16:13:20)
+//
+// CVS Reference : /AT91SAM7S512.pl/1.6/Wed Aug 30 14:08:44 2006//
+// CVS Reference : /SYS_SAM7S.pl/1.2/Thu Feb 3 10:47:39 2005//
+// CVS Reference : /MC_SAM7SE.pl/1.10/Thu Feb 16 16:35:28 2006//
+// CVS Reference : /PMC_SAM7S_USB.pl/1.4/Tue Feb 8 14:00:19 2005//
+// CVS Reference : /RSTC_SAM7S.pl/1.2/Wed Jul 13 15:25:17 2005//
+// CVS Reference : /UDP_4ept.pl/1.1/Thu Aug 3 12:26:00 2006//
+// CVS Reference : /PWM_SAM7S.pl/1.1/Tue May 10 12:38:54 2005//
+// CVS Reference : /AIC_6075B.pl/1.3/Fri May 20 14:21:42 2005//
+// CVS Reference : /PIO_6057A.pl/1.2/Thu Feb 3 10:29:42 2005//
+// CVS Reference : /RTTC_6081A.pl/1.2/Thu Nov 4 13:57:22 2004//
+// CVS Reference : /PITC_6079A.pl/1.2/Thu Nov 4 13:56:22 2004//
+// CVS Reference : /WDTC_6080A.pl/1.3/Thu Nov 4 13:58:52 2004//
+// CVS Reference : /VREG_6085B.pl/1.1/Tue Feb 1 16:40:38 2005//
+// CVS Reference : /PDC_6074C.pl/1.2/Thu Feb 3 09:02:11 2005//
+// CVS Reference : /DBGU_6059D.pl/1.1/Mon Jan 31 13:54:41 2005//
+// CVS Reference : /SPI_6088D.pl/1.3/Fri May 20 14:23:02 2005//
+// CVS Reference : /US_6089C.pl/1.1/Mon Jan 31 13:56:02 2005//
+// CVS Reference : /SSC_6078A.pl/1.1/Tue Jul 13 07:10:41 2004//
+// CVS Reference : /TWI_6061A.pl/1.2/Fri Oct 27 11:40:48 2006//
+// CVS Reference : /TC_6082A.pl/1.7/Wed Mar 9 16:31:51 2005//
+// CVS Reference : /ADC_6051C.pl/1.1/Mon Jan 31 13:12:40 2005//
+// CVS Reference : /EBI_SAM7SE512.pl/1.22/Fri Nov 18 17:47:47 2005//
+// CVS Reference : /SMC_1783A.pl/1.4/Thu Feb 3 10:30:06 2005//
+// CVS Reference : /SDRC_SAM7SE512.pl/1.7/Fri Jul 8 07:50:18 2005//
+// CVS Reference : /HECC_SAM7SE512.pl/1.8/Tue Jul 12 06:31:42 2005//
+// ----------------------------------------------------------------------------
+
+#ifndef AT91SAM7S512_H
+#define AT91SAM7S512_H
+
+#ifndef __ASSEMBLY__
+typedef volatile unsigned int AT91_REG;// Hardware register definition
+#define AT91_CAST(a) (a)
+#else
+#define AT91_CAST(a)
+#endif
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR System Peripherals
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_SYS {
+ AT91_REG AIC_SMR[32]; // Source Mode Register
+ AT91_REG AIC_SVR[32]; // Source Vector Register
+ AT91_REG AIC_IVR; // IRQ Vector Register
+ AT91_REG AIC_FVR; // FIQ Vector Register
+ AT91_REG AIC_ISR; // Interrupt Status Register
+ AT91_REG AIC_IPR; // Interrupt Pending Register
+ AT91_REG AIC_IMR; // Interrupt Mask Register
+ AT91_REG AIC_CISR; // Core Interrupt Status Register
+ AT91_REG Reserved0[2]; //
+ AT91_REG AIC_IECR; // Interrupt Enable Command Register
+ AT91_REG AIC_IDCR; // Interrupt Disable Command Register
+ AT91_REG AIC_ICCR; // Interrupt Clear Command Register
+ AT91_REG AIC_ISCR; // Interrupt Set Command Register
+ AT91_REG AIC_EOICR; // End of Interrupt Command Register
+ AT91_REG AIC_SPU; // Spurious Vector Register
+ AT91_REG AIC_DCR; // Debug Control Register (Protect)
+ AT91_REG Reserved1[1]; //
+ AT91_REG AIC_FFER; // Fast Forcing Enable Register
+ AT91_REG AIC_FFDR; // Fast Forcing Disable Register
+ AT91_REG AIC_FFSR; // Fast Forcing Status Register
+ AT91_REG Reserved2[45]; //
+ AT91_REG DBGU_CR; // Control Register
+ AT91_REG DBGU_MR; // Mode Register
+ AT91_REG DBGU_IER; // Interrupt Enable Register
+ AT91_REG DBGU_IDR; // Interrupt Disable Register
+ AT91_REG DBGU_IMR; // Interrupt Mask Register
+ AT91_REG DBGU_CSR; // Channel Status Register
+ AT91_REG DBGU_RHR; // Receiver Holding Register
+ AT91_REG DBGU_THR; // Transmitter Holding Register
+ AT91_REG DBGU_BRGR; // Baud Rate Generator Register
+ AT91_REG Reserved3[7]; //
+ AT91_REG DBGU_CIDR; // Chip ID Register
+ AT91_REG DBGU_EXID; // Chip ID Extension Register
+ AT91_REG DBGU_FNTR; // Force NTRST Register
+ AT91_REG Reserved4[45]; //
+ AT91_REG DBGU_RPR; // Receive Pointer Register
+ AT91_REG DBGU_RCR; // Receive Counter Register
+ AT91_REG DBGU_TPR; // Transmit Pointer Register
+ AT91_REG DBGU_TCR; // Transmit Counter Register
+ AT91_REG DBGU_RNPR; // Receive Next Pointer Register
+ AT91_REG DBGU_RNCR; // Receive Next Counter Register
+ AT91_REG DBGU_TNPR; // Transmit Next Pointer Register
+ AT91_REG DBGU_TNCR; // Transmit Next Counter Register
+ AT91_REG DBGU_PTCR; // PDC Transfer Control Register
+ AT91_REG DBGU_PTSR; // PDC Transfer Status Register
+ AT91_REG Reserved5[54]; //
+ AT91_REG PIOA_PER; // PIO Enable Register
+ AT91_REG PIOA_PDR; // PIO Disable Register
+ AT91_REG PIOA_PSR; // PIO Status Register
+ AT91_REG Reserved6[1]; //
+ AT91_REG PIOA_OER; // Output Enable Register
+ AT91_REG PIOA_ODR; // Output Disable Registerr
+ AT91_REG PIOA_OSR; // Output Status Register
+ AT91_REG Reserved7[1]; //
+ AT91_REG PIOA_IFER; // Input Filter Enable Register
+ AT91_REG PIOA_IFDR; // Input Filter Disable Register
+ AT91_REG PIOA_IFSR; // Input Filter Status Register
+ AT91_REG Reserved8[1]; //
+ AT91_REG PIOA_SODR; // Set Output Data Register
+ AT91_REG PIOA_CODR; // Clear Output Data Register
+ AT91_REG PIOA_ODSR; // Output Data Status Register
+ AT91_REG PIOA_PDSR; // Pin Data Status Register
+ AT91_REG PIOA_IER; // Interrupt Enable Register
+ AT91_REG PIOA_IDR; // Interrupt Disable Register
+ AT91_REG PIOA_IMR; // Interrupt Mask Register
+ AT91_REG PIOA_ISR; // Interrupt Status Register
+ AT91_REG PIOA_MDER; // Multi-driver Enable Register
+ AT91_REG PIOA_MDDR; // Multi-driver Disable Register
+ AT91_REG PIOA_MDSR; // Multi-driver Status Register
+ AT91_REG Reserved9[1]; //
+ AT91_REG PIOA_PPUDR; // Pull-up Disable Register
+ AT91_REG PIOA_PPUER; // Pull-up Enable Register
+ AT91_REG PIOA_PPUSR; // Pull-up Status Register
+ AT91_REG Reserved10[1]; //
+ AT91_REG PIOA_ASR; // Select A Register
+ AT91_REG PIOA_BSR; // Select B Register
+ AT91_REG PIOA_ABSR; // AB Select Status Register
+ AT91_REG Reserved11[9]; //
+ AT91_REG PIOA_OWER; // Output Write Enable Register
+ AT91_REG PIOA_OWDR; // Output Write Disable Register
+ AT91_REG PIOA_OWSR; // Output Write Status Register
+ AT91_REG Reserved12[469]; //
+ AT91_REG PMC_SCER; // System Clock Enable Register
+ AT91_REG PMC_SCDR; // System Clock Disable Register
+ AT91_REG PMC_SCSR; // System Clock Status Register
+ AT91_REG Reserved13[1]; //
+ AT91_REG PMC_PCER; // Peripheral Clock Enable Register
+ AT91_REG PMC_PCDR; // Peripheral Clock Disable Register
+ AT91_REG PMC_PCSR; // Peripheral Clock Status Register
+ AT91_REG Reserved14[1]; //
+ AT91_REG PMC_MOR; // Main Oscillator Register
+ AT91_REG PMC_MCFR; // Main Clock Frequency Register
+ AT91_REG Reserved15[1]; //
+ AT91_REG PMC_PLLR; // PLL Register
+ AT91_REG PMC_MCKR; // Master Clock Register
+ AT91_REG Reserved16[3]; //
+ AT91_REG PMC_PCKR[3]; // Programmable Clock Register
+ AT91_REG Reserved17[5]; //
+ AT91_REG PMC_IER; // Interrupt Enable Register
+ AT91_REG PMC_IDR; // Interrupt Disable Register
+ AT91_REG PMC_SR; // Status Register
+ AT91_REG PMC_IMR; // Interrupt Mask Register
+ AT91_REG Reserved18[36]; //
+ AT91_REG RSTC_RCR; // Reset Control Register
+ AT91_REG RSTC_RSR; // Reset Status Register
+ AT91_REG RSTC_RMR; // Reset Mode Register
+ AT91_REG Reserved19[5]; //
+ AT91_REG RTTC_RTMR; // Real-time Mode Register
+ AT91_REG RTTC_RTAR; // Real-time Alarm Register
+ AT91_REG RTTC_RTVR; // Real-time Value Register
+ AT91_REG RTTC_RTSR; // Real-time Status Register
+ AT91_REG PITC_PIMR; // Period Interval Mode Register
+ AT91_REG PITC_PISR; // Period Interval Status Register
+ AT91_REG PITC_PIVR; // Period Interval Value Register
+ AT91_REG PITC_PIIR; // Period Interval Image Register
+ AT91_REG WDTC_WDCR; // Watchdog Control Register
+ AT91_REG WDTC_WDMR; // Watchdog Mode Register
+ AT91_REG WDTC_WDSR; // Watchdog Status Register
+ AT91_REG Reserved20[5]; //
+ AT91_REG VREG_MR; // Voltage Regulator Mode Register
+} AT91S_SYS, *AT91PS_SYS;
+#else
+
+#endif
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Advanced Interrupt Controller
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_AIC {
+ AT91_REG AIC_SMR[32]; // Source Mode Register
+ AT91_REG AIC_SVR[32]; // Source Vector Register
+ AT91_REG AIC_IVR; // IRQ Vector Register
+ AT91_REG AIC_FVR; // FIQ Vector Register
+ AT91_REG AIC_ISR; // Interrupt Status Register
+ AT91_REG AIC_IPR; // Interrupt Pending Register
+ AT91_REG AIC_IMR; // Interrupt Mask Register
+ AT91_REG AIC_CISR; // Core Interrupt Status Register
+ AT91_REG Reserved0[2]; //
+ AT91_REG AIC_IECR; // Interrupt Enable Command Register
+ AT91_REG AIC_IDCR; // Interrupt Disable Command Register
+ AT91_REG AIC_ICCR; // Interrupt Clear Command Register
+ AT91_REG AIC_ISCR; // Interrupt Set Command Register
+ AT91_REG AIC_EOICR; // End of Interrupt Command Register
+ AT91_REG AIC_SPU; // Spurious Vector Register
+ AT91_REG AIC_DCR; // Debug Control Register (Protect)
+ AT91_REG Reserved1[1]; //
+ AT91_REG AIC_FFER; // Fast Forcing Enable Register
+ AT91_REG AIC_FFDR; // Fast Forcing Disable Register
+ AT91_REG AIC_FFSR; // Fast Forcing Status Register
+} AT91S_AIC, *AT91PS_AIC;
+#else
+#define AIC_SMR (AT91_CAST(AT91_REG *) 0x00000000) // (AIC_SMR) Source Mode Register
+#define AIC_SVR (AT91_CAST(AT91_REG *) 0x00000080) // (AIC_SVR) Source Vector Register
+#define AIC_IVR (AT91_CAST(AT91_REG *) 0x00000100) // (AIC_IVR) IRQ Vector Register
+#define AIC_FVR (AT91_CAST(AT91_REG *) 0x00000104) // (AIC_FVR) FIQ Vector Register
+#define AIC_ISR (AT91_CAST(AT91_REG *) 0x00000108) // (AIC_ISR) Interrupt Status Register
+#define AIC_IPR (AT91_CAST(AT91_REG *) 0x0000010C) // (AIC_IPR) Interrupt Pending Register
+#define AIC_IMR (AT91_CAST(AT91_REG *) 0x00000110) // (AIC_IMR) Interrupt Mask Register
+#define AIC_CISR (AT91_CAST(AT91_REG *) 0x00000114) // (AIC_CISR) Core Interrupt Status Register
+#define AIC_IECR (AT91_CAST(AT91_REG *) 0x00000120) // (AIC_IECR) Interrupt Enable Command Register
+#define AIC_IDCR (AT91_CAST(AT91_REG *) 0x00000124) // (AIC_IDCR) Interrupt Disable Command Register
+#define AIC_ICCR (AT91_CAST(AT91_REG *) 0x00000128) // (AIC_ICCR) Interrupt Clear Command Register
+#define AIC_ISCR (AT91_CAST(AT91_REG *) 0x0000012C) // (AIC_ISCR) Interrupt Set Command Register
+#define AIC_EOICR (AT91_CAST(AT91_REG *) 0x00000130) // (AIC_EOICR) End of Interrupt Command Register
+#define AIC_SPU (AT91_CAST(AT91_REG *) 0x00000134) // (AIC_SPU) Spurious Vector Register
+#define AIC_DCR (AT91_CAST(AT91_REG *) 0x00000138) // (AIC_DCR) Debug Control Register (Protect)
+#define AIC_FFER (AT91_CAST(AT91_REG *) 0x00000140) // (AIC_FFER) Fast Forcing Enable Register
+#define AIC_FFDR (AT91_CAST(AT91_REG *) 0x00000144) // (AIC_FFDR) Fast Forcing Disable Register
+#define AIC_FFSR (AT91_CAST(AT91_REG *) 0x00000148) // (AIC_FFSR) Fast Forcing Status Register
+
+#endif
+// -------- AIC_SMR : (AIC Offset: 0x0) Control Register --------
+#define AT91C_AIC_PRIOR (0x7 << 0) // (AIC) Priority Level
+#define AT91C_AIC_PRIOR_LOWEST (0x0) // (AIC) Lowest priority level
+#define AT91C_AIC_PRIOR_HIGHEST (0x7) // (AIC) Highest priority level
+#define AT91C_AIC_SRCTYPE (0x3 << 5) // (AIC) Interrupt Source Type
+#define AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL (0x0 << 5) // (AIC) Internal Sources Code Label High-level Sensitive
+#define AT91C_AIC_SRCTYPE_EXT_LOW_LEVEL (0x0 << 5) // (AIC) External Sources Code Label Low-level Sensitive
+#define AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE (0x1 << 5) // (AIC) Internal Sources Code Label Positive Edge triggered
+#define AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE (0x1 << 5) // (AIC) External Sources Code Label Negative Edge triggered
+#define AT91C_AIC_SRCTYPE_HIGH_LEVEL (0x2 << 5) // (AIC) Internal Or External Sources Code Label High-level Sensitive
+#define AT91C_AIC_SRCTYPE_POSITIVE_EDGE (0x3 << 5) // (AIC) Internal Or External Sources Code Label Positive Edge triggered
+// -------- AIC_CISR : (AIC Offset: 0x114) AIC Core Interrupt Status Register --------
+#define AT91C_AIC_NFIQ (0x1 << 0) // (AIC) NFIQ Status
+#define AT91C_AIC_NIRQ (0x1 << 1) // (AIC) NIRQ Status
+// -------- AIC_DCR : (AIC Offset: 0x138) AIC Debug Control Register (Protect) --------
+#define AT91C_AIC_DCR_PROT (0x1 << 0) // (AIC) Protection Mode
+#define AT91C_AIC_DCR_GMSK (0x1 << 1) // (AIC) General Mask
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Peripheral DMA Controller
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_PDC {
+ AT91_REG PDC_RPR; // Receive Pointer Register
+ AT91_REG PDC_RCR; // Receive Counter Register
+ AT91_REG PDC_TPR; // Transmit Pointer Register
+ AT91_REG PDC_TCR; // Transmit Counter Register
+ AT91_REG PDC_RNPR; // Receive Next Pointer Register
+ AT91_REG PDC_RNCR; // Receive Next Counter Register
+ AT91_REG PDC_TNPR; // Transmit Next Pointer Register
+ AT91_REG PDC_TNCR; // Transmit Next Counter Register
+ AT91_REG PDC_PTCR; // PDC Transfer Control Register
+ AT91_REG PDC_PTSR; // PDC Transfer Status Register
+} AT91S_PDC, *AT91PS_PDC;
+#else
+#define PDC_RPR (AT91_CAST(AT91_REG *) 0x00000000) // (PDC_RPR) Receive Pointer Register
+#define PDC_RCR (AT91_CAST(AT91_REG *) 0x00000004) // (PDC_RCR) Receive Counter Register
+#define PDC_TPR (AT91_CAST(AT91_REG *) 0x00000008) // (PDC_TPR) Transmit Pointer Register
+#define PDC_TCR (AT91_CAST(AT91_REG *) 0x0000000C) // (PDC_TCR) Transmit Counter Register
+#define PDC_RNPR (AT91_CAST(AT91_REG *) 0x00000010) // (PDC_RNPR) Receive Next Pointer Register
+#define PDC_RNCR (AT91_CAST(AT91_REG *) 0x00000014) // (PDC_RNCR) Receive Next Counter Register
+#define PDC_TNPR (AT91_CAST(AT91_REG *) 0x00000018) // (PDC_TNPR) Transmit Next Pointer Register
+#define PDC_TNCR (AT91_CAST(AT91_REG *) 0x0000001C) // (PDC_TNCR) Transmit Next Counter Register
+#define PDC_PTCR (AT91_CAST(AT91_REG *) 0x00000020) // (PDC_PTCR) PDC Transfer Control Register
+#define PDC_PTSR (AT91_CAST(AT91_REG *) 0x00000024) // (PDC_PTSR) PDC Transfer Status Register
+
+#endif
+// -------- PDC_PTCR : (PDC Offset: 0x20) PDC Transfer Control Register --------
+#define AT91C_PDC_RXTEN (0x1 << 0) // (PDC) Receiver Transfer Enable
+#define AT91C_PDC_RXTDIS (0x1 << 1) // (PDC) Receiver Transfer Disable
+#define AT91C_PDC_TXTEN (0x1 << 8) // (PDC) Transmitter Transfer Enable
+#define AT91C_PDC_TXTDIS (0x1 << 9) // (PDC) Transmitter Transfer Disable
+// -------- PDC_PTSR : (PDC Offset: 0x24) PDC Transfer Status Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Debug Unit
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_DBGU {
+ AT91_REG DBGU_CR; // Control Register
+ AT91_REG DBGU_MR; // Mode Register
+ AT91_REG DBGU_IER; // Interrupt Enable Register
+ AT91_REG DBGU_IDR; // Interrupt Disable Register
+ AT91_REG DBGU_IMR; // Interrupt Mask Register
+ AT91_REG DBGU_CSR; // Channel Status Register
+ AT91_REG DBGU_RHR; // Receiver Holding Register
+ AT91_REG DBGU_THR; // Transmitter Holding Register
+ AT91_REG DBGU_BRGR; // Baud Rate Generator Register
+ AT91_REG Reserved0[7]; //
+ AT91_REG DBGU_CIDR; // Chip ID Register
+ AT91_REG DBGU_EXID; // Chip ID Extension Register
+ AT91_REG DBGU_FNTR; // Force NTRST Register
+ AT91_REG Reserved1[45]; //
+ AT91_REG DBGU_RPR; // Receive Pointer Register
+ AT91_REG DBGU_RCR; // Receive Counter Register
+ AT91_REG DBGU_TPR; // Transmit Pointer Register
+ AT91_REG DBGU_TCR; // Transmit Counter Register
+ AT91_REG DBGU_RNPR; // Receive Next Pointer Register
+ AT91_REG DBGU_RNCR; // Receive Next Counter Register
+ AT91_REG DBGU_TNPR; // Transmit Next Pointer Register
+ AT91_REG DBGU_TNCR; // Transmit Next Counter Register
+ AT91_REG DBGU_PTCR; // PDC Transfer Control Register
+ AT91_REG DBGU_PTSR; // PDC Transfer Status Register
+} AT91S_DBGU, *AT91PS_DBGU;
+#else
+#define DBGU_CR (AT91_CAST(AT91_REG *) 0x00000000) // (DBGU_CR) Control Register
+#define DBGU_MR (AT91_CAST(AT91_REG *) 0x00000004) // (DBGU_MR) Mode Register
+#define DBGU_IER (AT91_CAST(AT91_REG *) 0x00000008) // (DBGU_IER) Interrupt Enable Register
+#define DBGU_IDR (AT91_CAST(AT91_REG *) 0x0000000C) // (DBGU_IDR) Interrupt Disable Register
+#define DBGU_IMR (AT91_CAST(AT91_REG *) 0x00000010) // (DBGU_IMR) Interrupt Mask Register
+#define DBGU_CSR (AT91_CAST(AT91_REG *) 0x00000014) // (DBGU_CSR) Channel Status Register
+#define DBGU_RHR (AT91_CAST(AT91_REG *) 0x00000018) // (DBGU_RHR) Receiver Holding Register
+#define DBGU_THR (AT91_CAST(AT91_REG *) 0x0000001C) // (DBGU_THR) Transmitter Holding Register
+#define DBGU_BRGR (AT91_CAST(AT91_REG *) 0x00000020) // (DBGU_BRGR) Baud Rate Generator Register
+//#define DBGU_CIDR (AT91_CAST(AT91_REG *) 0x00000040) // (DBGU_CIDR) Chip ID Register
+#define DBGU_EXID (AT91_CAST(AT91_REG *) 0x00000044) // (DBGU_EXID) Chip ID Extension Register
+#define DBGU_FNTR (AT91_CAST(AT91_REG *) 0x00000048) // (DBGU_FNTR) Force NTRST Register
+
+#endif
+// -------- DBGU_CR : (DBGU Offset: 0x0) Debug Unit Control Register --------
+#define AT91C_US_RSTRX (0x1 << 2) // (DBGU) Reset Receiver
+#define AT91C_US_RSTTX (0x1 << 3) // (DBGU) Reset Transmitter
+#define AT91C_US_RXEN (0x1 << 4) // (DBGU) Receiver Enable
+#define AT91C_US_RXDIS (0x1 << 5) // (DBGU) Receiver Disable
+#define AT91C_US_TXEN (0x1 << 6) // (DBGU) Transmitter Enable
+#define AT91C_US_TXDIS (0x1 << 7) // (DBGU) Transmitter Disable
+#define AT91C_US_RSTSTA (0x1 << 8) // (DBGU) Reset Status Bits
+// -------- DBGU_MR : (DBGU Offset: 0x4) Debug Unit Mode Register --------
+#define AT91C_US_PAR (0x7 << 9) // (DBGU) Parity type
+#define AT91C_US_PAR_EVEN (0x0 << 9) // (DBGU) Even Parity
+#define AT91C_US_PAR_ODD (0x1 << 9) // (DBGU) Odd Parity
+#define AT91C_US_PAR_SPACE (0x2 << 9) // (DBGU) Parity forced to 0 (Space)
+#define AT91C_US_PAR_MARK (0x3 << 9) // (DBGU) Parity forced to 1 (Mark)
+#define AT91C_US_PAR_NONE (0x4 << 9) // (DBGU) No Parity
+#define AT91C_US_PAR_MULTI_DROP (0x6 << 9) // (DBGU) Multi-drop mode
+#define AT91C_US_CHMODE (0x3 << 14) // (DBGU) Channel Mode
+#define AT91C_US_CHMODE_NORMAL (0x0 << 14) // (DBGU) Normal Mode: The USART channel operates as an RX/TX USART.
+#define AT91C_US_CHMODE_AUTO (0x1 << 14) // (DBGU) Automatic Echo: Receiver Data Input is connected to the TXD pin.
+#define AT91C_US_CHMODE_LOCAL (0x2 << 14) // (DBGU) Local Loopback: Transmitter Output Signal is connected to Receiver Input Signal.
+#define AT91C_US_CHMODE_REMOTE (0x3 << 14) // (DBGU) Remote Loopback: RXD pin is internally connected to TXD pin.
+// -------- DBGU_IER : (DBGU Offset: 0x8) Debug Unit Interrupt Enable Register --------
+#define AT91C_US_RXRDY (0x1 << 0) // (DBGU) RXRDY Interrupt
+#define AT91C_US_TXRDY (0x1 << 1) // (DBGU) TXRDY Interrupt
+#define AT91C_US_ENDRX (0x1 << 3) // (DBGU) End of Receive Transfer Interrupt
+#define AT91C_US_ENDTX (0x1 << 4) // (DBGU) End of Transmit Interrupt
+#define AT91C_US_OVRE (0x1 << 5) // (DBGU) Overrun Interrupt
+#define AT91C_US_FRAME (0x1 << 6) // (DBGU) Framing Error Interrupt
+#define AT91C_US_PARE (0x1 << 7) // (DBGU) Parity Error Interrupt
+#define AT91C_US_TXEMPTY (0x1 << 9) // (DBGU) TXEMPTY Interrupt
+#define AT91C_US_TXBUFE (0x1 << 11) // (DBGU) TXBUFE Interrupt
+#define AT91C_US_RXBUFF (0x1 << 12) // (DBGU) RXBUFF Interrupt
+#define AT91C_US_COMM_TX (0x1 << 30) // (DBGU) COMM_TX Interrupt
+#define AT91C_US_COMM_RX (0x1 << 31) // (DBGU) COMM_RX Interrupt
+// -------- DBGU_IDR : (DBGU Offset: 0xc) Debug Unit Interrupt Disable Register --------
+// -------- DBGU_IMR : (DBGU Offset: 0x10) Debug Unit Interrupt Mask Register --------
+// -------- DBGU_CSR : (DBGU Offset: 0x14) Debug Unit Channel Status Register --------
+// -------- DBGU_FNTR : (DBGU Offset: 0x48) Debug Unit FORCE_NTRST Register --------
+#define AT91C_US_FORCE_NTRST (0x1 << 0) // (DBGU) Force NTRST in JTAG
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Parallel Input Output Controler
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_PIO {
+ AT91_REG PIO_PER; // PIO Enable Register
+ AT91_REG PIO_PDR; // PIO Disable Register
+ AT91_REG PIO_PSR; // PIO Status Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG PIO_OER; // Output Enable Register
+ AT91_REG PIO_ODR; // Output Disable Registerr
+ AT91_REG PIO_OSR; // Output Status Register
+ AT91_REG Reserved1[1]; //
+ AT91_REG PIO_IFER; // Input Filter Enable Register
+ AT91_REG PIO_IFDR; // Input Filter Disable Register
+ AT91_REG PIO_IFSR; // Input Filter Status Register
+ AT91_REG Reserved2[1]; //
+ AT91_REG PIO_SODR; // Set Output Data Register
+ AT91_REG PIO_CODR; // Clear Output Data Register
+ AT91_REG PIO_ODSR; // Output Data Status Register
+ AT91_REG PIO_PDSR; // Pin Data Status Register
+ AT91_REG PIO_IER; // Interrupt Enable Register
+ AT91_REG PIO_IDR; // Interrupt Disable Register
+ AT91_REG PIO_IMR; // Interrupt Mask Register
+ AT91_REG PIO_ISR; // Interrupt Status Register
+ AT91_REG PIO_MDER; // Multi-driver Enable Register
+ AT91_REG PIO_MDDR; // Multi-driver Disable Register
+ AT91_REG PIO_MDSR; // Multi-driver Status Register
+ AT91_REG Reserved3[1]; //
+ AT91_REG PIO_PPUDR; // Pull-up Disable Register
+ AT91_REG PIO_PPUER; // Pull-up Enable Register
+ AT91_REG PIO_PPUSR; // Pull-up Status Register
+ AT91_REG Reserved4[1]; //
+ AT91_REG PIO_ASR; // Select A Register
+ AT91_REG PIO_BSR; // Select B Register
+ AT91_REG PIO_ABSR; // AB Select Status Register
+ AT91_REG Reserved5[9]; //
+ AT91_REG PIO_OWER; // Output Write Enable Register
+ AT91_REG PIO_OWDR; // Output Write Disable Register
+ AT91_REG PIO_OWSR; // Output Write Status Register
+} AT91S_PIO, *AT91PS_PIO;
+#else
+#define PIO_PER (AT91_CAST(AT91_REG *) 0x00000000) // (PIO_PER) PIO Enable Register
+#define PIO_PDR (AT91_CAST(AT91_REG *) 0x00000004) // (PIO_PDR) PIO Disable Register
+#define PIO_PSR (AT91_CAST(AT91_REG *) 0x00000008) // (PIO_PSR) PIO Status Register
+#define PIO_OER (AT91_CAST(AT91_REG *) 0x00000010) // (PIO_OER) Output Enable Register
+#define PIO_ODR (AT91_CAST(AT91_REG *) 0x00000014) // (PIO_ODR) Output Disable Register
+#define PIO_OSR (AT91_CAST(AT91_REG *) 0x00000018) // (PIO_OSR) Output Status Register
+#define PIO_IFER (AT91_CAST(AT91_REG *) 0x00000020) // (PIO_IFER) Input Filter Enable Register
+#define PIO_IFDR (AT91_CAST(AT91_REG *) 0x00000024) // (PIO_IFDR) Input Filter Disable Register
+#define PIO_IFSR (AT91_CAST(AT91_REG *) 0x00000028) // (PIO_IFSR) Input Filter Status Register
+#define PIO_SODR (AT91_CAST(AT91_REG *) 0x00000030) // (PIO_SODR) Set Output Data Register
+#define PIO_CODR (AT91_CAST(AT91_REG *) 0x00000034) // (PIO_CODR) Clear Output Data Register
+#define PIO_ODSR (AT91_CAST(AT91_REG *) 0x00000038) // (PIO_ODSR) Output Data Status Register
+#define PIO_PDSR (AT91_CAST(AT91_REG *) 0x0000003C) // (PIO_PDSR) Pin Data Status Register
+#define PIO_IER (AT91_CAST(AT91_REG *) 0x00000040) // (PIO_IER) Interrupt Enable Register
+#define PIO_IDR (AT91_CAST(AT91_REG *) 0x00000044) // (PIO_IDR) Interrupt Disable Register
+#define PIO_IMR (AT91_CAST(AT91_REG *) 0x00000048) // (PIO_IMR) Interrupt Mask Register
+#define PIO_ISR (AT91_CAST(AT91_REG *) 0x0000004C) // (PIO_ISR) Interrupt Status Register
+#define PIO_MDER (AT91_CAST(AT91_REG *) 0x00000050) // (PIO_MDER) Multi-driver Enable Register
+#define PIO_MDDR (AT91_CAST(AT91_REG *) 0x00000054) // (PIO_MDDR) Multi-driver Disable Register
+#define PIO_MDSR (AT91_CAST(AT91_REG *) 0x00000058) // (PIO_MDSR) Multi-driver Status Register
+#define PIO_PPUDR (AT91_CAST(AT91_REG *) 0x00000060) // (PIO_PPUDR) Pull-up Disable Register
+#define PIO_PPUER (AT91_CAST(AT91_REG *) 0x00000064) // (PIO_PPUER) Pull-up Enable Register
+#define PIO_PPUSR (AT91_CAST(AT91_REG *) 0x00000068) // (PIO_PPUSR) Pull-up Status Register
+#define PIO_ASR (AT91_CAST(AT91_REG *) 0x00000070) // (PIO_ASR) Select A Register
+#define PIO_BSR (AT91_CAST(AT91_REG *) 0x00000074) // (PIO_BSR) Select B Register
+#define PIO_ABSR (AT91_CAST(AT91_REG *) 0x00000078) // (PIO_ABSR) AB Select Status Register
+#define PIO_OWER (AT91_CAST(AT91_REG *) 0x000000A0) // (PIO_OWER) Output Write Enable Register
+#define PIO_OWDR (AT91_CAST(AT91_REG *) 0x000000A4) // (PIO_OWDR) Output Write Disable Register
+#define PIO_OWSR (AT91_CAST(AT91_REG *) 0x000000A8) // (PIO_OWSR) Output Write Status Register
+
+#endif
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Clock Generator Controler
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_CKGR {
+ AT91_REG CKGR_MOR; // Main Oscillator Register
+ AT91_REG CKGR_MCFR; // Main Clock Frequency Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG CKGR_PLLR; // PLL Register
+} AT91S_CKGR, *AT91PS_CKGR;
+#else
+#define CKGR_MOR (AT91_CAST(AT91_REG *) 0x00000000) // (CKGR_MOR) Main Oscillator Register
+#define CKGR_MCFR (AT91_CAST(AT91_REG *) 0x00000004) // (CKGR_MCFR) Main Clock Frequency Register
+#define CKGR_PLLR (AT91_CAST(AT91_REG *) 0x0000000C) // (CKGR_PLLR) PLL Register
+
+#endif
+// -------- CKGR_MOR : (CKGR Offset: 0x0) Main Oscillator Register --------
+#define AT91C_CKGR_MOSCEN (0x1 << 0) // (CKGR) Main Oscillator Enable
+#define AT91C_CKGR_OSCBYPASS (0x1 << 1) // (CKGR) Main Oscillator Bypass
+#define AT91C_CKGR_OSCOUNT (0xFF << 8) // (CKGR) Main Oscillator Start-up Time
+// -------- CKGR_MCFR : (CKGR Offset: 0x4) Main Clock Frequency Register --------
+#define AT91C_CKGR_MAINF (0xFFFF << 0) // (CKGR) Main Clock Frequency
+#define AT91C_CKGR_MAINRDY (0x1 << 16) // (CKGR) Main Clock Ready
+// -------- CKGR_PLLR : (CKGR Offset: 0xc) PLL B Register --------
+#define AT91C_CKGR_DIV (0xFF << 0) // (CKGR) Divider Selected
+#define AT91C_CKGR_DIV_0 (0x0) // (CKGR) Divider output is 0
+#define AT91C_CKGR_DIV_BYPASS (0x1) // (CKGR) Divider is bypassed
+#define AT91C_CKGR_PLLCOUNT (0x3F << 8) // (CKGR) PLL Counter
+#define AT91C_CKGR_OUT (0x3 << 14) // (CKGR) PLL Output Frequency Range
+#define AT91C_CKGR_OUT_0 (0x0 << 14) // (CKGR) Please refer to the PLL datasheet
+#define AT91C_CKGR_OUT_1 (0x1 << 14) // (CKGR) Please refer to the PLL datasheet
+#define AT91C_CKGR_OUT_2 (0x2 << 14) // (CKGR) Please refer to the PLL datasheet
+#define AT91C_CKGR_OUT_3 (0x3 << 14) // (CKGR) Please refer to the PLL datasheet
+#define AT91C_CKGR_MUL (0x7FF << 16) // (CKGR) PLL Multiplier
+#define AT91C_CKGR_USBDIV (0x3 << 28) // (CKGR) Divider for USB Clocks
+#define AT91C_CKGR_USBDIV_0 (0x0 << 28) // (CKGR) Divider output is PLL clock output
+#define AT91C_CKGR_USBDIV_1 (0x1 << 28) // (CKGR) Divider output is PLL clock output divided by 2
+#define AT91C_CKGR_USBDIV_2 (0x2 << 28) // (CKGR) Divider output is PLL clock output divided by 4
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Power Management Controler
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_PMC {
+ AT91_REG PMC_SCER; // System Clock Enable Register
+ AT91_REG PMC_SCDR; // System Clock Disable Register
+ AT91_REG PMC_SCSR; // System Clock Status Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG PMC_PCER; // Peripheral Clock Enable Register
+ AT91_REG PMC_PCDR; // Peripheral Clock Disable Register
+ AT91_REG PMC_PCSR; // Peripheral Clock Status Register
+ AT91_REG Reserved1[1]; //
+ AT91_REG PMC_MOR; // Main Oscillator Register
+ AT91_REG PMC_MCFR; // Main Clock Frequency Register
+ AT91_REG Reserved2[1]; //
+ AT91_REG PMC_PLLR; // PLL Register
+ AT91_REG PMC_MCKR; // Master Clock Register
+ AT91_REG Reserved3[3]; //
+ AT91_REG PMC_PCKR[3]; // Programmable Clock Register
+ AT91_REG Reserved4[5]; //
+ AT91_REG PMC_IER; // Interrupt Enable Register
+ AT91_REG PMC_IDR; // Interrupt Disable Register
+ AT91_REG PMC_SR; // Status Register
+ AT91_REG PMC_IMR; // Interrupt Mask Register
+} AT91S_PMC, *AT91PS_PMC;
+#else
+#define PMC_SCER (AT91_CAST(AT91_REG *) 0x00000000) // (PMC_SCER) System Clock Enable Register
+#define PMC_SCDR (AT91_CAST(AT91_REG *) 0x00000004) // (PMC_SCDR) System Clock Disable Register
+#define PMC_SCSR (AT91_CAST(AT91_REG *) 0x00000008) // (PMC_SCSR) System Clock Status Register
+#define PMC_PCER (AT91_CAST(AT91_REG *) 0x00000010) // (PMC_PCER) Peripheral Clock Enable Register
+#define PMC_PCDR (AT91_CAST(AT91_REG *) 0x00000014) // (PMC_PCDR) Peripheral Clock Disable Register
+#define PMC_PCSR (AT91_CAST(AT91_REG *) 0x00000018) // (PMC_PCSR) Peripheral Clock Status Register
+#define PMC_MCKR (AT91_CAST(AT91_REG *) 0x00000030) // (PMC_MCKR) Master Clock Register
+#define PMC_PCKR (AT91_CAST(AT91_REG *) 0x00000040) // (PMC_PCKR) Programmable Clock Register
+#define PMC_IER (AT91_CAST(AT91_REG *) 0x00000060) // (PMC_IER) Interrupt Enable Register
+#define PMC_IDR (AT91_CAST(AT91_REG *) 0x00000064) // (PMC_IDR) Interrupt Disable Register
+#define PMC_SR (AT91_CAST(AT91_REG *) 0x00000068) // (PMC_SR) Status Register
+#define PMC_IMR (AT91_CAST(AT91_REG *) 0x0000006C) // (PMC_IMR) Interrupt Mask Register
+
+#endif
+// -------- PMC_SCER : (PMC Offset: 0x0) System Clock Enable Register --------
+#define AT91C_PMC_PCK (0x1 << 0) // (PMC) Processor Clock
+#define AT91C_PMC_UDP (0x1 << 7) // (PMC) USB Device Port Clock
+#define AT91C_PMC_PCK0 (0x1 << 8) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK1 (0x1 << 9) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK2 (0x1 << 10) // (PMC) Programmable Clock Output
+// -------- PMC_SCDR : (PMC Offset: 0x4) System Clock Disable Register --------
+// -------- PMC_SCSR : (PMC Offset: 0x8) System Clock Status Register --------
+// -------- CKGR_MOR : (PMC Offset: 0x20) Main Oscillator Register --------
+// -------- CKGR_MCFR : (PMC Offset: 0x24) Main Clock Frequency Register --------
+// -------- CKGR_PLLR : (PMC Offset: 0x2c) PLL B Register --------
+// -------- PMC_MCKR : (PMC Offset: 0x30) Master Clock Register --------
+#define AT91C_PMC_CSS (0x3 << 0) // (PMC) Programmable Clock Selection
+#define AT91C_PMC_CSS_SLOW_CLK (0x0) // (PMC) Slow Clock is selected
+#define AT91C_PMC_CSS_MAIN_CLK (0x1) // (PMC) Main Clock is selected
+#define AT91C_PMC_CSS_PLL_CLK (0x3) // (PMC) Clock from PLL is selected
+#define AT91C_PMC_PRES (0x7 << 2) // (PMC) Programmable Clock Prescaler
+#define AT91C_PMC_PRES_CLK (0x0 << 2) // (PMC) Selected clock
+#define AT91C_PMC_PRES_CLK_2 (0x1 << 2) // (PMC) Selected clock divided by 2
+#define AT91C_PMC_PRES_CLK_4 (0x2 << 2) // (PMC) Selected clock divided by 4
+#define AT91C_PMC_PRES_CLK_8 (0x3 << 2) // (PMC) Selected clock divided by 8
+#define AT91C_PMC_PRES_CLK_16 (0x4 << 2) // (PMC) Selected clock divided by 16
+#define AT91C_PMC_PRES_CLK_32 (0x5 << 2) // (PMC) Selected clock divided by 32
+#define AT91C_PMC_PRES_CLK_64 (0x6 << 2) // (PMC) Selected clock divided by 64
+// -------- PMC_PCKR : (PMC Offset: 0x40) Programmable Clock Register --------
+// -------- PMC_IER : (PMC Offset: 0x60) PMC Interrupt Enable Register --------
+#define AT91C_PMC_MOSCS (0x1 << 0) // (PMC) MOSC Status/Enable/Disable/Mask
+#define AT91C_PMC_LOCK (0x1 << 2) // (PMC) PLL Status/Enable/Disable/Mask
+#define AT91C_PMC_MCKRDY (0x1 << 3) // (PMC) MCK_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK0RDY (0x1 << 8) // (PMC) PCK0_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK1RDY (0x1 << 9) // (PMC) PCK1_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK2RDY (0x1 << 10) // (PMC) PCK2_RDY Status/Enable/Disable/Mask
+// -------- PMC_IDR : (PMC Offset: 0x64) PMC Interrupt Disable Register --------
+// -------- PMC_SR : (PMC Offset: 0x68) PMC Status Register --------
+// -------- PMC_IMR : (PMC Offset: 0x6c) PMC Interrupt Mask Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Reset Controller Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_RSTC {
+ AT91_REG RSTC_RCR; // Reset Control Register
+ AT91_REG RSTC_RSR; // Reset Status Register
+ AT91_REG RSTC_RMR; // Reset Mode Register
+} AT91S_RSTC, *AT91PS_RSTC;
+#else
+#define RSTC_RCR (AT91_CAST(AT91_REG *) 0x00000000) // (RSTC_RCR) Reset Control Register
+#define RSTC_RSR (AT91_CAST(AT91_REG *) 0x00000004) // (RSTC_RSR) Reset Status Register
+#define RSTC_RMR (AT91_CAST(AT91_REG *) 0x00000008) // (RSTC_RMR) Reset Mode Register
+
+#endif
+// -------- RSTC_RCR : (RSTC Offset: 0x0) Reset Control Register --------
+#define AT91C_RSTC_PROCRST (0x1 << 0) // (RSTC) Processor Reset
+#define AT91C_RSTC_PERRST (0x1 << 2) // (RSTC) Peripheral Reset
+#define AT91C_RSTC_EXTRST (0x1 << 3) // (RSTC) External Reset
+#define AT91C_RSTC_KEY (0xFF << 24) // (RSTC) Password
+// -------- RSTC_RSR : (RSTC Offset: 0x4) Reset Status Register --------
+#define AT91C_RSTC_URSTS (0x1 << 0) // (RSTC) User Reset Status
+#define AT91C_RSTC_BODSTS (0x1 << 1) // (RSTC) Brownout Detection Status
+#define AT91C_RSTC_RSTTYP (0x7 << 8) // (RSTC) Reset Type
+#define AT91C_RSTC_RSTTYP_POWERUP (0x0 << 8) // (RSTC) Power-up Reset. VDDCORE rising.
+#define AT91C_RSTC_RSTTYP_WAKEUP (0x1 << 8) // (RSTC) WakeUp Reset. VDDCORE rising.
+#define AT91C_RSTC_RSTTYP_WATCHDOG (0x2 << 8) // (RSTC) Watchdog Reset. Watchdog overflow occured.
+#define AT91C_RSTC_RSTTYP_SOFTWARE (0x3 << 8) // (RSTC) Software Reset. Processor reset required by the software.
+#define AT91C_RSTC_RSTTYP_USER (0x4 << 8) // (RSTC) User Reset. NRST pin detected low.
+#define AT91C_RSTC_RSTTYP_BROWNOUT (0x5 << 8) // (RSTC) Brownout Reset occured.
+#define AT91C_RSTC_NRSTL (0x1 << 16) // (RSTC) NRST pin level
+#define AT91C_RSTC_SRCMP (0x1 << 17) // (RSTC) Software Reset Command in Progress.
+// -------- RSTC_RMR : (RSTC Offset: 0x8) Reset Mode Register --------
+#define AT91C_RSTC_URSTEN (0x1 << 0) // (RSTC) User Reset Enable
+#define AT91C_RSTC_URSTIEN (0x1 << 4) // (RSTC) User Reset Interrupt Enable
+#define AT91C_RSTC_ERSTL (0xF << 8) // (RSTC) User Reset Length
+#define AT91C_RSTC_BODIEN (0x1 << 16) // (RSTC) Brownout Detection Interrupt Enable
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Real Time Timer Controller Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_RTTC {
+ AT91_REG RTTC_RTMR; // Real-time Mode Register
+ AT91_REG RTTC_RTAR; // Real-time Alarm Register
+ AT91_REG RTTC_RTVR; // Real-time Value Register
+ AT91_REG RTTC_RTSR; // Real-time Status Register
+} AT91S_RTTC, *AT91PS_RTTC;
+#else
+#define RTTC_RTMR (AT91_CAST(AT91_REG *) 0x00000000) // (RTTC_RTMR) Real-time Mode Register
+#define RTTC_RTAR (AT91_CAST(AT91_REG *) 0x00000004) // (RTTC_RTAR) Real-time Alarm Register
+#define RTTC_RTVR (AT91_CAST(AT91_REG *) 0x00000008) // (RTTC_RTVR) Real-time Value Register
+#define RTTC_RTSR (AT91_CAST(AT91_REG *) 0x0000000C) // (RTTC_RTSR) Real-time Status Register
+
+#endif
+// -------- RTTC_RTMR : (RTTC Offset: 0x0) Real-time Mode Register --------
+#define AT91C_RTTC_RTPRES (0xFFFF << 0) // (RTTC) Real-time Timer Prescaler Value
+#define AT91C_RTTC_ALMIEN (0x1 << 16) // (RTTC) Alarm Interrupt Enable
+#define AT91C_RTTC_RTTINCIEN (0x1 << 17) // (RTTC) Real Time Timer Increment Interrupt Enable
+#define AT91C_RTTC_RTTRST (0x1 << 18) // (RTTC) Real Time Timer Restart
+// -------- RTTC_RTAR : (RTTC Offset: 0x4) Real-time Alarm Register --------
+#define AT91C_RTTC_ALMV (0x0 << 0) // (RTTC) Alarm Value
+// -------- RTTC_RTVR : (RTTC Offset: 0x8) Current Real-time Value Register --------
+#define AT91C_RTTC_CRTV (0x0 << 0) // (RTTC) Current Real-time Value
+// -------- RTTC_RTSR : (RTTC Offset: 0xc) Real-time Status Register --------
+#define AT91C_RTTC_ALMS (0x1 << 0) // (RTTC) Real-time Alarm Status
+#define AT91C_RTTC_RTTINC (0x1 << 1) // (RTTC) Real-time Timer Increment
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Periodic Interval Timer Controller Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_PITC {
+ AT91_REG PITC_PIMR; // Period Interval Mode Register
+ AT91_REG PITC_PISR; // Period Interval Status Register
+ AT91_REG PITC_PIVR; // Period Interval Value Register
+ AT91_REG PITC_PIIR; // Period Interval Image Register
+} AT91S_PITC, *AT91PS_PITC;
+#else
+#define PITC_PIMR (AT91_CAST(AT91_REG *) 0x00000000) // (PITC_PIMR) Period Interval Mode Register
+#define PITC_PISR (AT91_CAST(AT91_REG *) 0x00000004) // (PITC_PISR) Period Interval Status Register
+#define PITC_PIVR (AT91_CAST(AT91_REG *) 0x00000008) // (PITC_PIVR) Period Interval Value Register
+#define PITC_PIIR (AT91_CAST(AT91_REG *) 0x0000000C) // (PITC_PIIR) Period Interval Image Register
+
+#endif
+// -------- PITC_PIMR : (PITC Offset: 0x0) Periodic Interval Mode Register --------
+#define AT91C_PITC_PIV (0xFFFFF << 0) // (PITC) Periodic Interval Value
+#define AT91C_PITC_PITEN (0x1 << 24) // (PITC) Periodic Interval Timer Enabled
+#define AT91C_PITC_PITIEN (0x1 << 25) // (PITC) Periodic Interval Timer Interrupt Enable
+// -------- PITC_PISR : (PITC Offset: 0x4) Periodic Interval Status Register --------
+#define AT91C_PITC_PITS (0x1 << 0) // (PITC) Periodic Interval Timer Status
+// -------- PITC_PIVR : (PITC Offset: 0x8) Periodic Interval Value Register --------
+#define AT91C_PITC_CPIV (0xFFFFF << 0) // (PITC) Current Periodic Interval Value
+#define AT91C_PITC_PICNT (0xFFF << 20) // (PITC) Periodic Interval Counter
+// -------- PITC_PIIR : (PITC Offset: 0xc) Periodic Interval Image Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Watchdog Timer Controller Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_WDTC {
+ AT91_REG WDTC_WDCR; // Watchdog Control Register
+ AT91_REG WDTC_WDMR; // Watchdog Mode Register
+ AT91_REG WDTC_WDSR; // Watchdog Status Register
+} AT91S_WDTC, *AT91PS_WDTC;
+#else
+#define WDTC_WDCR (AT91_CAST(AT91_REG *) 0x00000000) // (WDTC_WDCR) Watchdog Control Register
+#define WDTC_WDMR (AT91_CAST(AT91_REG *) 0x00000004) // (WDTC_WDMR) Watchdog Mode Register
+#define WDTC_WDSR (AT91_CAST(AT91_REG *) 0x00000008) // (WDTC_WDSR) Watchdog Status Register
+
+#endif
+// -------- WDTC_WDCR : (WDTC Offset: 0x0) Periodic Interval Image Register --------
+#define AT91C_WDTC_WDRSTT (0x1 << 0) // (WDTC) Watchdog Restart
+#define AT91C_WDTC_KEY (0xFF << 24) // (WDTC) Watchdog KEY Password
+// -------- WDTC_WDMR : (WDTC Offset: 0x4) Watchdog Mode Register --------
+#define AT91C_WDTC_WDV (0xFFF << 0) // (WDTC) Watchdog Timer Restart
+#define AT91C_WDTC_WDFIEN (0x1 << 12) // (WDTC) Watchdog Fault Interrupt Enable
+#define AT91C_WDTC_WDRSTEN (0x1 << 13) // (WDTC) Watchdog Reset Enable
+#define AT91C_WDTC_WDRPROC (0x1 << 14) // (WDTC) Watchdog Timer Restart
+#define AT91C_WDTC_WDDIS (0x1 << 15) // (WDTC) Watchdog Disable
+#define AT91C_WDTC_WDD (0xFFF << 16) // (WDTC) Watchdog Delta Value
+#define AT91C_WDTC_WDDBGHLT (0x1 << 28) // (WDTC) Watchdog Debug Halt
+#define AT91C_WDTC_WDIDLEHLT (0x1 << 29) // (WDTC) Watchdog Idle Halt
+// -------- WDTC_WDSR : (WDTC Offset: 0x8) Watchdog Status Register --------
+#define AT91C_WDTC_WDUNF (0x1 << 0) // (WDTC) Watchdog Underflow
+#define AT91C_WDTC_WDERR (0x1 << 1) // (WDTC) Watchdog Error
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Voltage Regulator Mode Controller Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_VREG {
+ AT91_REG VREG_MR; // Voltage Regulator Mode Register
+} AT91S_VREG, *AT91PS_VREG;
+#else
+#define VREG_MR (AT91_CAST(AT91_REG *) 0x00000000) // (VREG_MR) Voltage Regulator Mode Register
+
+#endif
+// -------- VREG_MR : (VREG Offset: 0x0) Voltage Regulator Mode Register --------
+#define AT91C_VREG_PSTDBY (0x1 << 0) // (VREG) Voltage Regulator Power Standby Mode
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Embedded Flash Controller Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_EFC {
+ AT91_REG EFC_FMR; // MC Flash Mode Register
+ AT91_REG EFC_FCR; // MC Flash Command Register
+ AT91_REG EFC_FSR; // MC Flash Status Register
+ AT91_REG EFC_VR; // MC Flash Version Register
+} AT91S_EFC, *AT91PS_EFC;
+#else
+#define MC_FMR (AT91_CAST(AT91_REG *) 0x00000000) // (MC_FMR) MC Flash Mode Register
+#define MC_FCR (AT91_CAST(AT91_REG *) 0x00000004) // (MC_FCR) MC Flash Command Register
+#define MC_FSR (AT91_CAST(AT91_REG *) 0x00000008) // (MC_FSR) MC Flash Status Register
+#define MC_VR (AT91_CAST(AT91_REG *) 0x0000000C) // (MC_VR) MC Flash Version Register
+
+#endif
+// -------- MC_FMR : (EFC Offset: 0x0) MC Flash Mode Register --------
+#define AT91C_MC_FRDY (0x1 << 0) // (EFC) Flash Ready
+#define AT91C_MC_LOCKE (0x1 << 2) // (EFC) Lock Error
+#define AT91C_MC_PROGE (0x1 << 3) // (EFC) Programming Error
+#define AT91C_MC_NEBP (0x1 << 7) // (EFC) No Erase Before Programming
+#define AT91C_MC_FWS (0x3 << 8) // (EFC) Flash Wait State
+#define AT91C_MC_FWS_0FWS (0x0 << 8) // (EFC) 1 cycle for Read, 2 for Write operations
+#define AT91C_MC_FWS_1FWS (0x1 << 8) // (EFC) 2 cycles for Read, 3 for Write operations
+#define AT91C_MC_FWS_2FWS (0x2 << 8) // (EFC) 3 cycles for Read, 4 for Write operations
+#define AT91C_MC_FWS_3FWS (0x3 << 8) // (EFC) 4 cycles for Read, 4 for Write operations
+#define AT91C_MC_FMCN (0xFF << 16) // (EFC) Flash Microsecond Cycle Number
+// -------- MC_FCR : (EFC Offset: 0x4) MC Flash Command Register --------
+#define AT91C_MC_FCMD (0xF << 0) // (EFC) Flash Command
+#define AT91C_MC_FCMD_START_PROG (0x1) // (EFC) Starts the programming of th epage specified by PAGEN.
+#define AT91C_MC_FCMD_LOCK (0x2) // (EFC) Starts a lock sequence of the sector defined by the bits 4 to 7 of the field PAGEN.
+#define AT91C_MC_FCMD_PROG_AND_LOCK (0x3) // (EFC) The lock sequence automatically happens after the programming sequence is completed.
+#define AT91C_MC_FCMD_UNLOCK (0x4) // (EFC) Starts an unlock sequence of the sector defined by the bits 4 to 7 of the field PAGEN.
+#define AT91C_MC_FCMD_ERASE_ALL (0x8) // (EFC) Starts the erase of the entire flash.If at least a page is locked, the command is cancelled.
+#define AT91C_MC_FCMD_SET_GP_NVM (0xB) // (EFC) Set General Purpose NVM bits.
+#define AT91C_MC_FCMD_CLR_GP_NVM (0xD) // (EFC) Clear General Purpose NVM bits.
+#define AT91C_MC_FCMD_SET_SECURITY (0xF) // (EFC) Set Security Bit.
+#define AT91C_MC_PAGEN (0x3FF << 8) // (EFC) Page Number
+#define AT91C_MC_KEY (0xFF << 24) // (EFC) Writing Protect Key
+// -------- MC_FSR : (EFC Offset: 0x8) MC Flash Command Register --------
+#define AT91C_MC_SECURITY (0x1 << 4) // (EFC) Security Bit Status
+#define AT91C_MC_GPNVM0 (0x1 << 8) // (EFC) Sector 0 Lock Status
+#define AT91C_MC_GPNVM1 (0x1 << 9) // (EFC) Sector 1 Lock Status
+#define AT91C_MC_GPNVM2 (0x1 << 10) // (EFC) Sector 2 Lock Status
+#define AT91C_MC_GPNVM3 (0x1 << 11) // (EFC) Sector 3 Lock Status
+#define AT91C_MC_GPNVM4 (0x1 << 12) // (EFC) Sector 4 Lock Status
+#define AT91C_MC_GPNVM5 (0x1 << 13) // (EFC) Sector 5 Lock Status
+#define AT91C_MC_GPNVM6 (0x1 << 14) // (EFC) Sector 6 Lock Status
+#define AT91C_MC_GPNVM7 (0x1 << 15) // (EFC) Sector 7 Lock Status
+#define AT91C_MC_LOCKS0 (0x1 << 16) // (EFC) Sector 0 Lock Status
+#define AT91C_MC_LOCKS1 (0x1 << 17) // (EFC) Sector 1 Lock Status
+#define AT91C_MC_LOCKS2 (0x1 << 18) // (EFC) Sector 2 Lock Status
+#define AT91C_MC_LOCKS3 (0x1 << 19) // (EFC) Sector 3 Lock Status
+#define AT91C_MC_LOCKS4 (0x1 << 20) // (EFC) Sector 4 Lock Status
+#define AT91C_MC_LOCKS5 (0x1 << 21) // (EFC) Sector 5 Lock Status
+#define AT91C_MC_LOCKS6 (0x1 << 22) // (EFC) Sector 6 Lock Status
+#define AT91C_MC_LOCKS7 (0x1 << 23) // (EFC) Sector 7 Lock Status
+#define AT91C_MC_LOCKS8 (0x1 << 24) // (EFC) Sector 8 Lock Status
+#define AT91C_MC_LOCKS9 (0x1 << 25) // (EFC) Sector 9 Lock Status
+#define AT91C_MC_LOCKS10 (0x1 << 26) // (EFC) Sector 10 Lock Status
+#define AT91C_MC_LOCKS11 (0x1 << 27) // (EFC) Sector 11 Lock Status
+#define AT91C_MC_LOCKS12 (0x1 << 28) // (EFC) Sector 12 Lock Status
+#define AT91C_MC_LOCKS13 (0x1 << 29) // (EFC) Sector 13 Lock Status
+#define AT91C_MC_LOCKS14 (0x1 << 30) // (EFC) Sector 14 Lock Status
+#define AT91C_MC_LOCKS15 (0x1 << 31) // (EFC) Sector 15 Lock Status
+// -------- EFC_VR : (EFC Offset: 0xc) EFC version register --------
+#define AT91C_EFC_VERSION (0xFFF << 0) // (EFC) EFC version number
+#define AT91C_EFC_MFN (0x7 << 16) // (EFC) EFC MFN
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Memory Controller Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_MC {
+ AT91_REG MC_RCR; // MC Remap Control Register
+ AT91_REG MC_ASR; // MC Abort Status Register
+ AT91_REG MC_AASR; // MC Abort Address Status Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG MC_PUIA[16]; // MC Protection Unit Area
+ AT91_REG MC_PUP; // MC Protection Unit Peripherals
+ AT91_REG MC_PUER; // MC Protection Unit Enable Register
+ AT91_REG Reserved1[2]; //
+ AT91_REG MC0_FMR; // MC Flash Mode Register
+ AT91_REG MC0_FCR; // MC Flash Command Register
+ AT91_REG MC0_FSR; // MC Flash Status Register
+ AT91_REG MC0_VR; // MC Flash Version Register
+ AT91_REG MC1_FMR; // MC Flash Mode Register
+ AT91_REG MC1_FCR; // MC Flash Command Register
+ AT91_REG MC1_FSR; // MC Flash Status Register
+ AT91_REG MC1_VR; // MC Flash Version Register
+} AT91S_MC, *AT91PS_MC;
+#else
+#define MC_RCR (AT91_CAST(AT91_REG *) 0x00000000) // (MC_RCR) MC Remap Control Register
+#define MC_ASR (AT91_CAST(AT91_REG *) 0x00000004) // (MC_ASR) MC Abort Status Register
+#define MC_AASR (AT91_CAST(AT91_REG *) 0x00000008) // (MC_AASR) MC Abort Address Status Register
+#define MC_PUIA (AT91_CAST(AT91_REG *) 0x00000010) // (MC_PUIA) MC Protection Unit Area
+#define MC_PUP (AT91_CAST(AT91_REG *) 0x00000050) // (MC_PUP) MC Protection Unit Peripherals
+#define MC_PUER (AT91_CAST(AT91_REG *) 0x00000054) // (MC_PUER) MC Protection Unit Enable Register
+
+#endif
+// -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register --------
+#define AT91C_MC_RCB (0x1 << 0) // (MC) Remap Command Bit
+// -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register --------
+#define AT91C_MC_UNDADD (0x1 << 0) // (MC) Undefined Addess Abort Status
+#define AT91C_MC_MISADD (0x1 << 1) // (MC) Misaligned Addess Abort Status
+#define AT91C_MC_MPU (0x1 << 2) // (MC) Memory protection Unit Abort Status
+#define AT91C_MC_ABTSZ (0x3 << 8) // (MC) Abort Size Status
+#define AT91C_MC_ABTSZ_BYTE (0x0 << 8) // (MC) Byte
+#define AT91C_MC_ABTSZ_HWORD (0x1 << 8) // (MC) Half-word
+#define AT91C_MC_ABTSZ_WORD (0x2 << 8) // (MC) Word
+#define AT91C_MC_ABTTYP (0x3 << 10) // (MC) Abort Type Status
+#define AT91C_MC_ABTTYP_DATAR (0x0 << 10) // (MC) Data Read
+#define AT91C_MC_ABTTYP_DATAW (0x1 << 10) // (MC) Data Write
+#define AT91C_MC_ABTTYP_FETCH (0x2 << 10) // (MC) Code Fetch
+#define AT91C_MC_MST0 (0x1 << 16) // (MC) Master 0 Abort Source
+#define AT91C_MC_MST1 (0x1 << 17) // (MC) Master 1 Abort Source
+#define AT91C_MC_SVMST0 (0x1 << 24) // (MC) Saved Master 0 Abort Source
+#define AT91C_MC_SVMST1 (0x1 << 25) // (MC) Saved Master 1 Abort Source
+// -------- MC_PUIA : (MC Offset: 0x10) MC Protection Unit Area --------
+#define AT91C_MC_PROT (0x3 << 0) // (MC) Protection
+#define AT91C_MC_PROT_PNAUNA (0x0) // (MC) Privilege: No Access, User: No Access
+#define AT91C_MC_PROT_PRWUNA (0x1) // (MC) Privilege: Read/Write, User: No Access
+#define AT91C_MC_PROT_PRWURO (0x2) // (MC) Privilege: Read/Write, User: Read Only
+#define AT91C_MC_PROT_PRWURW (0x3) // (MC) Privilege: Read/Write, User: Read/Write
+#define AT91C_MC_SIZE (0xF << 4) // (MC) Internal Area Size
+#define AT91C_MC_SIZE_1KB (0x0 << 4) // (MC) Area size 1KByte
+#define AT91C_MC_SIZE_2KB (0x1 << 4) // (MC) Area size 2KByte
+#define AT91C_MC_SIZE_4KB (0x2 << 4) // (MC) Area size 4KByte
+#define AT91C_MC_SIZE_8KB (0x3 << 4) // (MC) Area size 8KByte
+#define AT91C_MC_SIZE_16KB (0x4 << 4) // (MC) Area size 16KByte
+#define AT91C_MC_SIZE_32KB (0x5 << 4) // (MC) Area size 32KByte
+#define AT91C_MC_SIZE_64KB (0x6 << 4) // (MC) Area size 64KByte
+#define AT91C_MC_SIZE_128KB (0x7 << 4) // (MC) Area size 128KByte
+#define AT91C_MC_SIZE_256KB (0x8 << 4) // (MC) Area size 256KByte
+#define AT91C_MC_SIZE_512KB (0x9 << 4) // (MC) Area size 512KByte
+#define AT91C_MC_SIZE_1MB (0xA << 4) // (MC) Area size 1MByte
+#define AT91C_MC_SIZE_2MB (0xB << 4) // (MC) Area size 2MByte
+#define AT91C_MC_SIZE_4MB (0xC << 4) // (MC) Area size 4MByte
+#define AT91C_MC_SIZE_8MB (0xD << 4) // (MC) Area size 8MByte
+#define AT91C_MC_SIZE_16MB (0xE << 4) // (MC) Area size 16MByte
+#define AT91C_MC_SIZE_64MB (0xF << 4) // (MC) Area size 64MByte
+#define AT91C_MC_BA (0x3FFFF << 10) // (MC) Internal Area Base Address
+// -------- MC_PUP : (MC Offset: 0x50) MC Protection Unit Peripheral --------
+// -------- MC_PUER : (MC Offset: 0x54) MC Protection Unit Area --------
+#define AT91C_MC_PUEB (0x1 << 0) // (MC) Protection Unit enable Bit
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Serial Parallel Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_SPI {
+ AT91_REG SPI_CR; // Control Register
+ AT91_REG SPI_MR; // Mode Register
+ AT91_REG SPI_RDR; // Receive Data Register
+ AT91_REG SPI_TDR; // Transmit Data Register
+ AT91_REG SPI_SR; // Status Register
+ AT91_REG SPI_IER; // Interrupt Enable Register
+ AT91_REG SPI_IDR; // Interrupt Disable Register
+ AT91_REG SPI_IMR; // Interrupt Mask Register
+ AT91_REG Reserved0[4]; //
+ AT91_REG SPI_CSR[4]; // Chip Select Register
+ AT91_REG Reserved1[48]; //
+ AT91_REG SPI_RPR; // Receive Pointer Register
+ AT91_REG SPI_RCR; // Receive Counter Register
+ AT91_REG SPI_TPR; // Transmit Pointer Register
+ AT91_REG SPI_TCR; // Transmit Counter Register
+ AT91_REG SPI_RNPR; // Receive Next Pointer Register
+ AT91_REG SPI_RNCR; // Receive Next Counter Register
+ AT91_REG SPI_TNPR; // Transmit Next Pointer Register
+ AT91_REG SPI_TNCR; // Transmit Next Counter Register
+ AT91_REG SPI_PTCR; // PDC Transfer Control Register
+ AT91_REG SPI_PTSR; // PDC Transfer Status Register
+} AT91S_SPI, *AT91PS_SPI;
+#else
+#define SPI_CR (AT91_CAST(AT91_REG *) 0x00000000) // (SPI_CR) Control Register
+#define SPI_MR (AT91_CAST(AT91_REG *) 0x00000004) // (SPI_MR) Mode Register
+#define SPI_RDR (AT91_CAST(AT91_REG *) 0x00000008) // (SPI_RDR) Receive Data Register
+#define SPI_TDR (AT91_CAST(AT91_REG *) 0x0000000C) // (SPI_TDR) Transmit Data Register
+#define SPI_SR (AT91_CAST(AT91_REG *) 0x00000010) // (SPI_SR) Status Register
+#define SPI_IER (AT91_CAST(AT91_REG *) 0x00000014) // (SPI_IER) Interrupt Enable Register
+#define SPI_IDR (AT91_CAST(AT91_REG *) 0x00000018) // (SPI_IDR) Interrupt Disable Register
+#define SPI_IMR (AT91_CAST(AT91_REG *) 0x0000001C) // (SPI_IMR) Interrupt Mask Register
+#define SPI_CSR (AT91_CAST(AT91_REG *) 0x00000030) // (SPI_CSR) Chip Select Register
+
+#endif
+// -------- SPI_CR : (SPI Offset: 0x0) SPI Control Register --------
+#define AT91C_SPI_SPIEN (0x1 << 0) // (SPI) SPI Enable
+#define AT91C_SPI_SPIDIS (0x1 << 1) // (SPI) SPI Disable
+#define AT91C_SPI_SWRST (0x1 << 7) // (SPI) SPI Software reset
+#define AT91C_SPI_LASTXFER (0x1 << 24) // (SPI) SPI Last Transfer
+// -------- SPI_MR : (SPI Offset: 0x4) SPI Mode Register --------
+#define AT91C_SPI_MSTR (0x1 << 0) // (SPI) Master/Slave Mode
+#define AT91C_SPI_PS (0x1 << 1) // (SPI) Peripheral Select
+#define AT91C_SPI_PS_FIXED (0x0 << 1) // (SPI) Fixed Peripheral Select
+#define AT91C_SPI_PS_VARIABLE (0x1 << 1) // (SPI) Variable Peripheral Select
+#define AT91C_SPI_PCSDEC (0x1 << 2) // (SPI) Chip Select Decode
+#define AT91C_SPI_FDIV (0x1 << 3) // (SPI) Clock Selection
+#define AT91C_SPI_MODFDIS (0x1 << 4) // (SPI) Mode Fault Detection
+#define AT91C_SPI_LLB (0x1 << 7) // (SPI) Clock Selection
+#define AT91C_SPI_PCS (0xF << 16) // (SPI) Peripheral Chip Select
+#define AT91C_SPI_DLYBCS (0xFF << 24) // (SPI) Delay Between Chip Selects
+// -------- SPI_RDR : (SPI Offset: 0x8) Receive Data Register --------
+#define AT91C_SPI_RD (0xFFFF << 0) // (SPI) Receive Data
+#define AT91C_SPI_RPCS (0xF << 16) // (SPI) Peripheral Chip Select Status
+// -------- SPI_TDR : (SPI Offset: 0xc) Transmit Data Register --------
+#define AT91C_SPI_TD (0xFFFF << 0) // (SPI) Transmit Data
+#define AT91C_SPI_TPCS (0xF << 16) // (SPI) Peripheral Chip Select Status
+// -------- SPI_SR : (SPI Offset: 0x10) Status Register --------
+#define AT91C_SPI_RDRF (0x1 << 0) // (SPI) Receive Data Register Full
+#define AT91C_SPI_TDRE (0x1 << 1) // (SPI) Transmit Data Register Empty
+#define AT91C_SPI_MODF (0x1 << 2) // (SPI) Mode Fault Error
+#define AT91C_SPI_OVRES (0x1 << 3) // (SPI) Overrun Error Status
+#define AT91C_SPI_ENDRX (0x1 << 4) // (SPI) End of Receiver Transfer
+#define AT91C_SPI_ENDTX (0x1 << 5) // (SPI) End of Receiver Transfer
+#define AT91C_SPI_RXBUFF (0x1 << 6) // (SPI) RXBUFF Interrupt
+#define AT91C_SPI_TXBUFE (0x1 << 7) // (SPI) TXBUFE Interrupt
+#define AT91C_SPI_NSSR (0x1 << 8) // (SPI) NSSR Interrupt
+#define AT91C_SPI_TXEMPTY (0x1 << 9) // (SPI) TXEMPTY Interrupt
+#define AT91C_SPI_SPIENS (0x1 << 16) // (SPI) Enable Status
+// -------- SPI_IER : (SPI Offset: 0x14) Interrupt Enable Register --------
+// -------- SPI_IDR : (SPI Offset: 0x18) Interrupt Disable Register --------
+// -------- SPI_IMR : (SPI Offset: 0x1c) Interrupt Mask Register --------
+// -------- SPI_CSR : (SPI Offset: 0x30) Chip Select Register --------
+#define AT91C_SPI_CPOL (0x1 << 0) // (SPI) Clock Polarity
+#define AT91C_SPI_NCPHA (0x1 << 1) // (SPI) Clock Phase
+#define AT91C_SPI_CSAAT (0x1 << 3) // (SPI) Chip Select Active After Transfer
+#define AT91C_SPI_BITS (0xF << 4) // (SPI) Bits Per Transfer
+#define AT91C_SPI_BITS_8 (0x0 << 4) // (SPI) 8 Bits Per transfer
+#define AT91C_SPI_BITS_9 (0x1 << 4) // (SPI) 9 Bits Per transfer
+#define AT91C_SPI_BITS_10 (0x2 << 4) // (SPI) 10 Bits Per transfer
+#define AT91C_SPI_BITS_11 (0x3 << 4) // (SPI) 11 Bits Per transfer
+#define AT91C_SPI_BITS_12 (0x4 << 4) // (SPI) 12 Bits Per transfer
+#define AT91C_SPI_BITS_13 (0x5 << 4) // (SPI) 13 Bits Per transfer
+#define AT91C_SPI_BITS_14 (0x6 << 4) // (SPI) 14 Bits Per transfer
+#define AT91C_SPI_BITS_15 (0x7 << 4) // (SPI) 15 Bits Per transfer
+#define AT91C_SPI_BITS_16 (0x8 << 4) // (SPI) 16 Bits Per transfer
+#define AT91C_SPI_SCBR (0xFF << 8) // (SPI) Serial Clock Baud Rate
+#define AT91C_SPI_DLYBS (0xFF << 16) // (SPI) Delay Before SPCK
+#define AT91C_SPI_DLYBCT (0xFF << 24) // (SPI) Delay Between Consecutive Transfers
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Analog to Digital Convertor
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_ADC {
+ AT91_REG ADC_CR; // ADC Control Register
+ AT91_REG ADC_MR; // ADC Mode Register
+ AT91_REG Reserved0[2]; //
+ AT91_REG ADC_CHER; // ADC Channel Enable Register
+ AT91_REG ADC_CHDR; // ADC Channel Disable Register
+ AT91_REG ADC_CHSR; // ADC Channel Status Register
+ AT91_REG ADC_SR; // ADC Status Register
+ AT91_REG ADC_LCDR; // ADC Last Converted Data Register
+ AT91_REG ADC_IER; // ADC Interrupt Enable Register
+ AT91_REG ADC_IDR; // ADC Interrupt Disable Register
+ AT91_REG ADC_IMR; // ADC Interrupt Mask Register
+ AT91_REG ADC_CDR[8]; // ADC Channel Data Register
+ AT91_REG Reserved1[44]; //
+ AT91_REG ADC_RPR; // Receive Pointer Register
+ AT91_REG ADC_RCR; // Receive Counter Register
+ AT91_REG ADC_TPR; // Transmit Pointer Register
+ AT91_REG ADC_TCR; // Transmit Counter Register
+ AT91_REG ADC_RNPR; // Receive Next Pointer Register
+ AT91_REG ADC_RNCR; // Receive Next Counter Register
+ AT91_REG ADC_TNPR; // Transmit Next Pointer Register
+ AT91_REG ADC_TNCR; // Transmit Next Counter Register
+ AT91_REG ADC_PTCR; // PDC Transfer Control Register
+ AT91_REG ADC_PTSR; // PDC Transfer Status Register
+} AT91S_ADC, *AT91PS_ADC;
+#else
+#define ADC_CR (AT91_CAST(AT91_REG *) 0x00000000) // (ADC_CR) ADC Control Register
+#define ADC_MR (AT91_CAST(AT91_REG *) 0x00000004) // (ADC_MR) ADC Mode Register
+#define ADC_CHER (AT91_CAST(AT91_REG *) 0x00000010) // (ADC_CHER) ADC Channel Enable Register
+#define ADC_CHDR (AT91_CAST(AT91_REG *) 0x00000014) // (ADC_CHDR) ADC Channel Disable Register
+#define ADC_CHSR (AT91_CAST(AT91_REG *) 0x00000018) // (ADC_CHSR) ADC Channel Status Register
+#define ADC_SR (AT91_CAST(AT91_REG *) 0x0000001C) // (ADC_SR) ADC Status Register
+#define ADC_LCDR (AT91_CAST(AT91_REG *) 0x00000020) // (ADC_LCDR) ADC Last Converted Data Register
+#define ADC_IER (AT91_CAST(AT91_REG *) 0x00000024) // (ADC_IER) ADC Interrupt Enable Register
+#define ADC_IDR (AT91_CAST(AT91_REG *) 0x00000028) // (ADC_IDR) ADC Interrupt Disable Register
+#define ADC_IMR (AT91_CAST(AT91_REG *) 0x0000002C) // (ADC_IMR) ADC Interrupt Mask Register
+#define ADC_CDR0 (AT91_CAST(AT91_REG *) 0x00000030) // (ADC_CDR0) ADC Channel Data Register 0
+#define ADC_CDR1 (AT91_CAST(AT91_REG *) 0x00000034) // (ADC_CDR1) ADC Channel Data Register 1
+#define ADC_CDR2 (AT91_CAST(AT91_REG *) 0x00000038) // (ADC_CDR2) ADC Channel Data Register 2
+#define ADC_CDR3 (AT91_CAST(AT91_REG *) 0x0000003C) // (ADC_CDR3) ADC Channel Data Register 3
+#define ADC_CDR4 (AT91_CAST(AT91_REG *) 0x00000040) // (ADC_CDR4) ADC Channel Data Register 4
+#define ADC_CDR5 (AT91_CAST(AT91_REG *) 0x00000044) // (ADC_CDR5) ADC Channel Data Register 5
+#define ADC_CDR6 (AT91_CAST(AT91_REG *) 0x00000048) // (ADC_CDR6) ADC Channel Data Register 6
+#define ADC_CDR7 (AT91_CAST(AT91_REG *) 0x0000004C) // (ADC_CDR7) ADC Channel Data Register 7
+
+#endif
+// -------- ADC_CR : (ADC Offset: 0x0) ADC Control Register --------
+#define AT91C_ADC_SWRST (0x1 << 0) // (ADC) Software Reset
+#define AT91C_ADC_START (0x1 << 1) // (ADC) Start Conversion
+// -------- ADC_MR : (ADC Offset: 0x4) ADC Mode Register --------
+#define AT91C_ADC_TRGEN (0x1 << 0) // (ADC) Trigger Enable
+#define AT91C_ADC_TRGEN_DIS (0x0) // (ADC) Hradware triggers are disabled. Starting a conversion is only possible by software
+#define AT91C_ADC_TRGEN_EN (0x1) // (ADC) Hardware trigger selected by TRGSEL field is enabled.
+#define AT91C_ADC_TRGSEL (0x7 << 1) // (ADC) Trigger Selection
+#define AT91C_ADC_TRGSEL_TIOA0 (0x0 << 1) // (ADC) Selected TRGSEL = TIAO0
+#define AT91C_ADC_TRGSEL_TIOA1 (0x1 << 1) // (ADC) Selected TRGSEL = TIAO1
+#define AT91C_ADC_TRGSEL_TIOA2 (0x2 << 1) // (ADC) Selected TRGSEL = TIAO2
+#define AT91C_ADC_TRGSEL_TIOA3 (0x3 << 1) // (ADC) Selected TRGSEL = TIAO3
+#define AT91C_ADC_TRGSEL_TIOA4 (0x4 << 1) // (ADC) Selected TRGSEL = TIAO4
+#define AT91C_ADC_TRGSEL_TIOA5 (0x5 << 1) // (ADC) Selected TRGSEL = TIAO5
+#define AT91C_ADC_TRGSEL_EXT (0x6 << 1) // (ADC) Selected TRGSEL = External Trigger
+#define AT91C_ADC_LOWRES (0x1 << 4) // (ADC) Resolution.
+#define AT91C_ADC_LOWRES_10_BIT (0x0 << 4) // (ADC) 10-bit resolution
+#define AT91C_ADC_LOWRES_8_BIT (0x1 << 4) // (ADC) 8-bit resolution
+#define AT91C_ADC_SLEEP (0x1 << 5) // (ADC) Sleep Mode
+#define AT91C_ADC_SLEEP_NORMAL_MODE (0x0 << 5) // (ADC) Normal Mode
+#define AT91C_ADC_SLEEP_MODE (0x1 << 5) // (ADC) Sleep Mode
+#define AT91C_ADC_PRESCAL (0x3F << 8) // (ADC) Prescaler rate selection
+#define AT91C_ADC_STARTUP (0x1F << 16) // (ADC) Startup Time
+#define AT91C_ADC_SHTIM (0xF << 24) // (ADC) Sample & Hold Time
+// -------- ADC_CHER : (ADC Offset: 0x10) ADC Channel Enable Register --------
+#define AT91C_ADC_CH0 (0x1 << 0) // (ADC) Channel 0
+#define AT91C_ADC_CH1 (0x1 << 1) // (ADC) Channel 1
+#define AT91C_ADC_CH2 (0x1 << 2) // (ADC) Channel 2
+#define AT91C_ADC_CH3 (0x1 << 3) // (ADC) Channel 3
+#define AT91C_ADC_CH4 (0x1 << 4) // (ADC) Channel 4
+#define AT91C_ADC_CH5 (0x1 << 5) // (ADC) Channel 5
+#define AT91C_ADC_CH6 (0x1 << 6) // (ADC) Channel 6
+#define AT91C_ADC_CH7 (0x1 << 7) // (ADC) Channel 7
+// -------- ADC_CHDR : (ADC Offset: 0x14) ADC Channel Disable Register --------
+// -------- ADC_CHSR : (ADC Offset: 0x18) ADC Channel Status Register --------
+// -------- ADC_SR : (ADC Offset: 0x1c) ADC Status Register --------
+#define AT91C_ADC_EOC0 (0x1 << 0) // (ADC) End of Conversion
+#define AT91C_ADC_EOC1 (0x1 << 1) // (ADC) End of Conversion
+#define AT91C_ADC_EOC2 (0x1 << 2) // (ADC) End of Conversion
+#define AT91C_ADC_EOC3 (0x1 << 3) // (ADC) End of Conversion
+#define AT91C_ADC_EOC4 (0x1 << 4) // (ADC) End of Conversion
+#define AT91C_ADC_EOC5 (0x1 << 5) // (ADC) End of Conversion
+#define AT91C_ADC_EOC6 (0x1 << 6) // (ADC) End of Conversion
+#define AT91C_ADC_EOC7 (0x1 << 7) // (ADC) End of Conversion
+#define AT91C_ADC_OVRE0 (0x1 << 8) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE1 (0x1 << 9) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE2 (0x1 << 10) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE3 (0x1 << 11) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE4 (0x1 << 12) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE5 (0x1 << 13) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE6 (0x1 << 14) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE7 (0x1 << 15) // (ADC) Overrun Error
+#define AT91C_ADC_DRDY (0x1 << 16) // (ADC) Data Ready
+#define AT91C_ADC_GOVRE (0x1 << 17) // (ADC) General Overrun
+#define AT91C_ADC_ENDRX (0x1 << 18) // (ADC) End of Receiver Transfer
+#define AT91C_ADC_RXBUFF (0x1 << 19) // (ADC) RXBUFF Interrupt
+// -------- ADC_LCDR : (ADC Offset: 0x20) ADC Last Converted Data Register --------
+#define AT91C_ADC_LDATA (0x3FF << 0) // (ADC) Last Data Converted
+// -------- ADC_IER : (ADC Offset: 0x24) ADC Interrupt Enable Register --------
+// -------- ADC_IDR : (ADC Offset: 0x28) ADC Interrupt Disable Register --------
+// -------- ADC_IMR : (ADC Offset: 0x2c) ADC Interrupt Mask Register --------
+// -------- ADC_CDR0 : (ADC Offset: 0x30) ADC Channel Data Register 0 --------
+#define AT91C_ADC_DATA (0x3FF << 0) // (ADC) Converted Data
+// -------- ADC_CDR1 : (ADC Offset: 0x34) ADC Channel Data Register 1 --------
+// -------- ADC_CDR2 : (ADC Offset: 0x38) ADC Channel Data Register 2 --------
+// -------- ADC_CDR3 : (ADC Offset: 0x3c) ADC Channel Data Register 3 --------
+// -------- ADC_CDR4 : (ADC Offset: 0x40) ADC Channel Data Register 4 --------
+// -------- ADC_CDR5 : (ADC Offset: 0x44) ADC Channel Data Register 5 --------
+// -------- ADC_CDR6 : (ADC Offset: 0x48) ADC Channel Data Register 6 --------
+// -------- ADC_CDR7 : (ADC Offset: 0x4c) ADC Channel Data Register 7 --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Synchronous Serial Controller Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_SSC {
+ AT91_REG SSC_CR; // Control Register
+ AT91_REG SSC_CMR; // Clock Mode Register
+ AT91_REG Reserved0[2]; //
+ AT91_REG SSC_RCMR; // Receive Clock ModeRegister
+ AT91_REG SSC_RFMR; // Receive Frame Mode Register
+ AT91_REG SSC_TCMR; // Transmit Clock Mode Register
+ AT91_REG SSC_TFMR; // Transmit Frame Mode Register
+ AT91_REG SSC_RHR; // Receive Holding Register
+ AT91_REG SSC_THR; // Transmit Holding Register
+ AT91_REG Reserved1[2]; //
+ AT91_REG SSC_RSHR; // Receive Sync Holding Register
+ AT91_REG SSC_TSHR; // Transmit Sync Holding Register
+ AT91_REG Reserved2[2]; //
+ AT91_REG SSC_SR; // Status Register
+ AT91_REG SSC_IER; // Interrupt Enable Register
+ AT91_REG SSC_IDR; // Interrupt Disable Register
+ AT91_REG SSC_IMR; // Interrupt Mask Register
+ AT91_REG Reserved3[44]; //
+ AT91_REG SSC_RPR; // Receive Pointer Register
+ AT91_REG SSC_RCR; // Receive Counter Register
+ AT91_REG SSC_TPR; // Transmit Pointer Register
+ AT91_REG SSC_TCR; // Transmit Counter Register
+ AT91_REG SSC_RNPR; // Receive Next Pointer Register
+ AT91_REG SSC_RNCR; // Receive Next Counter Register
+ AT91_REG SSC_TNPR; // Transmit Next Pointer Register
+ AT91_REG SSC_TNCR; // Transmit Next Counter Register
+ AT91_REG SSC_PTCR; // PDC Transfer Control Register
+ AT91_REG SSC_PTSR; // PDC Transfer Status Register
+} AT91S_SSC, *AT91PS_SSC;
+#else
+#define SSC_CR (AT91_CAST(AT91_REG *) 0x00000000) // (SSC_CR) Control Register
+#define SSC_CMR (AT91_CAST(AT91_REG *) 0x00000004) // (SSC_CMR) Clock Mode Register
+#define SSC_RCMR (AT91_CAST(AT91_REG *) 0x00000010) // (SSC_RCMR) Receive Clock ModeRegister
+#define SSC_RFMR (AT91_CAST(AT91_REG *) 0x00000014) // (SSC_RFMR) Receive Frame Mode Register
+#define SSC_TCMR (AT91_CAST(AT91_REG *) 0x00000018) // (SSC_TCMR) Transmit Clock Mode Register
+#define SSC_TFMR (AT91_CAST(AT91_REG *) 0x0000001C) // (SSC_TFMR) Transmit Frame Mode Register
+#define SSC_RHR (AT91_CAST(AT91_REG *) 0x00000020) // (SSC_RHR) Receive Holding Register
+#define SSC_THR (AT91_CAST(AT91_REG *) 0x00000024) // (SSC_THR) Transmit Holding Register
+#define SSC_RSHR (AT91_CAST(AT91_REG *) 0x00000030) // (SSC_RSHR) Receive Sync Holding Register
+#define SSC_TSHR (AT91_CAST(AT91_REG *) 0x00000034) // (SSC_TSHR) Transmit Sync Holding Register
+#define SSC_SR (AT91_CAST(AT91_REG *) 0x00000040) // (SSC_SR) Status Register
+#define SSC_IER (AT91_CAST(AT91_REG *) 0x00000044) // (SSC_IER) Interrupt Enable Register
+#define SSC_IDR (AT91_CAST(AT91_REG *) 0x00000048) // (SSC_IDR) Interrupt Disable Register
+#define SSC_IMR (AT91_CAST(AT91_REG *) 0x0000004C) // (SSC_IMR) Interrupt Mask Register
+
+#endif
+// -------- SSC_CR : (SSC Offset: 0x0) SSC Control Register --------
+#define AT91C_SSC_RXEN (0x1 << 0) // (SSC) Receive Enable
+#define AT91C_SSC_RXDIS (0x1 << 1) // (SSC) Receive Disable
+#define AT91C_SSC_TXEN (0x1 << 8) // (SSC) Transmit Enable
+#define AT91C_SSC_TXDIS (0x1 << 9) // (SSC) Transmit Disable
+#define AT91C_SSC_SWRST (0x1 << 15) // (SSC) Software Reset
+// -------- SSC_RCMR : (SSC Offset: 0x10) SSC Receive Clock Mode Register --------
+#define AT91C_SSC_CKS (0x3 << 0) // (SSC) Receive/Transmit Clock Selection
+#define AT91C_SSC_CKS_DIV (0x0) // (SSC) Divided Clock
+#define AT91C_SSC_CKS_TK (0x1) // (SSC) TK Clock signal
+#define AT91C_SSC_CKS_RK (0x2) // (SSC) RK pin
+#define AT91C_SSC_CKO (0x7 << 2) // (SSC) Receive/Transmit Clock Output Mode Selection
+#define AT91C_SSC_CKO_NONE (0x0 << 2) // (SSC) Receive/Transmit Clock Output Mode: None RK pin: Input-only
+#define AT91C_SSC_CKO_CONTINOUS (0x1 << 2) // (SSC) Continuous Receive/Transmit Clock RK pin: Output
+#define AT91C_SSC_CKO_DATA_TX (0x2 << 2) // (SSC) Receive/Transmit Clock only during data transfers RK pin: Output
+#define AT91C_SSC_CKI (0x1 << 5) // (SSC) Receive/Transmit Clock Inversion
+#define AT91C_SSC_START (0xF << 8) // (SSC) Receive/Transmit Start Selection
+#define AT91C_SSC_START_CONTINOUS (0x0 << 8) // (SSC) Continuous, as soon as the receiver is enabled, and immediately after the end of transfer of the previous data.
+#define AT91C_SSC_START_TX (0x1 << 8) // (SSC) Transmit/Receive start
+#define AT91C_SSC_START_LOW_RF (0x2 << 8) // (SSC) Detection of a low level on RF input
+#define AT91C_SSC_START_HIGH_RF (0x3 << 8) // (SSC) Detection of a high level on RF input
+#define AT91C_SSC_START_FALL_RF (0x4 << 8) // (SSC) Detection of a falling edge on RF input
+#define AT91C_SSC_START_RISE_RF (0x5 << 8) // (SSC) Detection of a rising edge on RF input
+#define AT91C_SSC_START_LEVEL_RF (0x6 << 8) // (SSC) Detection of any level change on RF input
+#define AT91C_SSC_START_EDGE_RF (0x7 << 8) // (SSC) Detection of any edge on RF input
+#define AT91C_SSC_START_0 (0x8 << 8) // (SSC) Compare 0
+#define AT91C_SSC_STTDLY (0xFF << 16) // (SSC) Receive/Transmit Start Delay
+#define AT91C_SSC_PERIOD (0xFF << 24) // (SSC) Receive/Transmit Period Divider Selection
+// -------- SSC_RFMR : (SSC Offset: 0x14) SSC Receive Frame Mode Register --------
+#define AT91C_SSC_DATLEN (0x1F << 0) // (SSC) Data Length
+#define AT91C_SSC_LOOP (0x1 << 5) // (SSC) Loop Mode
+#define AT91C_SSC_MSBF (0x1 << 7) // (SSC) Most Significant Bit First
+#define AT91C_SSC_DATNB (0xF << 8) // (SSC) Data Number per Frame
+#define AT91C_SSC_FSLEN (0xF << 16) // (SSC) Receive/Transmit Frame Sync length
+#define AT91C_SSC_FSOS (0x7 << 20) // (SSC) Receive/Transmit Frame Sync Output Selection
+#define AT91C_SSC_FSOS_NONE (0x0 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: None RK pin Input-only
+#define AT91C_SSC_FSOS_NEGATIVE (0x1 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Negative Pulse
+#define AT91C_SSC_FSOS_POSITIVE (0x2 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Positive Pulse
+#define AT91C_SSC_FSOS_LOW (0x3 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver Low during data transfer
+#define AT91C_SSC_FSOS_HIGH (0x4 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver High during data transfer
+#define AT91C_SSC_FSOS_TOGGLE (0x5 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Toggling at each start of data transfer
+#define AT91C_SSC_FSEDGE (0x1 << 24) // (SSC) Frame Sync Edge Detection
+// -------- SSC_TCMR : (SSC Offset: 0x18) SSC Transmit Clock Mode Register --------
+// -------- SSC_TFMR : (SSC Offset: 0x1c) SSC Transmit Frame Mode Register --------
+#define AT91C_SSC_DATDEF (0x1 << 5) // (SSC) Data Default Value
+#define AT91C_SSC_FSDEN (0x1 << 23) // (SSC) Frame Sync Data Enable
+// -------- SSC_SR : (SSC Offset: 0x40) SSC Status Register --------
+#define AT91C_SSC_TXRDY (0x1 << 0) // (SSC) Transmit Ready
+#define AT91C_SSC_TXEMPTY (0x1 << 1) // (SSC) Transmit Empty
+#define AT91C_SSC_ENDTX (0x1 << 2) // (SSC) End Of Transmission
+#define AT91C_SSC_TXBUFE (0x1 << 3) // (SSC) Transmit Buffer Empty
+#define AT91C_SSC_RXRDY (0x1 << 4) // (SSC) Receive Ready
+#define AT91C_SSC_OVRUN (0x1 << 5) // (SSC) Receive Overrun
+#define AT91C_SSC_ENDRX (0x1 << 6) // (SSC) End of Reception
+#define AT91C_SSC_RXBUFF (0x1 << 7) // (SSC) Receive Buffer Full
+#define AT91C_SSC_TXSYN (0x1 << 10) // (SSC) Transmit Sync
+#define AT91C_SSC_RXSYN (0x1 << 11) // (SSC) Receive Sync
+#define AT91C_SSC_TXENA (0x1 << 16) // (SSC) Transmit Enable
+#define AT91C_SSC_RXENA (0x1 << 17) // (SSC) Receive Enable
+// -------- SSC_IER : (SSC Offset: 0x44) SSC Interrupt Enable Register --------
+// -------- SSC_IDR : (SSC Offset: 0x48) SSC Interrupt Disable Register --------
+// -------- SSC_IMR : (SSC Offset: 0x4c) SSC Interrupt Mask Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Usart
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_USART {
+ AT91_REG US_CR; // Control Register
+ AT91_REG US_MR; // Mode Register
+ AT91_REG US_IER; // Interrupt Enable Register
+ AT91_REG US_IDR; // Interrupt Disable Register
+ AT91_REG US_IMR; // Interrupt Mask Register
+ AT91_REG US_CSR; // Channel Status Register
+ AT91_REG US_RHR; // Receiver Holding Register
+ AT91_REG US_THR; // Transmitter Holding Register
+ AT91_REG US_BRGR; // Baud Rate Generator Register
+ AT91_REG US_RTOR; // Receiver Time-out Register
+ AT91_REG US_TTGR; // Transmitter Time-guard Register
+ AT91_REG Reserved0[5]; //
+ AT91_REG US_FIDI; // FI_DI_Ratio Register
+ AT91_REG US_NER; // Nb Errors Register
+ AT91_REG Reserved1[1]; //
+ AT91_REG US_IF; // IRDA_FILTER Register
+ AT91_REG Reserved2[44]; //
+ AT91_REG US_RPR; // Receive Pointer Register
+ AT91_REG US_RCR; // Receive Counter Register
+ AT91_REG US_TPR; // Transmit Pointer Register
+ AT91_REG US_TCR; // Transmit Counter Register
+ AT91_REG US_RNPR; // Receive Next Pointer Register
+ AT91_REG US_RNCR; // Receive Next Counter Register
+ AT91_REG US_TNPR; // Transmit Next Pointer Register
+ AT91_REG US_TNCR; // Transmit Next Counter Register
+ AT91_REG US_PTCR; // PDC Transfer Control Register
+ AT91_REG US_PTSR; // PDC Transfer Status Register
+} AT91S_USART, *AT91PS_USART;
+#else
+#define US_CR (AT91_CAST(AT91_REG *) 0x00000000) // (US_CR) Control Register
+#define US_MR (AT91_CAST(AT91_REG *) 0x00000004) // (US_MR) Mode Register
+#define US_IER (AT91_CAST(AT91_REG *) 0x00000008) // (US_IER) Interrupt Enable Register
+#define US_IDR (AT91_CAST(AT91_REG *) 0x0000000C) // (US_IDR) Interrupt Disable Register
+#define US_IMR (AT91_CAST(AT91_REG *) 0x00000010) // (US_IMR) Interrupt Mask Register
+#define US_CSR (AT91_CAST(AT91_REG *) 0x00000014) // (US_CSR) Channel Status Register
+#define US_RHR (AT91_CAST(AT91_REG *) 0x00000018) // (US_RHR) Receiver Holding Register
+#define US_THR (AT91_CAST(AT91_REG *) 0x0000001C) // (US_THR) Transmitter Holding Register
+#define US_BRGR (AT91_CAST(AT91_REG *) 0x00000020) // (US_BRGR) Baud Rate Generator Register
+#define US_RTOR (AT91_CAST(AT91_REG *) 0x00000024) // (US_RTOR) Receiver Time-out Register
+#define US_TTGR (AT91_CAST(AT91_REG *) 0x00000028) // (US_TTGR) Transmitter Time-guard Register
+#define US_FIDI (AT91_CAST(AT91_REG *) 0x00000040) // (US_FIDI) FI_DI_Ratio Register
+#define US_NER (AT91_CAST(AT91_REG *) 0x00000044) // (US_NER) Nb Errors Register
+#define US_IF (AT91_CAST(AT91_REG *) 0x0000004C) // (US_IF) IRDA_FILTER Register
+
+#endif
+// -------- US_CR : (USART Offset: 0x0) Debug Unit Control Register --------
+#define AT91C_US_STTBRK (0x1 << 9) // (USART) Start Break
+#define AT91C_US_STPBRK (0x1 << 10) // (USART) Stop Break
+#define AT91C_US_STTTO (0x1 << 11) // (USART) Start Time-out
+#define AT91C_US_SENDA (0x1 << 12) // (USART) Send Address
+#define AT91C_US_RSTIT (0x1 << 13) // (USART) Reset Iterations
+#define AT91C_US_RSTNACK (0x1 << 14) // (USART) Reset Non Acknowledge
+#define AT91C_US_RETTO (0x1 << 15) // (USART) Rearm Time-out
+#define AT91C_US_DTREN (0x1 << 16) // (USART) Data Terminal ready Enable
+#define AT91C_US_DTRDIS (0x1 << 17) // (USART) Data Terminal ready Disable
+#define AT91C_US_RTSEN (0x1 << 18) // (USART) Request to Send enable
+#define AT91C_US_RTSDIS (0x1 << 19) // (USART) Request to Send Disable
+// -------- US_MR : (USART Offset: 0x4) Debug Unit Mode Register --------
+#define AT91C_US_USMODE (0xF << 0) // (USART) Usart mode
+#define AT91C_US_USMODE_NORMAL (0x0) // (USART) Normal
+#define AT91C_US_USMODE_RS485 (0x1) // (USART) RS485
+#define AT91C_US_USMODE_HWHSH (0x2) // (USART) Hardware Handshaking
+#define AT91C_US_USMODE_MODEM (0x3) // (USART) Modem
+#define AT91C_US_USMODE_ISO7816_0 (0x4) // (USART) ISO7816 protocol: T = 0
+#define AT91C_US_USMODE_ISO7816_1 (0x6) // (USART) ISO7816 protocol: T = 1
+#define AT91C_US_USMODE_IRDA (0x8) // (USART) IrDA
+#define AT91C_US_USMODE_SWHSH (0xC) // (USART) Software Handshaking
+#define AT91C_US_CLKS (0x3 << 4) // (USART) Clock Selection (Baud Rate generator Input Clock
+#define AT91C_US_CLKS_CLOCK (0x0 << 4) // (USART) Clock
+#define AT91C_US_CLKS_FDIV1 (0x1 << 4) // (USART) fdiv1
+#define AT91C_US_CLKS_SLOW (0x2 << 4) // (USART) slow_clock (ARM)
+#define AT91C_US_CLKS_EXT (0x3 << 4) // (USART) External (SCK)
+#define AT91C_US_CHRL (0x3 << 6) // (USART) Clock Selection (Baud Rate generator Input Clock
+#define AT91C_US_CHRL_5_BITS (0x0 << 6) // (USART) Character Length: 5 bits
+#define AT91C_US_CHRL_6_BITS (0x1 << 6) // (USART) Character Length: 6 bits
+#define AT91C_US_CHRL_7_BITS (0x2 << 6) // (USART) Character Length: 7 bits
+#define AT91C_US_CHRL_8_BITS (0x3 << 6) // (USART) Character Length: 8 bits
+#define AT91C_US_SYNC (0x1 << 8) // (USART) Synchronous Mode Select
+#define AT91C_US_NBSTOP (0x3 << 12) // (USART) Number of Stop bits
+#define AT91C_US_NBSTOP_1_BIT (0x0 << 12) // (USART) 1 stop bit
+#define AT91C_US_NBSTOP_15_BIT (0x1 << 12) // (USART) Asynchronous (SYNC=0) 2 stop bits Synchronous (SYNC=1) 2 stop bits
+#define AT91C_US_NBSTOP_2_BIT (0x2 << 12) // (USART) 2 stop bits
+#define AT91C_US_MSBF (0x1 << 16) // (USART) Bit Order
+#define AT91C_US_MODE9 (0x1 << 17) // (USART) 9-bit Character length
+#define AT91C_US_CKLO (0x1 << 18) // (USART) Clock Output Select
+#define AT91C_US_OVER (0x1 << 19) // (USART) Over Sampling Mode
+#define AT91C_US_INACK (0x1 << 20) // (USART) Inhibit Non Acknowledge
+#define AT91C_US_DSNACK (0x1 << 21) // (USART) Disable Successive NACK
+#define AT91C_US_MAX_ITER (0x1 << 24) // (USART) Number of Repetitions
+#define AT91C_US_FILTER (0x1 << 28) // (USART) Receive Line Filter
+// -------- US_IER : (USART Offset: 0x8) Debug Unit Interrupt Enable Register --------
+#define AT91C_US_RXBRK (0x1 << 2) // (USART) Break Received/End of Break
+#define AT91C_US_TIMEOUT (0x1 << 8) // (USART) Receiver Time-out
+#define AT91C_US_ITERATION (0x1 << 10) // (USART) Max number of Repetitions Reached
+#define AT91C_US_NACK (0x1 << 13) // (USART) Non Acknowledge
+#define AT91C_US_RIIC (0x1 << 16) // (USART) Ring INdicator Input Change Flag
+#define AT91C_US_DSRIC (0x1 << 17) // (USART) Data Set Ready Input Change Flag
+#define AT91C_US_DCDIC (0x1 << 18) // (USART) Data Carrier Flag
+#define AT91C_US_CTSIC (0x1 << 19) // (USART) Clear To Send Input Change Flag
+// -------- US_IDR : (USART Offset: 0xc) Debug Unit Interrupt Disable Register --------
+// -------- US_IMR : (USART Offset: 0x10) Debug Unit Interrupt Mask Register --------
+// -------- US_CSR : (USART Offset: 0x14) Debug Unit Channel Status Register --------
+#define AT91C_US_RI (0x1 << 20) // (USART) Image of RI Input
+#define AT91C_US_DSR (0x1 << 21) // (USART) Image of DSR Input
+#define AT91C_US_DCD (0x1 << 22) // (USART) Image of DCD Input
+#define AT91C_US_CTS (0x1 << 23) // (USART) Image of CTS Input
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Two-wire Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_TWI {
+ AT91_REG TWI_CR; // Control Register
+ AT91_REG TWI_MMR; // Master Mode Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG TWI_IADR; // Internal Address Register
+ AT91_REG TWI_CWGR; // Clock Waveform Generator Register
+ AT91_REG Reserved1[3]; //
+ AT91_REG TWI_SR; // Status Register
+ AT91_REG TWI_IER; // Interrupt Enable Register
+ AT91_REG TWI_IDR; // Interrupt Disable Register
+ AT91_REG TWI_IMR; // Interrupt Mask Register
+ AT91_REG TWI_RHR; // Receive Holding Register
+ AT91_REG TWI_THR; // Transmit Holding Register
+ AT91_REG Reserved2[50]; //
+ AT91_REG TWI_RPR; // Receive Pointer Register
+ AT91_REG TWI_RCR; // Receive Counter Register
+ AT91_REG TWI_TPR; // Transmit Pointer Register
+ AT91_REG TWI_TCR; // Transmit Counter Register
+ AT91_REG TWI_RNPR; // Receive Next Pointer Register
+ AT91_REG TWI_RNCR; // Receive Next Counter Register
+ AT91_REG TWI_TNPR; // Transmit Next Pointer Register
+ AT91_REG TWI_TNCR; // Transmit Next Counter Register
+ AT91_REG TWI_PTCR; // PDC Transfer Control Register
+ AT91_REG TWI_PTSR; // PDC Transfer Status Register
+} AT91S_TWI, *AT91PS_TWI;
+#else
+#define TWI_CR (AT91_CAST(AT91_REG *) 0x00000000) // (TWI_CR) Control Register
+#define TWI_MMR (AT91_CAST(AT91_REG *) 0x00000004) // (TWI_MMR) Master Mode Register
+#define TWI_IADR (AT91_CAST(AT91_REG *) 0x0000000C) // (TWI_IADR) Internal Address Register
+#define TWI_CWGR (AT91_CAST(AT91_REG *) 0x00000010) // (TWI_CWGR) Clock Waveform Generator Register
+#define TWI_SR (AT91_CAST(AT91_REG *) 0x00000020) // (TWI_SR) Status Register
+#define TWI_IER (AT91_CAST(AT91_REG *) 0x00000024) // (TWI_IER) Interrupt Enable Register
+#define TWI_IDR (AT91_CAST(AT91_REG *) 0x00000028) // (TWI_IDR) Interrupt Disable Register
+#define TWI_IMR (AT91_CAST(AT91_REG *) 0x0000002C) // (TWI_IMR) Interrupt Mask Register
+#define TWI_RHR (AT91_CAST(AT91_REG *) 0x00000030) // (TWI_RHR) Receive Holding Register
+#define TWI_THR (AT91_CAST(AT91_REG *) 0x00000034) // (TWI_THR) Transmit Holding Register
+
+#endif
+// -------- TWI_CR : (TWI Offset: 0x0) TWI Control Register --------
+#define AT91C_TWI_START (0x1 << 0) // (TWI) Send a START Condition
+#define AT91C_TWI_STOP (0x1 << 1) // (TWI) Send a STOP Condition
+#define AT91C_TWI_MSEN (0x1 << 2) // (TWI) TWI Master Transfer Enabled
+#define AT91C_TWI_MSDIS (0x1 << 3) // (TWI) TWI Master Transfer Disabled
+#define AT91C_TWI_SWRST (0x1 << 7) // (TWI) Software Reset
+// -------- TWI_MMR : (TWI Offset: 0x4) TWI Master Mode Register --------
+#define AT91C_TWI_IADRSZ (0x3 << 8) // (TWI) Internal Device Address Size
+#define AT91C_TWI_IADRSZ_NO (0x0 << 8) // (TWI) No internal device address
+#define AT91C_TWI_IADRSZ_1_BYTE (0x1 << 8) // (TWI) One-byte internal device address
+#define AT91C_TWI_IADRSZ_2_BYTE (0x2 << 8) // (TWI) Two-byte internal device address
+#define AT91C_TWI_IADRSZ_3_BYTE (0x3 << 8) // (TWI) Three-byte internal device address
+#define AT91C_TWI_MREAD (0x1 << 12) // (TWI) Master Read Direction
+#define AT91C_TWI_DADR (0x7F << 16) // (TWI) Device Address
+// -------- TWI_CWGR : (TWI Offset: 0x10) TWI Clock Waveform Generator Register --------
+#define AT91C_TWI_CLDIV (0xFF << 0) // (TWI) Clock Low Divider
+#define AT91C_TWI_CHDIV (0xFF << 8) // (TWI) Clock High Divider
+#define AT91C_TWI_CKDIV (0x7 << 16) // (TWI) Clock Divider
+// -------- TWI_SR : (TWI Offset: 0x20) TWI Status Register --------
+#define AT91C_TWI_TXCOMP (0x1 << 0) // (TWI) Transmission Completed
+#define AT91C_TWI_RXRDY (0x1 << 1) // (TWI) Receive holding register ReaDY
+#define AT91C_TWI_TXRDY (0x1 << 2) // (TWI) Transmit holding register ReaDY
+#define AT91C_TWI_OVRE (0x1 << 6) // (TWI) Overrun Error
+#define AT91C_TWI_UNRE (0x1 << 7) // (TWI) Underrun Error
+#define AT91C_TWI_NACK (0x1 << 8) // (TWI) Not Acknowledged
+#define AT91C_TWI_ENDRX (0x1 << 12) // (TWI)
+#define AT91C_TWI_ENDTX (0x1 << 13) // (TWI)
+#define AT91C_TWI_RXBUFF (0x1 << 14) // (TWI)
+#define AT91C_TWI_TXBUFE (0x1 << 15) // (TWI)
+// -------- TWI_IER : (TWI Offset: 0x24) TWI Interrupt Enable Register --------
+// -------- TWI_IDR : (TWI Offset: 0x28) TWI Interrupt Disable Register --------
+// -------- TWI_IMR : (TWI Offset: 0x2c) TWI Interrupt Mask Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Timer Counter Channel Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_TC {
+ AT91_REG TC_CCR; // Channel Control Register
+ AT91_REG TC_CMR; // Channel Mode Register (Capture Mode / Waveform Mode)
+ AT91_REG Reserved0[2]; //
+ AT91_REG TC_CV; // Counter Value
+ AT91_REG TC_RA; // Register A
+ AT91_REG TC_RB; // Register B
+ AT91_REG TC_RC; // Register C
+ AT91_REG TC_SR; // Status Register
+ AT91_REG TC_IER; // Interrupt Enable Register
+ AT91_REG TC_IDR; // Interrupt Disable Register
+ AT91_REG TC_IMR; // Interrupt Mask Register
+} AT91S_TC, *AT91PS_TC;
+#else
+#define TC_CCR (AT91_CAST(AT91_REG *) 0x00000000) // (TC_CCR) Channel Control Register
+#define TC_CMR (AT91_CAST(AT91_REG *) 0x00000004) // (TC_CMR) Channel Mode Register (Capture Mode / Waveform Mode)
+#define TC_CV (AT91_CAST(AT91_REG *) 0x00000010) // (TC_CV) Counter Value
+#define TC_RA (AT91_CAST(AT91_REG *) 0x00000014) // (TC_RA) Register A
+#define TC_RB (AT91_CAST(AT91_REG *) 0x00000018) // (TC_RB) Register B
+#define TC_RC (AT91_CAST(AT91_REG *) 0x0000001C) // (TC_RC) Register C
+#define TC_SR (AT91_CAST(AT91_REG *) 0x00000020) // (TC_SR) Status Register
+#define TC_IER (AT91_CAST(AT91_REG *) 0x00000024) // (TC_IER) Interrupt Enable Register
+#define TC_IDR (AT91_CAST(AT91_REG *) 0x00000028) // (TC_IDR) Interrupt Disable Register
+#define TC_IMR (AT91_CAST(AT91_REG *) 0x0000002C) // (TC_IMR) Interrupt Mask Register
+
+#endif
+// -------- TC_CCR : (TC Offset: 0x0) TC Channel Control Register --------
+#define AT91C_TC_CLKEN (0x1 << 0) // (TC) Counter Clock Enable Command
+#define AT91C_TC_CLKDIS (0x1 << 1) // (TC) Counter Clock Disable Command
+#define AT91C_TC_SWTRG (0x1 << 2) // (TC) Software Trigger Command
+// -------- TC_CMR : (TC Offset: 0x4) TC Channel Mode Register: Capture Mode / Waveform Mode --------
+#define AT91C_TC_CLKS (0x7 << 0) // (TC) Clock Selection
+#define AT91C_TC_CLKS_TIMER_DIV1_CLOCK (0x0) // (TC) Clock selected: TIMER_DIV1_CLOCK
+#define AT91C_TC_CLKS_TIMER_DIV2_CLOCK (0x1) // (TC) Clock selected: TIMER_DIV2_CLOCK
+#define AT91C_TC_CLKS_TIMER_DIV3_CLOCK (0x2) // (TC) Clock selected: TIMER_DIV3_CLOCK
+#define AT91C_TC_CLKS_TIMER_DIV4_CLOCK (0x3) // (TC) Clock selected: TIMER_DIV4_CLOCK
+#define AT91C_TC_CLKS_TIMER_DIV5_CLOCK (0x4) // (TC) Clock selected: TIMER_DIV5_CLOCK
+#define AT91C_TC_CLKS_XC0 (0x5) // (TC) Clock selected: XC0
+#define AT91C_TC_CLKS_XC1 (0x6) // (TC) Clock selected: XC1
+#define AT91C_TC_CLKS_XC2 (0x7) // (TC) Clock selected: XC2
+#define AT91C_TC_CLKI (0x1 << 3) // (TC) Clock Invert
+#define AT91C_TC_BURST (0x3 << 4) // (TC) Burst Signal Selection
+#define AT91C_TC_BURST_NONE (0x0 << 4) // (TC) The clock is not gated by an external signal
+#define AT91C_TC_BURST_XC0 (0x1 << 4) // (TC) XC0 is ANDed with the selected clock
+#define AT91C_TC_BURST_XC1 (0x2 << 4) // (TC) XC1 is ANDed with the selected clock
+#define AT91C_TC_BURST_XC2 (0x3 << 4) // (TC) XC2 is ANDed with the selected clock
+#define AT91C_TC_CPCSTOP (0x1 << 6) // (TC) Counter Clock Stopped with RC Compare
+#define AT91C_TC_LDBSTOP (0x1 << 6) // (TC) Counter Clock Stopped with RB Loading
+#define AT91C_TC_CPCDIS (0x1 << 7) // (TC) Counter Clock Disable with RC Compare
+#define AT91C_TC_LDBDIS (0x1 << 7) // (TC) Counter Clock Disabled with RB Loading
+#define AT91C_TC_ETRGEDG (0x3 << 8) // (TC) External Trigger Edge Selection
+#define AT91C_TC_ETRGEDG_NONE (0x0 << 8) // (TC) Edge: None
+#define AT91C_TC_ETRGEDG_RISING (0x1 << 8) // (TC) Edge: rising edge
+#define AT91C_TC_ETRGEDG_FALLING (0x2 << 8) // (TC) Edge: falling edge
+#define AT91C_TC_ETRGEDG_BOTH (0x3 << 8) // (TC) Edge: each edge
+#define AT91C_TC_EEVTEDG (0x3 << 8) // (TC) External Event Edge Selection
+#define AT91C_TC_EEVTEDG_NONE (0x0 << 8) // (TC) Edge: None
+#define AT91C_TC_EEVTEDG_RISING (0x1 << 8) // (TC) Edge: rising edge
+#define AT91C_TC_EEVTEDG_FALLING (0x2 << 8) // (TC) Edge: falling edge
+#define AT91C_TC_EEVTEDG_BOTH (0x3 << 8) // (TC) Edge: each edge
+#define AT91C_TC_EEVT (0x3 << 10) // (TC) External Event Selection
+#define AT91C_TC_EEVT_TIOB (0x0 << 10) // (TC) Signal selected as external event: TIOB TIOB direction: input
+#define AT91C_TC_EEVT_XC0 (0x1 << 10) // (TC) Signal selected as external event: XC0 TIOB direction: output
+#define AT91C_TC_EEVT_XC1 (0x2 << 10) // (TC) Signal selected as external event: XC1 TIOB direction: output
+#define AT91C_TC_EEVT_XC2 (0x3 << 10) // (TC) Signal selected as external event: XC2 TIOB direction: output
+#define AT91C_TC_ABETRG (0x1 << 10) // (TC) TIOA or TIOB External Trigger Selection
+#define AT91C_TC_ENETRG (0x1 << 12) // (TC) External Event Trigger enable
+#define AT91C_TC_WAVESEL (0x3 << 13) // (TC) Waveform Selection
+#define AT91C_TC_WAVESEL_UP (0x0 << 13) // (TC) UP mode without atomatic trigger on RC Compare
+#define AT91C_TC_WAVESEL_UPDOWN (0x1 << 13) // (TC) UPDOWN mode without automatic trigger on RC Compare
+#define AT91C_TC_WAVESEL_UP_AUTO (0x2 << 13) // (TC) UP mode with automatic trigger on RC Compare
+#define AT91C_TC_WAVESEL_UPDOWN_AUTO (0x3 << 13) // (TC) UPDOWN mode with automatic trigger on RC Compare
+#define AT91C_TC_CPCTRG (0x1 << 14) // (TC) RC Compare Trigger Enable
+#define AT91C_TC_WAVE (0x1 << 15) // (TC)
+#define AT91C_TC_ACPA (0x3 << 16) // (TC) RA Compare Effect on TIOA
+#define T91C_TC_ACPA_NONE (0x0 << 16) // (TC) Effect: none
+#define AT91C_TC_ACPA_SET (0x1 << 16) // (TC) Effect: set
+#define AT91C_TC_ACPA_CLEAR (0x2 << 16) // (TC) Effect: clear
+#define AT91C_TC_ACPA_TOGGLE (0x3 << 16) // (TC) Effect: toggle
+#define AT91C_TC_LDRA (0x3 << 16) // (TC) RA Loading Selection
+#define T91C_TC_LDRA_NONE (0x0 << 16) // (TC) Edge: None
+#define AT91C_TC_LDRA_RISING (0x1 << 16) // (TC) Edge: rising edge of TIOA
+#define AT91C_TC_LDRA_FALLING (0x2 << 16) // (TC) Edge: falling edge of TIOA
+#define AT91C_TC_LDRA_BOTH (0x3 << 16) // (TC) Edge: each edge of TIOA
+#define AT91C_TC_ACPC (0x3 << 18) // (TC) RC Compare Effect on TIOA
+#define AT91C_TC_ACPC_NONE (0x0 << 18) // (TC) Effect: none
+#define AT91C_TC_ACPC_SET (0x1 << 18) // (TC) Effect: set
+#define AT91C_TC_ACPC_CLEAR (0x2 << 18) // (TC) Effect: clear
+#define AT91C_TC_ACPC_TOGGLE (0x3 << 18) // (TC) Effect: toggle
+#define AT91C_TC_LDRB (0x3 << 18) // (TC) RB Loading Selection
+#define AT91C_TC_LDRB_NONE (0x0 << 18) // (TC) Edge: None
+#define AT91C_TC_LDRB_RISING (0x1 << 18) // (TC) Edge: rising edge of TIOA
+#define AT91C_TC_LDRB_FALLING (0x2 << 18) // (TC) Edge: falling edge of TIOA
+#define AT91C_TC_LDRB_BOTH (0x3 << 18) // (TC) Edge: each edge of TIOA
+#define AT91C_TC_AEEVT (0x3 << 20) // (TC) External Event Effect on TIOA
+#define AT91C_TC_AEEVT_NONE (0x0 << 20) // (TC) Effect: none
+#define AT91C_TC_AEEVT_SET (0x1 << 20) // (TC) Effect: set
+#define AT91C_TC_AEEVT_CLEAR (0x2 << 20) // (TC) Effect: clear
+#define AT91C_TC_AEEVT_TOGGLE (0x3 << 20) // (TC) Effect: toggle
+#define AT91C_TC_ASWTRG (0x3 << 22) // (TC) Software Trigger Effect on TIOA
+#define AT91C_TC_ASWTRG_NONE (0x0 << 22) // (TC) Effect: none
+#define AT91C_TC_ASWTRG_SET (0x1 << 22) // (TC) Effect: set
+#define AT91C_TC_ASWTRG_CLEAR (0x2 << 22) // (TC) Effect: clear
+#define AT91C_TC_ASWTRG_TOGGLE (0x3 << 22) // (TC) Effect: toggle
+#define AT91C_TC_BCPB (0x3 << 24) // (TC) RB Compare Effect on TIOB
+#define AT91C_TC_BCPB_NONE (0x0 << 24) // (TC) Effect: none
+#define AT91C_TC_BCPB_SET (0x1 << 24) // (TC) Effect: set
+#define AT91C_TC_BCPB_CLEAR (0x2 << 24) // (TC) Effect: clear
+#define AT91C_TC_BCPB_TOGGLE (0x3 << 24) // (TC) Effect: toggle
+#define AT91C_TC_BCPC (0x3 << 26) // (TC) RC Compare Effect on TIOB
+#define AT91C_TC_BCPC_NONE (0x0 << 26) // (TC) Effect: none
+#define AT91C_TC_BCPC_SET (0x1 << 26) // (TC) Effect: set
+#define AT91C_TC_BCPC_CLEAR (0x2 << 26) // (TC) Effect: clear
+#define AT91C_TC_BCPC_TOGGLE (0x3 << 26) // (TC) Effect: toggle
+#define AT91C_TC_BEEVT (0x3 << 28) // (TC) External Event Effect on TIOB
+#define AT91C_TC_BEEVT_NONE (0x0 << 28) // (TC) Effect: none
+#define AT91C_TC_BEEVT_SET (0x1 << 28) // (TC) Effect: set
+#define AT91C_TC_BEEVT_CLEAR (0x2 << 28) // (TC) Effect: clear
+#define AT91C_TC_BEEVT_TOGGLE (0x3 << 28) // (TC) Effect: toggle
+#define AT91C_TC_BSWTRG (0x3 << 30) // (TC) Software Trigger Effect on TIOB
+#define AT91C_TC_BSWTRG_NONE (0x0 << 30) // (TC) Effect: none
+#define AT91C_TC_BSWTRG_SET (0x1 << 30) // (TC) Effect: set
+#define AT91C_TC_BSWTRG_CLEAR (0x2 << 30) // (TC) Effect: clear
+#define AT91C_TC_BSWTRG_TOGGLE (0x3 << 30) // (TC) Effect: toggle
+// -------- TC_SR : (TC Offset: 0x20) TC Channel Status Register --------
+#define AT91C_TC_COVFS (0x1 << 0) // (TC) Counter Overflow
+#define AT91C_TC_LOVRS (0x1 << 1) // (TC) Load Overrun
+#define AT91C_TC_CPAS (0x1 << 2) // (TC) RA Compare
+#define AT91C_TC_CPBS (0x1 << 3) // (TC) RB Compare
+#define AT91C_TC_CPCS (0x1 << 4) // (TC) RC Compare
+#define AT91C_TC_LDRAS (0x1 << 5) // (TC) RA Loading
+#define AT91C_TC_LDRBS (0x1 << 6) // (TC) RB Loading
+#define AT91C_TC_ETRGS (0x1 << 7) // (TC) External Trigger
+#define AT91C_TC_CLKSTA (0x1 << 16) // (TC) Clock Enabling
+#define AT91C_TC_MTIOA (0x1 << 17) // (TC) TIOA Mirror
+#define AT91C_TC_MTIOB (0x1 << 18) // (TC) TIOA Mirror
+// -------- TC_IER : (TC Offset: 0x24) TC Channel Interrupt Enable Register --------
+// -------- TC_IDR : (TC Offset: 0x28) TC Channel Interrupt Disable Register --------
+// -------- TC_IMR : (TC Offset: 0x2c) TC Channel Interrupt Mask Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Timer Counter Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_TCB {
+ AT91S_TC TCB_TC0; // TC Channel 0
+ AT91_REG Reserved0[4]; //
+ AT91S_TC TCB_TC1; // TC Channel 1
+ AT91_REG Reserved1[4]; //
+ AT91S_TC TCB_TC2; // TC Channel 2
+ AT91_REG Reserved2[4]; //
+ AT91_REG TCB_BCR; // TC Block Control Register
+ AT91_REG TCB_BMR; // TC Block Mode Register
+} AT91S_TCB, *AT91PS_TCB;
+#else
+#define TCB_BCR (AT91_CAST(AT91_REG *) 0x000000C0) // (TCB_BCR) TC Block Control Register
+#define TCB_BMR (AT91_CAST(AT91_REG *) 0x000000C4) // (TCB_BMR) TC Block Mode Register
+
+#endif
+// -------- TCB_BCR : (TCB Offset: 0xc0) TC Block Control Register --------
+#define AT91C_TCB_SYNC (0x1 << 0) // (TCB) Synchro Command
+// -------- TCB_BMR : (TCB Offset: 0xc4) TC Block Mode Register --------
+#define AT91C_TCB_TC0XC0S (0x3 << 0) // (TCB) External Clock Signal 0 Selection
+#define AT91C_TCB_TC0XC0S_TCLK0 (0x0) // (TCB) TCLK0 connected to XC0
+#define AT91C_TCB_TC0XC0S_NONE (0x1) // (TCB) None signal connected to XC0
+#define AT91C_TCB_TC0XC0S_TIOA1 (0x2) // (TCB) TIOA1 connected to XC0
+#define AT91C_TCB_TC0XC0S_TIOA2 (0x3) // (TCB) TIOA2 connected to XC0
+#define AT91C_TCB_TC1XC1S (0x3 << 2) // (TCB) External Clock Signal 1 Selection
+#define AT91C_TCB_TC1XC1S_TCLK1 (0x0 << 2) // (TCB) TCLK1 connected to XC1
+#define AT91C_TCB_TC1XC1S_NONE (0x1 << 2) // (TCB) None signal connected to XC1
+#define AT91C_TCB_TC1XC1S_TIOA0 (0x2 << 2) // (TCB) TIOA0 connected to XC1
+#define AT91C_TCB_TC1XC1S_TIOA2 (0x3 << 2) // (TCB) TIOA2 connected to XC1
+#define AT91C_TCB_TC2XC2S (0x3 << 4) // (TCB) External Clock Signal 2 Selection
+#define AT91C_TCB_TC2XC2S_TCLK2 (0x0 << 4) // (TCB) TCLK2 connected to XC2
+#define AT91C_TCB_TC2XC2S_NONE (0x1 << 4) // (TCB) None signal connected to XC2
+#define AT91C_TCB_TC2XC2S_TIOA0 (0x2 << 4) // (TCB) TIOA0 connected to XC2
+#define AT91C_TCB_TC2XC2S_TIOA1 (0x3 << 4) // (TCB) TIOA2 connected to XC2
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR PWMC Channel Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_PWMC_CH {
+ AT91_REG PWMC_CMR; // Channel Mode Register
+ AT91_REG PWMC_CDTYR; // Channel Duty Cycle Register
+ AT91_REG PWMC_CPRDR; // Channel Period Register
+ AT91_REG PWMC_CCNTR; // Channel Counter Register
+ AT91_REG PWMC_CUPDR; // Channel Update Register
+ AT91_REG PWMC_Reserved[3]; // Reserved
+} AT91S_PWMC_CH, *AT91PS_PWMC_CH;
+#else
+#define PWMC_CMR (AT91_CAST(AT91_REG *) 0x00000000) // (PWMC_CMR) Channel Mode Register
+#define PWMC_CDTYR (AT91_CAST(AT91_REG *) 0x00000004) // (PWMC_CDTYR) Channel Duty Cycle Register
+#define PWMC_CPRDR (AT91_CAST(AT91_REG *) 0x00000008) // (PWMC_CPRDR) Channel Period Register
+#define PWMC_CCNTR (AT91_CAST(AT91_REG *) 0x0000000C) // (PWMC_CCNTR) Channel Counter Register
+#define PWMC_CUPDR (AT91_CAST(AT91_REG *) 0x00000010) // (PWMC_CUPDR) Channel Update Register
+#define Reserved (AT91_CAST(AT91_REG *) 0x00000014) // (Reserved) Reserved
+
+#endif
+// -------- PWMC_CMR : (PWMC_CH Offset: 0x0) PWMC Channel Mode Register --------
+#define AT91C_PWMC_CPRE (0xF << 0) // (PWMC_CH) Channel Pre-scaler : PWMC_CLKx
+#define AT91C_PWMC_CPRE_MCK (0x0) // (PWMC_CH)
+#define AT91C_PWMC_CPRE_MCKA (0xB) // (PWMC_CH)
+#define AT91C_PWMC_CPRE_MCKB (0xC) // (PWMC_CH)
+#define AT91C_PWMC_CALG (0x1 << 8) // (PWMC_CH) Channel Alignment
+#define AT91C_PWMC_CPOL (0x1 << 9) // (PWMC_CH) Channel Polarity
+#define AT91C_PWMC_CPD (0x1 << 10) // (PWMC_CH) Channel Update Period
+// -------- PWMC_CDTYR : (PWMC_CH Offset: 0x4) PWMC Channel Duty Cycle Register --------
+#define AT91C_PWMC_CDTY (0x0 << 0) // (PWMC_CH) Channel Duty Cycle
+// -------- PWMC_CPRDR : (PWMC_CH Offset: 0x8) PWMC Channel Period Register --------
+#define AT91C_PWMC_CPRD (0x0 << 0) // (PWMC_CH) Channel Period
+// -------- PWMC_CCNTR : (PWMC_CH Offset: 0xc) PWMC Channel Counter Register --------
+#define AT91C_PWMC_CCNT (0x0 << 0) // (PWMC_CH) Channel Counter
+// -------- PWMC_CUPDR : (PWMC_CH Offset: 0x10) PWMC Channel Update Register --------
+#define AT91C_PWMC_CUPD (0x0 << 0) // (PWMC_CH) Channel Update
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Pulse Width Modulation Controller Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_PWMC {
+ AT91_REG PWMC_MR; // PWMC Mode Register
+ AT91_REG PWMC_ENA; // PWMC Enable Register
+ AT91_REG PWMC_DIS; // PWMC Disable Register
+ AT91_REG PWMC_SR; // PWMC Status Register
+ AT91_REG PWMC_IER; // PWMC Interrupt Enable Register
+ AT91_REG PWMC_IDR; // PWMC Interrupt Disable Register
+ AT91_REG PWMC_IMR; // PWMC Interrupt Mask Register
+ AT91_REG PWMC_ISR; // PWMC Interrupt Status Register
+ AT91_REG Reserved0[55]; //
+ AT91_REG PWMC_VR; // PWMC Version Register
+ AT91_REG Reserved1[64]; //
+ AT91S_PWMC_CH PWMC_CH[4]; // PWMC Channel
+} AT91S_PWMC, *AT91PS_PWMC;
+#else
+#define PWMC_MR (AT91_CAST(AT91_REG *) 0x00000000) // (PWMC_MR) PWMC Mode Register
+#define PWMC_ENA (AT91_CAST(AT91_REG *) 0x00000004) // (PWMC_ENA) PWMC Enable Register
+#define PWMC_DIS (AT91_CAST(AT91_REG *) 0x00000008) // (PWMC_DIS) PWMC Disable Register
+#define PWMC_SR (AT91_CAST(AT91_REG *) 0x0000000C) // (PWMC_SR) PWMC Status Register
+#define PWMC_IER (AT91_CAST(AT91_REG *) 0x00000010) // (PWMC_IER) PWMC Interrupt Enable Register
+#define PWMC_IDR (AT91_CAST(AT91_REG *) 0x00000014) // (PWMC_IDR) PWMC Interrupt Disable Register
+#define PWMC_IMR (AT91_CAST(AT91_REG *) 0x00000018) // (PWMC_IMR) PWMC Interrupt Mask Register
+#define PWMC_ISR (AT91_CAST(AT91_REG *) 0x0000001C) // (PWMC_ISR) PWMC Interrupt Status Register
+#define PWMC_VR (AT91_CAST(AT91_REG *) 0x000000FC) // (PWMC_VR) PWMC Version Register
+
+#endif
+// -------- PWMC_MR : (PWMC Offset: 0x0) PWMC Mode Register --------
+#define AT91C_PWMC_DIVA (0xFF << 0) // (PWMC) CLKA divide factor.
+#define AT91C_PWMC_PREA (0xF << 8) // (PWMC) Divider Input Clock Prescaler A
+#define AT91C_PWMC_PREA_MCK (0x0 << 8) // (PWMC)
+#define AT91C_PWMC_DIVB (0xFF << 16) // (PWMC) CLKB divide factor.
+#define AT91C_PWMC_PREB (0xF << 24) // (PWMC) Divider Input Clock Prescaler B
+#define AT91C_PWMC_PREB_MCK (0x0 << 24) // (PWMC)
+// -------- PWMC_ENA : (PWMC Offset: 0x4) PWMC Enable Register --------
+#define AT91C_PWMC_CHID0 (0x1 << 0) // (PWMC) Channel ID 0
+#define AT91C_PWMC_CHID1 (0x1 << 1) // (PWMC) Channel ID 1
+#define AT91C_PWMC_CHID2 (0x1 << 2) // (PWMC) Channel ID 2
+#define AT91C_PWMC_CHID3 (0x1 << 3) // (PWMC) Channel ID 3
+// -------- PWMC_DIS : (PWMC Offset: 0x8) PWMC Disable Register --------
+// -------- PWMC_SR : (PWMC Offset: 0xc) PWMC Status Register --------
+// -------- PWMC_IER : (PWMC Offset: 0x10) PWMC Interrupt Enable Register --------
+// -------- PWMC_IDR : (PWMC Offset: 0x14) PWMC Interrupt Disable Register --------
+// -------- PWMC_IMR : (PWMC Offset: 0x18) PWMC Interrupt Mask Register --------
+// -------- PWMC_ISR : (PWMC Offset: 0x1c) PWMC Interrupt Status Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR USB Device Interface
+// *****************************************************************************
+#ifndef __ASSEMBLY__
+typedef struct _AT91S_UDP {
+ AT91_REG UDP_NUM; // Frame Number Register
+ AT91_REG UDP_GLBSTATE; // Global State Register
+ AT91_REG UDP_FADDR; // Function Address Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG UDP_IER; // Interrupt Enable Register
+ AT91_REG UDP_IDR; // Interrupt Disable Register
+ AT91_REG UDP_IMR; // Interrupt Mask Register
+ AT91_REG UDP_ISR; // Interrupt Status Register
+ AT91_REG UDP_ICR; // Interrupt Clear Register
+ AT91_REG Reserved1[1]; //
+ AT91_REG UDP_RSTEP; // Reset Endpoint Register
+ AT91_REG Reserved2[1]; //
+ AT91_REG UDP_CSR[4]; // Endpoint Control and Status Register
+ AT91_REG Reserved3[4]; //
+ AT91_REG UDP_FDR[4]; // Endpoint FIFO Data Register
+ AT91_REG Reserved4[5]; //
+ AT91_REG UDP_TXVC; // Transceiver Control Register
+} AT91S_UDP, *AT91PS_UDP;
+#else
+#define UDP_FRM_NUM (AT91_CAST(AT91_REG *) 0x00000000) // (UDP_FRM_NUM) Frame Number Register
+#define UDP_GLBSTATE (AT91_CAST(AT91_REG *) 0x00000004) // (UDP_GLBSTATE) Global State Register
+#define UDP_FADDR (AT91_CAST(AT91_REG *) 0x00000008) // (UDP_FADDR) Function Address Register
+#define UDP_IER (AT91_CAST(AT91_REG *) 0x00000010) // (UDP_IER) Interrupt Enable Register
+#define UDP_IDR (AT91_CAST(AT91_REG *) 0x00000014) // (UDP_IDR) Interrupt Disable Register
+#define UDP_IMR (AT91_CAST(AT91_REG *) 0x00000018) // (UDP_IMR) Interrupt Mask Register
+#define UDP_ISR (AT91_CAST(AT91_REG *) 0x0000001C) // (UDP_ISR) Interrupt Status Register
+#define UDP_ICR (AT91_CAST(AT91_REG *) 0x00000020) // (UDP_ICR) Interrupt Clear Register
+#define UDP_RSTEP (AT91_CAST(AT91_REG *) 0x00000028) // (UDP_RSTEP) Reset Endpoint Register
+#define UDP_CSR (AT91_CAST(AT91_REG *) 0x00000030) // (UDP_CSR) Endpoint Control and Status Register
+#define UDP_FDR (AT91_CAST(AT91_REG *) 0x00000050) // (UDP_FDR) Endpoint FIFO Data Register
+#define UDP_TXVC (AT91_CAST(AT91_REG *) 0x00000074) // (UDP_TXVC) Transceiver Control Register
+
+#endif
+// -------- UDP_FRM_NUM : (UDP Offset: 0x0) USB Frame Number Register --------
+#define AT91C_UDP_FRM_NUM (0x7FF << 0) // (UDP) Frame Number as Defined in the Packet Field Formats
+#define AT91C_UDP_FRM_ERR (0x1 << 16) // (UDP) Frame Error
+#define AT91C_UDP_FRM_OK (0x1 << 17) // (UDP) Frame OK
+// -------- UDP_GLB_STATE : (UDP Offset: 0x4) USB Global State Register --------
+#define AT91C_UDP_FADDEN (0x1 << 0) // (UDP) Function Address Enable
+#define AT91C_UDP_CONFG (0x1 << 1) // (UDP) Configured
+#define AT91C_UDP_ESR (0x1 << 2) // (UDP) Enable Send Resume
+#define AT91C_UDP_RSMINPR (0x1 << 3) // (UDP) A Resume Has Been Sent to the Host
+#define AT91C_UDP_RMWUPE (0x1 << 4) // (UDP) Remote Wake Up Enable
+// -------- UDP_FADDR : (UDP Offset: 0x8) USB Function Address Register --------
+#define AT91C_UDP_FADD (0xFF << 0) // (UDP) Function Address Value
+#define AT91C_UDP_FEN (0x1 << 8) // (UDP) Function Enable
+// -------- UDP_IER : (UDP Offset: 0x10) USB Interrupt Enable Register --------
+#define AT91C_UDP_EPINT0 (0x1 << 0) // (UDP) Endpoint 0 Interrupt
+#define AT91C_UDP_EPINT1 (0x1 << 1) // (UDP) Endpoint 0 Interrupt
+#define AT91C_UDP_EPINT2 (0x1 << 2) // (UDP) Endpoint 2 Interrupt
+#define AT91C_UDP_EPINT3 (0x1 << 3) // (UDP) Endpoint 3 Interrupt
+#define AT91C_UDP_RXSUSP (0x1 << 8) // (UDP) USB Suspend Interrupt
+#define AT91C_UDP_RXRSM (0x1 << 9) // (UDP) USB Resume Interrupt
+#define AT91C_UDP_EXTRSM (0x1 << 10) // (UDP) USB External Resume Interrupt
+#define AT91C_UDP_SOFINT (0x1 << 11) // (UDP) USB Start Of frame Interrupt
+#define AT91C_UDP_WAKEUP (0x1 << 13) // (UDP) USB Resume Interrupt
+// -------- UDP_IDR : (UDP Offset: 0x14) USB Interrupt Disable Register --------
+// -------- UDP_IMR : (UDP Offset: 0x18) USB Interrupt Mask Register --------
+// -------- UDP_ISR : (UDP Offset: 0x1c) USB Interrupt Status Register --------
+#define AT91C_UDP_ENDBUSRES (0x1 << 12) // (UDP) USB End Of Bus Reset Interrupt
+// -------- UDP_ICR : (UDP Offset: 0x20) USB Interrupt Clear Register --------
+// -------- UDP_RST_EP : (UDP Offset: 0x28) USB Reset Endpoint Register --------
+#define AT91C_UDP_EP0 (0x1 << 0) // (UDP) Reset Endpoint 0
+#define AT91C_UDP_EP1 (0x1 << 1) // (UDP) Reset Endpoint 1
+#define AT91C_UDP_EP2 (0x1 << 2) // (UDP) Reset Endpoint 2
+#define AT91C_UDP_EP3 (0x1 << 3) // (UDP) Reset Endpoint 3
+// -------- UDP_CSR : (UDP Offset: 0x30) USB Endpoint Control and Status Register --------
+#define AT91C_UDP_TXCOMP (0x1 << 0) // (UDP) Generates an IN packet with data previously written in the DPR
+#define AT91C_UDP_RX_DATA_BK0 (0x1 << 1) // (UDP) Receive Data Bank 0
+#define AT91C_UDP_RXSETUP (0x1 << 2) // (UDP) Sends STALL to the Host (Control endpoints)
+#define AT91C_UDP_ISOERROR (0x1 << 3) // (UDP) Isochronous error (Isochronous endpoints)
+#define AT91C_UDP_STALLSENT (0x1 << 3) // (UDP) Stall sent (Control, bulk, interrupt endpoints)
+#define AT91C_UDP_TXPKTRDY (0x1 << 4) // (UDP) Transmit Packet Ready
+#define AT91C_UDP_FORCESTALL (0x1 << 5) // (UDP) Force Stall (used by Control, Bulk and Isochronous endpoints).
+#define AT91C_UDP_RX_DATA_BK1 (0x1 << 6) // (UDP) Receive Data Bank 1 (only used by endpoints with ping-pong attributes).
+#define AT91C_UDP_DIR (0x1 << 7) // (UDP) Transfer Direction
+#define AT91C_UDP_EPTYPE (0x7 << 8) // (UDP) Endpoint type
+#define AT91C_UDP_EPTYPE_CTRL (0x0 << 8) // (UDP) Control
+#define AT91C_UDP_EPTYPE_ISO_OUT (0x1 << 8) // (UDP) Isochronous OUT
+#define AT91C_UDP_EPTYPE_BULK_OUT (0x2 << 8) // (UDP) Bulk OUT
+#define AT91C_UDP_EPTYPE_INT_OUT (0x3 << 8) // (UDP) Interrupt OUT
+#define AT91C_UDP_EPTYPE_ISO_IN (0x5 << 8) // (UDP) Isochronous IN
+#define AT91C_UDP_EPTYPE_BULK_IN (0x6 << 8) // (UDP) Bulk IN
+#define AT91C_UDP_EPTYPE_INT_IN (0x7 << 8) // (UDP) Interrupt IN
+#define AT91C_UDP_DTGLE (0x1 << 11) // (UDP) Data Toggle
+#define AT91C_UDP_EPEDS (0x1 << 15) // (UDP) Endpoint Enable Disable
+#define AT91C_UDP_RXBYTECNT (0x7FF << 16) // (UDP) Number Of Bytes Available in the FIFO
+// -------- UDP_TXVC : (UDP Offset: 0x74) Transceiver Control Register --------
+#define AT91C_UDP_TXVDIS (0x1 << 8) // (UDP)
+
+// *****************************************************************************
+// REGISTER ADDRESS DEFINITION FOR AT91SAM7S512
+// *****************************************************************************
+// ========== Register definition for SYS peripheral ==========
+// ========== Register definition for AIC peripheral ==========
+#define AT91C_AIC_IVR (AT91_CAST(AT91_REG *) 0xFFFFF100) // (AIC) IRQ Vector Register
+#define AT91C_AIC_SMR (AT91_CAST(AT91_REG *) 0xFFFFF000) // (AIC) Source Mode Register
+#define AT91C_AIC_FVR (AT91_CAST(AT91_REG *) 0xFFFFF104) // (AIC) FIQ Vector Register
+#define AT91C_AIC_DCR (AT91_CAST(AT91_REG *) 0xFFFFF138) // (AIC) Debug Control Register (Protect)
+#define AT91C_AIC_EOICR (AT91_CAST(AT91_REG *) 0xFFFFF130) // (AIC) End of Interrupt Command Register
+#define AT91C_AIC_SVR (AT91_CAST(AT91_REG *) 0xFFFFF080) // (AIC) Source Vector Register
+#define AT91C_AIC_FFSR (AT91_CAST(AT91_REG *) 0xFFFFF148) // (AIC) Fast Forcing Status Register
+#define AT91C_AIC_ICCR (AT91_CAST(AT91_REG *) 0xFFFFF128) // (AIC) Interrupt Clear Command Register
+#define AT91C_AIC_ISR (AT91_CAST(AT91_REG *) 0xFFFFF108) // (AIC) Interrupt Status Register
+#define AT91C_AIC_IMR (AT91_CAST(AT91_REG *) 0xFFFFF110) // (AIC) Interrupt Mask Register
+#define AT91C_AIC_IPR (AT91_CAST(AT91_REG *) 0xFFFFF10C) // (AIC) Interrupt Pending Register
+#define AT91C_AIC_FFER (AT91_CAST(AT91_REG *) 0xFFFFF140) // (AIC) Fast Forcing Enable Register
+#define AT91C_AIC_IECR (AT91_CAST(AT91_REG *) 0xFFFFF120) // (AIC) Interrupt Enable Command Register
+#define AT91C_AIC_ISCR (AT91_CAST(AT91_REG *) 0xFFFFF12C) // (AIC) Interrupt Set Command Register
+#define AT91C_AIC_FFDR (AT91_CAST(AT91_REG *) 0xFFFFF144) // (AIC) Fast Forcing Disable Register
+#define AT91C_AIC_CISR (AT91_CAST(AT91_REG *) 0xFFFFF114) // (AIC) Core Interrupt Status Register
+#define AT91C_AIC_IDCR (AT91_CAST(AT91_REG *) 0xFFFFF124) // (AIC) Interrupt Disable Command Register
+#define AT91C_AIC_SPU (AT91_CAST(AT91_REG *) 0xFFFFF134) // (AIC) Spurious Vector Register
+// ========== Register definition for PDC_DBGU peripheral ==========
+#define AT91C_DBGU_TCR (AT91_CAST(AT91_REG *) 0xFFFFF30C) // (PDC_DBGU) Transmit Counter Register
+#define AT91C_DBGU_RNPR (AT91_CAST(AT91_REG *) 0xFFFFF310) // (PDC_DBGU) Receive Next Pointer Register
+#define AT91C_DBGU_TNPR (AT91_CAST(AT91_REG *) 0xFFFFF318) // (PDC_DBGU) Transmit Next Pointer Register
+#define AT91C_DBGU_TPR (AT91_CAST(AT91_REG *) 0xFFFFF308) // (PDC_DBGU) Transmit Pointer Register
+#define AT91C_DBGU_RPR (AT91_CAST(AT91_REG *) 0xFFFFF300) // (PDC_DBGU) Receive Pointer Register
+#define AT91C_DBGU_RCR (AT91_CAST(AT91_REG *) 0xFFFFF304) // (PDC_DBGU) Receive Counter Register
+#define AT91C_DBGU_RNCR (AT91_CAST(AT91_REG *) 0xFFFFF314) // (PDC_DBGU) Receive Next Counter Register
+#define AT91C_DBGU_PTCR (AT91_CAST(AT91_REG *) 0xFFFFF320) // (PDC_DBGU) PDC Transfer Control Register
+#define AT91C_DBGU_PTSR (AT91_CAST(AT91_REG *) 0xFFFFF324) // (PDC_DBGU) PDC Transfer Status Register
+#define AT91C_DBGU_TNCR (AT91_CAST(AT91_REG *) 0xFFFFF31C) // (PDC_DBGU) Transmit Next Counter Register
+// ========== Register definition for DBGU peripheral ==========
+#define AT91C_DBGU_EXID (AT91_CAST(AT91_REG *) 0xFFFFF244) // (DBGU) Chip ID Extension Register
+#define AT91C_DBGU_BRGR (AT91_CAST(AT91_REG *) 0xFFFFF220) // (DBGU) Baud Rate Generator Register
+#define AT91C_DBGU_IDR (AT91_CAST(AT91_REG *) 0xFFFFF20C) // (DBGU) Interrupt Disable Register
+#define AT91C_DBGU_CSR (AT91_CAST(AT91_REG *) 0xFFFFF214) // (DBGU) Channel Status Register
+#define AT91C_DBGU_CIDR (AT91_CAST(AT91_REG *) 0xFFFFF240) // (DBGU) Chip ID Register
+#define AT91C_DBGU_MR (AT91_CAST(AT91_REG *) 0xFFFFF204) // (DBGU) Mode Register
+#define AT91C_DBGU_IMR (AT91_CAST(AT91_REG *) 0xFFFFF210) // (DBGU) Interrupt Mask Register
+#define AT91C_DBGU_CR (AT91_CAST(AT91_REG *) 0xFFFFF200) // (DBGU) Control Register
+#define AT91C_DBGU_FNTR (AT91_CAST(AT91_REG *) 0xFFFFF248) // (DBGU) Force NTRST Register
+#define AT91C_DBGU_THR (AT91_CAST(AT91_REG *) 0xFFFFF21C) // (DBGU) Transmitter Holding Register
+#define AT91C_DBGU_RHR (AT91_CAST(AT91_REG *) 0xFFFFF218) // (DBGU) Receiver Holding Register
+#define AT91C_DBGU_IER (AT91_CAST(AT91_REG *) 0xFFFFF208) // (DBGU) Interrupt Enable Register
+// ========== Register definition for PIOA peripheral ==========
+#define AT91C_PIOA_ODR (AT91_CAST(AT91_REG *) 0xFFFFF414) // (PIOA) Output Disable Registerr
+#define AT91C_PIOA_SODR (AT91_CAST(AT91_REG *) 0xFFFFF430) // (PIOA) Set Output Data Register
+#define AT91C_PIOA_ISR (AT91_CAST(AT91_REG *) 0xFFFFF44C) // (PIOA) Interrupt Status Register
+#define AT91C_PIOA_ABSR (AT91_CAST(AT91_REG *) 0xFFFFF478) // (PIOA) AB Select Status Register
+#define AT91C_PIOA_IER (AT91_CAST(AT91_REG *) 0xFFFFF440) // (PIOA) Interrupt Enable Register
+#define AT91C_PIOA_PPUDR (AT91_CAST(AT91_REG *) 0xFFFFF460) // (PIOA) Pull-up Disable Register
+#define AT91C_PIOA_IMR (AT91_CAST(AT91_REG *) 0xFFFFF448) // (PIOA) Interrupt Mask Register
+#define AT91C_PIOA_PER (AT91_CAST(AT91_REG *) 0xFFFFF400) // (PIOA) PIO Enable Register
+#define AT91C_PIOA_IFDR (AT91_CAST(AT91_REG *) 0xFFFFF424) // (PIOA) Input Filter Disable Register
+#define AT91C_PIOA_OWDR (AT91_CAST(AT91_REG *) 0xFFFFF4A4) // (PIOA) Output Write Disable Register
+#define AT91C_PIOA_MDSR (AT91_CAST(AT91_REG *) 0xFFFFF458) // (PIOA) Multi-driver Status Register
+#define AT91C_PIOA_IDR (AT91_CAST(AT91_REG *) 0xFFFFF444) // (PIOA) Interrupt Disable Register
+#define AT91C_PIOA_ODSR (AT91_CAST(AT91_REG *) 0xFFFFF438) // (PIOA) Output Data Status Register
+#define AT91C_PIOA_PPUSR (AT91_CAST(AT91_REG *) 0xFFFFF468) // (PIOA) Pull-up Status Register
+#define AT91C_PIOA_OWSR (AT91_CAST(AT91_REG *) 0xFFFFF4A8) // (PIOA) Output Write Status Register
+#define AT91C_PIOA_BSR (AT91_CAST(AT91_REG *) 0xFFFFF474) // (PIOA) Select B Register
+#define AT91C_PIOA_OWER (AT91_CAST(AT91_REG *) 0xFFFFF4A0) // (PIOA) Output Write Enable Register
+#define AT91C_PIOA_IFER (AT91_CAST(AT91_REG *) 0xFFFFF420) // (PIOA) Input Filter Enable Register
+#define AT91C_PIOA_PDSR (AT91_CAST(AT91_REG *) 0xFFFFF43C) // (PIOA) Pin Data Status Register
+#define AT91C_PIOA_PPUER (AT91_CAST(AT91_REG *) 0xFFFFF464) // (PIOA) Pull-up Enable Register
+#define AT91C_PIOA_OSR (AT91_CAST(AT91_REG *) 0xFFFFF418) // (PIOA) Output Status Register
+#define AT91C_PIOA_ASR (AT91_CAST(AT91_REG *) 0xFFFFF470) // (PIOA) Select A Register
+#define AT91C_PIOA_MDDR (AT91_CAST(AT91_REG *) 0xFFFFF454) // (PIOA) Multi-driver Disable Register
+#define AT91C_PIOA_CODR (AT91_CAST(AT91_REG *) 0xFFFFF434) // (PIOA) Clear Output Data Register
+#define AT91C_PIOA_MDER (AT91_CAST(AT91_REG *) 0xFFFFF450) // (PIOA) Multi-driver Enable Register
+#define AT91C_PIOA_PDR (AT91_CAST(AT91_REG *) 0xFFFFF404) // (PIOA) PIO Disable Register
+#define AT91C_PIOA_IFSR (AT91_CAST(AT91_REG *) 0xFFFFF428) // (PIOA) Input Filter Status Register
+#define AT91C_PIOA_OER (AT91_CAST(AT91_REG *) 0xFFFFF410) // (PIOA) Output Enable Register
+#define AT91C_PIOA_PSR (AT91_CAST(AT91_REG *) 0xFFFFF408) // (PIOA) PIO Status Register
+// ========== Register definition for CKGR peripheral ==========
+#define AT91C_CKGR_MOR (AT91_CAST(AT91_REG *) 0xFFFFFC20) // (CKGR) Main Oscillator Register
+#define AT91C_CKGR_PLLR (AT91_CAST(AT91_REG *) 0xFFFFFC2C) // (CKGR) PLL Register
+#define AT91C_CKGR_MCFR (AT91_CAST(AT91_REG *) 0xFFFFFC24) // (CKGR) Main Clock Frequency Register
+// ========== Register definition for PMC peripheral ==========
+#define AT91C_PMC_IDR (AT91_CAST(AT91_REG *) 0xFFFFFC64) // (PMC) Interrupt Disable Register
+#define AT91C_PMC_MOR (AT91_CAST(AT91_REG *) 0xFFFFFC20) // (PMC) Main Oscillator Register
+#define AT91C_PMC_PLLR (AT91_CAST(AT91_REG *) 0xFFFFFC2C) // (PMC) PLL Register
+#define AT91C_PMC_PCER (AT91_CAST(AT91_REG *) 0xFFFFFC10) // (PMC) Peripheral Clock Enable Register
+#define AT91C_PMC_PCKR (AT91_CAST(AT91_REG *) 0xFFFFFC40) // (PMC) Programmable Clock Register
+#define AT91C_PMC_MCKR (AT91_CAST(AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register
+#define AT91C_PMC_SCDR (AT91_CAST(AT91_REG *) 0xFFFFFC04) // (PMC) System Clock Disable Register
+#define AT91C_PMC_PCDR (AT91_CAST(AT91_REG *) 0xFFFFFC14) // (PMC) Peripheral Clock Disable Register
+#define AT91C_PMC_SCSR (AT91_CAST(AT91_REG *) 0xFFFFFC08) // (PMC) System Clock Status Register
+#define AT91C_PMC_PCSR (AT91_CAST(AT91_REG *) 0xFFFFFC18) // (PMC) Peripheral Clock Status Register
+#define AT91C_PMC_MCFR (AT91_CAST(AT91_REG *) 0xFFFFFC24) // (PMC) Main Clock Frequency Register
+#define AT91C_PMC_SCER (AT91_CAST(AT91_REG *) 0xFFFFFC00) // (PMC) System Clock Enable Register
+#define AT91C_PMC_IMR (AT91_CAST(AT91_REG *) 0xFFFFFC6C) // (PMC) Interrupt Mask Register
+#define AT91C_PMC_IER (AT91_CAST(AT91_REG *) 0xFFFFFC60) // (PMC) Interrupt Enable Register
+#define AT91C_PMC_SR (AT91_CAST(AT91_REG *) 0xFFFFFC68) // (PMC) Status Register
+// ========== Register definition for RSTC peripheral ==========
+#define AT91C_RSTC_RCR (AT91_CAST(AT91_REG *) 0xFFFFFD00) // (RSTC) Reset Control Register
+#define AT91C_RSTC_RMR (AT91_CAST(AT91_REG *) 0xFFFFFD08) // (RSTC) Reset Mode Register
+#define AT91C_RSTC_RSR (AT91_CAST(AT91_REG *) 0xFFFFFD04) // (RSTC) Reset Status Register
+// ========== Register definition for RTTC peripheral ==========
+#define AT91C_RTTC_RTSR (AT91_CAST(AT91_REG *) 0xFFFFFD2C) // (RTTC) Real-time Status Register
+#define AT91C_RTTC_RTMR (AT91_CAST(AT91_REG *) 0xFFFFFD20) // (RTTC) Real-time Mode Register
+#define AT91C_RTTC_RTVR (AT91_CAST(AT91_REG *) 0xFFFFFD28) // (RTTC) Real-time Value Register
+#define AT91C_RTTC_RTAR (AT91_CAST(AT91_REG *) 0xFFFFFD24) // (RTTC) Real-time Alarm Register
+// ========== Register definition for PITC peripheral ==========
+#define AT91C_PITC_PIVR (AT91_CAST(AT91_REG *) 0xFFFFFD38) // (PITC) Period Interval Value Register
+#define AT91C_PITC_PISR (AT91_CAST(AT91_REG *) 0xFFFFFD34) // (PITC) Period Interval Status Register
+#define AT91C_PITC_PIIR (AT91_CAST(AT91_REG *) 0xFFFFFD3C) // (PITC) Period Interval Image Register
+#define AT91C_PITC_PIMR (AT91_CAST(AT91_REG *) 0xFFFFFD30) // (PITC) Period Interval Mode Register
+// ========== Register definition for WDTC peripheral ==========
+#define AT91C_WDTC_WDCR (AT91_CAST(AT91_REG *) 0xFFFFFD40) // (WDTC) Watchdog Control Register
+#define AT91C_WDTC_WDSR (AT91_CAST(AT91_REG *) 0xFFFFFD48) // (WDTC) Watchdog Status Register
+#define AT91C_WDTC_WDMR (AT91_CAST(AT91_REG *) 0xFFFFFD44) // (WDTC) Watchdog Mode Register
+// ========== Register definition for VREG peripheral ==========
+#define AT91C_VREG_MR (AT91_CAST(AT91_REG *) 0xFFFFFD60) // (VREG) Voltage Regulator Mode Register
+// ========== Register definition for EFC0 peripheral ==========
+#define AT91C_EFC0_FCR (AT91_CAST(AT91_REG *) 0xFFFFFF64) // (EFC0) MC Flash Command Register
+#define AT91C_EFC0_FSR (AT91_CAST(AT91_REG *) 0xFFFFFF68) // (EFC0) MC Flash Status Register
+#define AT91C_EFC0_VR (AT91_CAST(AT91_REG *) 0xFFFFFF6C) // (EFC0) MC Flash Version Register
+#define AT91C_EFC0_FMR (AT91_CAST(AT91_REG *) 0xFFFFFF60) // (EFC0) MC Flash Mode Register
+// ========== Register definition for EFC1 peripheral ==========
+#define AT91C_EFC1_VR (AT91_CAST(AT91_REG *) 0xFFFFFF7C) // (EFC1) MC Flash Version Register
+#define AT91C_EFC1_FCR (AT91_CAST(AT91_REG *) 0xFFFFFF74) // (EFC1) MC Flash Command Register
+#define AT91C_EFC1_FSR (AT91_CAST(AT91_REG *) 0xFFFFFF78) // (EFC1) MC Flash Status Register
+#define AT91C_EFC1_FMR (AT91_CAST(AT91_REG *) 0xFFFFFF70) // (EFC1) MC Flash Mode Register
+// ========== Register definition for MC peripheral ==========
+#define AT91C_MC_ASR (AT91_CAST(AT91_REG *) 0xFFFFFF04) // (MC) MC Abort Status Register
+#define AT91C_MC_RCR (AT91_CAST(AT91_REG *) 0xFFFFFF00) // (MC) MC Remap Control Register
+#define AT91C_MC_PUP (AT91_CAST(AT91_REG *) 0xFFFFFF50) // (MC) MC Protection Unit Peripherals
+#define AT91C_MC_PUIA (AT91_CAST(AT91_REG *) 0xFFFFFF10) // (MC) MC Protection Unit Area
+#define AT91C_MC_AASR (AT91_CAST(AT91_REG *) 0xFFFFFF08) // (MC) MC Abort Address Status Register
+#define AT91C_MC_PUER (AT91_CAST(AT91_REG *) 0xFFFFFF54) // (MC) MC Protection Unit Enable Register
+// ========== Register definition for PDC_SPI peripheral ==========
+#define AT91C_SPI_PTCR (AT91_CAST(AT91_REG *) 0xFFFE0120) // (PDC_SPI) PDC Transfer Control Register
+#define AT91C_SPI_TPR (AT91_CAST(AT91_REG *) 0xFFFE0108) // (PDC_SPI) Transmit Pointer Register
+#define AT91C_SPI_TCR (AT91_CAST(AT91_REG *) 0xFFFE010C) // (PDC_SPI) Transmit Counter Register
+#define AT91C_SPI_RCR (AT91_CAST(AT91_REG *) 0xFFFE0104) // (PDC_SPI) Receive Counter Register
+#define AT91C_SPI_PTSR (AT91_CAST(AT91_REG *) 0xFFFE0124) // (PDC_SPI) PDC Transfer Status Register
+#define AT91C_SPI_RNPR (AT91_CAST(AT91_REG *) 0xFFFE0110) // (PDC_SPI) Receive Next Pointer Register
+#define AT91C_SPI_RPR (AT91_CAST(AT91_REG *) 0xFFFE0100) // (PDC_SPI) Receive Pointer Register
+#define AT91C_SPI_TNCR (AT91_CAST(AT91_REG *) 0xFFFE011C) // (PDC_SPI) Transmit Next Counter Register
+#define AT91C_SPI_RNCR (AT91_CAST(AT91_REG *) 0xFFFE0114) // (PDC_SPI) Receive Next Counter Register
+#define AT91C_SPI_TNPR (AT91_CAST(AT91_REG *) 0xFFFE0118) // (PDC_SPI) Transmit Next Pointer Register
+// ========== Register definition for SPI peripheral ==========
+#define AT91C_SPI_IER (AT91_CAST(AT91_REG *) 0xFFFE0014) // (SPI) Interrupt Enable Register
+#define AT91C_SPI_SR (AT91_CAST(AT91_REG *) 0xFFFE0010) // (SPI) Status Register
+#define AT91C_SPI_IDR (AT91_CAST(AT91_REG *) 0xFFFE0018) // (SPI) Interrupt Disable Register
+#define AT91C_SPI_CR (AT91_CAST(AT91_REG *) 0xFFFE0000) // (SPI) Control Register
+#define AT91C_SPI_MR (AT91_CAST(AT91_REG *) 0xFFFE0004) // (SPI) Mode Register
+#define AT91C_SPI_IMR (AT91_CAST(AT91_REG *) 0xFFFE001C) // (SPI) Interrupt Mask Register
+#define AT91C_SPI_TDR (AT91_CAST(AT91_REG *) 0xFFFE000C) // (SPI) Transmit Data Register
+#define AT91C_SPI_RDR (AT91_CAST(AT91_REG *) 0xFFFE0008) // (SPI) Receive Data Register
+#define AT91C_SPI_CSR (AT91_CAST(AT91_REG *) 0xFFFE0030) // (SPI) Chip Select Register
+// ========== Register definition for PDC_ADC peripheral ==========
+#define AT91C_ADC_PTSR (AT91_CAST(AT91_REG *) 0xFFFD8124) // (PDC_ADC) PDC Transfer Status Register
+#define AT91C_ADC_PTCR (AT91_CAST(AT91_REG *) 0xFFFD8120) // (PDC_ADC) PDC Transfer Control Register
+#define AT91C_ADC_TNPR (AT91_CAST(AT91_REG *) 0xFFFD8118) // (PDC_ADC) Transmit Next Pointer Register
+#define AT91C_ADC_TNCR (AT91_CAST(AT91_REG *) 0xFFFD811C) // (PDC_ADC) Transmit Next Counter Register
+#define AT91C_ADC_RNPR (AT91_CAST(AT91_REG *) 0xFFFD8110) // (PDC_ADC) Receive Next Pointer Register
+#define AT91C_ADC_RNCR (AT91_CAST(AT91_REG *) 0xFFFD8114) // (PDC_ADC) Receive Next Counter Register
+#define AT91C_ADC_RPR (AT91_CAST(AT91_REG *) 0xFFFD8100) // (PDC_ADC) Receive Pointer Register
+#define AT91C_ADC_TCR (AT91_CAST(AT91_REG *) 0xFFFD810C) // (PDC_ADC) Transmit Counter Register
+#define AT91C_ADC_TPR (AT91_CAST(AT91_REG *) 0xFFFD8108) // (PDC_ADC) Transmit Pointer Register
+#define AT91C_ADC_RCR (AT91_CAST(AT91_REG *) 0xFFFD8104) // (PDC_ADC) Receive Counter Register
+// ========== Register definition for ADC peripheral ==========
+#define AT91C_ADC_CDR2 (AT91_CAST(AT91_REG *) 0xFFFD8038) // (ADC) ADC Channel Data Register 2
+#define AT91C_ADC_CDR3 (AT91_CAST(AT91_REG *) 0xFFFD803C) // (ADC) ADC Channel Data Register 3
+#define AT91C_ADC_CDR0 (AT91_CAST(AT91_REG *) 0xFFFD8030) // (ADC) ADC Channel Data Register 0
+#define AT91C_ADC_CDR5 (AT91_CAST(AT91_REG *) 0xFFFD8044) // (ADC) ADC Channel Data Register 5
+#define AT91C_ADC_CHDR (AT91_CAST(AT91_REG *) 0xFFFD8014) // (ADC) ADC Channel Disable Register
+#define AT91C_ADC_SR (AT91_CAST(AT91_REG *) 0xFFFD801C) // (ADC) ADC Status Register
+#define AT91C_ADC_CDR4 (AT91_CAST(AT91_REG *) 0xFFFD8040) // (ADC) ADC Channel Data Register 4
+#define AT91C_ADC_CDR1 (AT91_CAST(AT91_REG *) 0xFFFD8034) // (ADC) ADC Channel Data Register 1
+#define AT91C_ADC_LCDR (AT91_CAST(AT91_REG *) 0xFFFD8020) // (ADC) ADC Last Converted Data Register
+#define AT91C_ADC_IDR (AT91_CAST(AT91_REG *) 0xFFFD8028) // (ADC) ADC Interrupt Disable Register
+#define AT91C_ADC_CR (AT91_CAST(AT91_REG *) 0xFFFD8000) // (ADC) ADC Control Register
+#define AT91C_ADC_CDR7 (AT91_CAST(AT91_REG *) 0xFFFD804C) // (ADC) ADC Channel Data Register 7
+#define AT91C_ADC_CDR6 (AT91_CAST(AT91_REG *) 0xFFFD8048) // (ADC) ADC Channel Data Register 6
+#define AT91C_ADC_IER (AT91_CAST(AT91_REG *) 0xFFFD8024) // (ADC) ADC Interrupt Enable Register
+#define AT91C_ADC_CHER (AT91_CAST(AT91_REG *) 0xFFFD8010) // (ADC) ADC Channel Enable Register
+#define AT91C_ADC_CHSR (AT91_CAST(AT91_REG *) 0xFFFD8018) // (ADC) ADC Channel Status Register
+#define AT91C_ADC_MR (AT91_CAST(AT91_REG *) 0xFFFD8004) // (ADC) ADC Mode Register
+#define AT91C_ADC_IMR (AT91_CAST(AT91_REG *) 0xFFFD802C) // (ADC) ADC Interrupt Mask Register
+// ========== Register definition for PDC_SSC peripheral ==========
+#define AT91C_SSC_TNCR (AT91_CAST(AT91_REG *) 0xFFFD411C) // (PDC_SSC) Transmit Next Counter Register
+#define AT91C_SSC_RPR (AT91_CAST(AT91_REG *) 0xFFFD4100) // (PDC_SSC) Receive Pointer Register
+#define AT91C_SSC_RNCR (AT91_CAST(AT91_REG *) 0xFFFD4114) // (PDC_SSC) Receive Next Counter Register
+#define AT91C_SSC_TPR (AT91_CAST(AT91_REG *) 0xFFFD4108) // (PDC_SSC) Transmit Pointer Register
+#define AT91C_SSC_PTCR (AT91_CAST(AT91_REG *) 0xFFFD4120) // (PDC_SSC) PDC Transfer Control Register
+#define AT91C_SSC_TCR (AT91_CAST(AT91_REG *) 0xFFFD410C) // (PDC_SSC) Transmit Counter Register
+#define AT91C_SSC_RCR (AT91_CAST(AT91_REG *) 0xFFFD4104) // (PDC_SSC) Receive Counter Register
+#define AT91C_SSC_RNPR (AT91_CAST(AT91_REG *) 0xFFFD4110) // (PDC_SSC) Receive Next Pointer Register
+#define AT91C_SSC_TNPR (AT91_CAST(AT91_REG *) 0xFFFD4118) // (PDC_SSC) Transmit Next Pointer Register
+#define AT91C_SSC_PTSR (AT91_CAST(AT91_REG *) 0xFFFD4124) // (PDC_SSC) PDC Transfer Status Register
+// ========== Register definition for SSC peripheral ==========
+#define AT91C_SSC_RHR (AT91_CAST(AT91_REG *) 0xFFFD4020) // (SSC) Receive Holding Register
+#define AT91C_SSC_RSHR (AT91_CAST(AT91_REG *) 0xFFFD4030) // (SSC) Receive Sync Holding Register
+#define AT91C_SSC_TFMR (AT91_CAST(AT91_REG *) 0xFFFD401C) // (SSC) Transmit Frame Mode Register
+#define AT91C_SSC_IDR (AT91_CAST(AT91_REG *) 0xFFFD4048) // (SSC) Interrupt Disable Register
+#define AT91C_SSC_THR (AT91_CAST(AT91_REG *) 0xFFFD4024) // (SSC) Transmit Holding Register
+#define AT91C_SSC_RCMR (AT91_CAST(AT91_REG *) 0xFFFD4010) // (SSC) Receive Clock ModeRegister
+#define AT91C_SSC_IER (AT91_CAST(AT91_REG *) 0xFFFD4044) // (SSC) Interrupt Enable Register
+#define AT91C_SSC_TSHR (AT91_CAST(AT91_REG *) 0xFFFD4034) // (SSC) Transmit Sync Holding Register
+#define AT91C_SSC_SR (AT91_CAST(AT91_REG *) 0xFFFD4040) // (SSC) Status Register
+#define AT91C_SSC_CMR (AT91_CAST(AT91_REG *) 0xFFFD4004) // (SSC) Clock Mode Register
+#define AT91C_SSC_TCMR (AT91_CAST(AT91_REG *) 0xFFFD4018) // (SSC) Transmit Clock Mode Register
+#define AT91C_SSC_CR (AT91_CAST(AT91_REG *) 0xFFFD4000) // (SSC) Control Register
+#define AT91C_SSC_IMR (AT91_CAST(AT91_REG *) 0xFFFD404C) // (SSC) Interrupt Mask Register
+#define AT91C_SSC_RFMR (AT91_CAST(AT91_REG *) 0xFFFD4014) // (SSC) Receive Frame Mode Register
+// ========== Register definition for PDC_US1 peripheral ==========
+#define AT91C_US1_RNCR (AT91_CAST(AT91_REG *) 0xFFFC4114) // (PDC_US1) Receive Next Counter Register
+#define AT91C_US1_PTCR (AT91_CAST(AT91_REG *) 0xFFFC4120) // (PDC_US1) PDC Transfer Control Register
+#define AT91C_US1_TCR (AT91_CAST(AT91_REG *) 0xFFFC410C) // (PDC_US1) Transmit Counter Register
+#define AT91C_US1_PTSR (AT91_CAST(AT91_REG *) 0xFFFC4124) // (PDC_US1) PDC Transfer Status Register
+#define AT91C_US1_TNPR (AT91_CAST(AT91_REG *) 0xFFFC4118) // (PDC_US1) Transmit Next Pointer Register
+#define AT91C_US1_RCR (AT91_CAST(AT91_REG *) 0xFFFC4104) // (PDC_US1) Receive Counter Register
+#define AT91C_US1_RNPR (AT91_CAST(AT91_REG *) 0xFFFC4110) // (PDC_US1) Receive Next Pointer Register
+#define AT91C_US1_RPR (AT91_CAST(AT91_REG *) 0xFFFC4100) // (PDC_US1) Receive Pointer Register
+#define AT91C_US1_TNCR (AT91_CAST(AT91_REG *) 0xFFFC411C) // (PDC_US1) Transmit Next Counter Register
+#define AT91C_US1_TPR (AT91_CAST(AT91_REG *) 0xFFFC4108) // (PDC_US1) Transmit Pointer Register
+// ========== Register definition for US1 peripheral ==========
+#define AT91C_US1_IF (AT91_CAST(AT91_REG *) 0xFFFC404C) // (US1) IRDA_FILTER Register
+#define AT91C_US1_NER (AT91_CAST(AT91_REG *) 0xFFFC4044) // (US1) Nb Errors Register
+#define AT91C_US1_RTOR (AT91_CAST(AT91_REG *) 0xFFFC4024) // (US1) Receiver Time-out Register
+#define AT91C_US1_CSR (AT91_CAST(AT91_REG *) 0xFFFC4014) // (US1) Channel Status Register
+#define AT91C_US1_IDR (AT91_CAST(AT91_REG *) 0xFFFC400C) // (US1) Interrupt Disable Register
+#define AT91C_US1_IER (AT91_CAST(AT91_REG *) 0xFFFC4008) // (US1) Interrupt Enable Register
+#define AT91C_US1_THR (AT91_CAST(AT91_REG *) 0xFFFC401C) // (US1) Transmitter Holding Register
+#define AT91C_US1_TTGR (AT91_CAST(AT91_REG *) 0xFFFC4028) // (US1) Transmitter Time-guard Register
+#define AT91C_US1_RHR (AT91_CAST(AT91_REG *) 0xFFFC4018) // (US1) Receiver Holding Register
+#define AT91C_US1_BRGR (AT91_CAST(AT91_REG *) 0xFFFC4020) // (US1) Baud Rate Generator Register
+#define AT91C_US1_IMR (AT91_CAST(AT91_REG *) 0xFFFC4010) // (US1) Interrupt Mask Register
+#define AT91C_US1_FIDI (AT91_CAST(AT91_REG *) 0xFFFC4040) // (US1) FI_DI_Ratio Register
+#define AT91C_US1_CR (AT91_CAST(AT91_REG *) 0xFFFC4000) // (US1) Control Register
+#define AT91C_US1_MR (AT91_CAST(AT91_REG *) 0xFFFC4004) // (US1) Mode Register
+// ========== Register definition for PDC_US0 peripheral ==========
+#define AT91C_US0_TNPR (AT91_CAST(AT91_REG *) 0xFFFC0118) // (PDC_US0) Transmit Next Pointer Register
+#define AT91C_US0_RNPR (AT91_CAST(AT91_REG *) 0xFFFC0110) // (PDC_US0) Receive Next Pointer Register
+#define AT91C_US0_TCR (AT91_CAST(AT91_REG *) 0xFFFC010C) // (PDC_US0) Transmit Counter Register
+#define AT91C_US0_PTCR (AT91_CAST(AT91_REG *) 0xFFFC0120) // (PDC_US0) PDC Transfer Control Register
+#define AT91C_US0_PTSR (AT91_CAST(AT91_REG *) 0xFFFC0124) // (PDC_US0) PDC Transfer Status Register
+#define AT91C_US0_TNCR (AT91_CAST(AT91_REG *) 0xFFFC011C) // (PDC_US0) Transmit Next Counter Register
+#define AT91C_US0_TPR (AT91_CAST(AT91_REG *) 0xFFFC0108) // (PDC_US0) Transmit Pointer Register
+#define AT91C_US0_RCR (AT91_CAST(AT91_REG *) 0xFFFC0104) // (PDC_US0) Receive Counter Register
+#define AT91C_US0_RPR (AT91_CAST(AT91_REG *) 0xFFFC0100) // (PDC_US0) Receive Pointer Register
+#define AT91C_US0_RNCR (AT91_CAST(AT91_REG *) 0xFFFC0114) // (PDC_US0) Receive Next Counter Register
+// ========== Register definition for US0 peripheral ==========
+#define AT91C_US0_BRGR (AT91_CAST(AT91_REG *) 0xFFFC0020) // (US0) Baud Rate Generator Register
+#define AT91C_US0_NER (AT91_CAST(AT91_REG *) 0xFFFC0044) // (US0) Nb Errors Register
+#define AT91C_US0_CR (AT91_CAST(AT91_REG *) 0xFFFC0000) // (US0) Control Register
+#define AT91C_US0_IMR (AT91_CAST(AT91_REG *) 0xFFFC0010) // (US0) Interrupt Mask Register
+#define AT91C_US0_FIDI (AT91_CAST(AT91_REG *) 0xFFFC0040) // (US0) FI_DI_Ratio Register
+#define AT91C_US0_TTGR (AT91_CAST(AT91_REG *) 0xFFFC0028) // (US0) Transmitter Time-guard Register
+#define AT91C_US0_MR (AT91_CAST(AT91_REG *) 0xFFFC0004) // (US0) Mode Register
+#define AT91C_US0_RTOR (AT91_CAST(AT91_REG *) 0xFFFC0024) // (US0) Receiver Time-out Register
+#define AT91C_US0_CSR (AT91_CAST(AT91_REG *) 0xFFFC0014) // (US0) Channel Status Register
+#define AT91C_US0_RHR (AT91_CAST(AT91_REG *) 0xFFFC0018) // (US0) Receiver Holding Register
+#define AT91C_US0_IDR (AT91_CAST(AT91_REG *) 0xFFFC000C) // (US0) Interrupt Disable Register
+#define AT91C_US0_THR (AT91_CAST(AT91_REG *) 0xFFFC001C) // (US0) Transmitter Holding Register
+#define AT91C_US0_IF (AT91_CAST(AT91_REG *) 0xFFFC004C) // (US0) IRDA_FILTER Register
+#define AT91C_US0_IER (AT91_CAST(AT91_REG *) 0xFFFC0008) // (US0) Interrupt Enable Register
+// ========== Register definition for TWI peripheral ==========
+#define AT91C_TWI_IER (AT91_CAST(AT91_REG *) 0xFFFB8024) // (TWI) Interrupt Enable Register
+#define AT91C_TWI_CR (AT91_CAST(AT91_REG *) 0xFFFB8000) // (TWI) Control Register
+#define AT91C_TWI_SR (AT91_CAST(AT91_REG *) 0xFFFB8020) // (TWI) Status Register
+#define AT91C_TWI_IMR (AT91_CAST(AT91_REG *) 0xFFFB802C) // (TWI) Interrupt Mask Register
+#define AT91C_TWI_THR (AT91_CAST(AT91_REG *) 0xFFFB8034) // (TWI) Transmit Holding Register
+#define AT91C_TWI_IDR (AT91_CAST(AT91_REG *) 0xFFFB8028) // (TWI) Interrupt Disable Register
+#define AT91C_TWI_IADR (AT91_CAST(AT91_REG *) 0xFFFB800C) // (TWI) Internal Address Register
+#define AT91C_TWI_MMR (AT91_CAST(AT91_REG *) 0xFFFB8004) // (TWI) Master Mode Register
+#define AT91C_TWI_CWGR (AT91_CAST(AT91_REG *) 0xFFFB8010) // (TWI) Clock Waveform Generator Register
+#define AT91C_TWI_RHR (AT91_CAST(AT91_REG *) 0xFFFB8030) // (TWI) Receive Holding Register
+// ========== Register definition for TC0 peripheral ==========
+#define AT91C_TC0_SR (AT91_CAST(AT91_REG *) 0xFFFA0020) // (TC0) Status Register
+#define AT91C_TC0_RC (AT91_CAST(AT91_REG *) 0xFFFA001C) // (TC0) Register C
+#define AT91C_TC0_RB (AT91_CAST(AT91_REG *) 0xFFFA0018) // (TC0) Register B
+#define AT91C_TC0_CCR (AT91_CAST(AT91_REG *) 0xFFFA0000) // (TC0) Channel Control Register
+#define AT91C_TC0_CMR (AT91_CAST(AT91_REG *) 0xFFFA0004) // (TC0) Channel Mode Register (Capture Mode / Waveform Mode)
+#define AT91C_TC0_IER (AT91_CAST(AT91_REG *) 0xFFFA0024) // (TC0) Interrupt Enable Register
+#define AT91C_TC0_RA (AT91_CAST(AT91_REG *) 0xFFFA0014) // (TC0) Register A
+#define AT91C_TC0_IDR (AT91_CAST(AT91_REG *) 0xFFFA0028) // (TC0) Interrupt Disable Register
+#define AT91C_TC0_CV (AT91_CAST(AT91_REG *) 0xFFFA0010) // (TC0) Counter Value
+#define AT91C_TC0_IMR (AT91_CAST(AT91_REG *) 0xFFFA002C) // (TC0) Interrupt Mask Register
+// ========== Register definition for TC1 peripheral ==========
+#define AT91C_TC1_RB (AT91_CAST(AT91_REG *) 0xFFFA0058) // (TC1) Register B
+#define AT91C_TC1_CCR (AT91_CAST(AT91_REG *) 0xFFFA0040) // (TC1) Channel Control Register
+#define AT91C_TC1_IER (AT91_CAST(AT91_REG *) 0xFFFA0064) // (TC1) Interrupt Enable Register
+#define AT91C_TC1_IDR (AT91_CAST(AT91_REG *) 0xFFFA0068) // (TC1) Interrupt Disable Register
+#define AT91C_TC1_SR (AT91_CAST(AT91_REG *) 0xFFFA0060) // (TC1) Status Register
+#define AT91C_TC1_CMR (AT91_CAST(AT91_REG *) 0xFFFA0044) // (TC1) Channel Mode Register (Capture Mode / Waveform Mode)
+#define AT91C_TC1_RA (AT91_CAST(AT91_REG *) 0xFFFA0054) // (TC1) Register A
+#define AT91C_TC1_RC (AT91_CAST(AT91_REG *) 0xFFFA005C) // (TC1) Register C
+#define AT91C_TC1_IMR (AT91_CAST(AT91_REG *) 0xFFFA006C) // (TC1) Interrupt Mask Register
+#define AT91C_TC1_CV (AT91_CAST(AT91_REG *) 0xFFFA0050) // (TC1) Counter Value
+// ========== Register definition for TC2 peripheral ==========
+#define AT91C_TC2_CMR (AT91_CAST(AT91_REG *) 0xFFFA0084) // (TC2) Channel Mode Register (Capture Mode / Waveform Mode)
+#define AT91C_TC2_CCR (AT91_CAST(AT91_REG *) 0xFFFA0080) // (TC2) Channel Control Register
+#define AT91C_TC2_CV (AT91_CAST(AT91_REG *) 0xFFFA0090) // (TC2) Counter Value
+#define AT91C_TC2_RA (AT91_CAST(AT91_REG *) 0xFFFA0094) // (TC2) Register A
+#define AT91C_TC2_RB (AT91_CAST(AT91_REG *) 0xFFFA0098) // (TC2) Register B
+#define AT91C_TC2_IDR (AT91_CAST(AT91_REG *) 0xFFFA00A8) // (TC2) Interrupt Disable Register
+#define AT91C_TC2_IMR (AT91_CAST(AT91_REG *) 0xFFFA00AC) // (TC2) Interrupt Mask Register
+#define AT91C_TC2_RC (AT91_CAST(AT91_REG *) 0xFFFA009C) // (TC2) Register C
+#define AT91C_TC2_IER (AT91_CAST(AT91_REG *) 0xFFFA00A4) // (TC2) Interrupt Enable Register
+#define AT91C_TC2_SR (AT91_CAST(AT91_REG *) 0xFFFA00A0) // (TC2) Status Register
+// ========== Register definition for TCB peripheral ==========
+#define AT91C_TCB_BMR (AT91_CAST(AT91_REG *) 0xFFFA00C4) // (TCB) TC Block Mode Register
+#define AT91C_TCB_BCR (AT91_CAST(AT91_REG *) 0xFFFA00C0) // (TCB) TC Block Control Register
+// ========== Register definition for PWMC_CH3 peripheral ==========
+#define AT91C_PWMC_CH3_CUPDR (AT91_CAST(AT91_REG *) 0xFFFCC270) // (PWMC_CH3) Channel Update Register
+#define AT91C_PWMC_CH3_Reserved (AT91_CAST(AT91_REG *) 0xFFFCC274) // (PWMC_CH3) Reserved
+#define AT91C_PWMC_CH3_CPRDR (AT91_CAST(AT91_REG *) 0xFFFCC268) // (PWMC_CH3) Channel Period Register
+#define AT91C_PWMC_CH3_CDTYR (AT91_CAST(AT91_REG *) 0xFFFCC264) // (PWMC_CH3) Channel Duty Cycle Register
+#define AT91C_PWMC_CH3_CCNTR (AT91_CAST(AT91_REG *) 0xFFFCC26C) // (PWMC_CH3) Channel Counter Register
+#define AT91C_PWMC_CH3_CMR (AT91_CAST(AT91_REG *) 0xFFFCC260) // (PWMC_CH3) Channel Mode Register
+// ========== Register definition for PWMC_CH2 peripheral ==========
+#define AT91C_PWMC_CH2_Reserved (AT91_CAST(AT91_REG *) 0xFFFCC254) // (PWMC_CH2) Reserved
+#define AT91C_PWMC_CH2_CMR (AT91_CAST(AT91_REG *) 0xFFFCC240) // (PWMC_CH2) Channel Mode Register
+#define AT91C_PWMC_CH2_CCNTR (AT91_CAST(AT91_REG *) 0xFFFCC24C) // (PWMC_CH2) Channel Counter Register
+#define AT91C_PWMC_CH2_CPRDR (AT91_CAST(AT91_REG *) 0xFFFCC248) // (PWMC_CH2) Channel Period Register
+#define AT91C_PWMC_CH2_CUPDR (AT91_CAST(AT91_REG *) 0xFFFCC250) // (PWMC_CH2) Channel Update Register
+#define AT91C_PWMC_CH2_CDTYR (AT91_CAST(AT91_REG *) 0xFFFCC244) // (PWMC_CH2) Channel Duty Cycle Register
+// ========== Register definition for PWMC_CH1 peripheral ==========
+#define AT91C_PWMC_CH1_Reserved (AT91_CAST(AT91_REG *) 0xFFFCC234) // (PWMC_CH1) Reserved
+#define AT91C_PWMC_CH1_CUPDR (AT91_CAST(AT91_REG *) 0xFFFCC230) // (PWMC_CH1) Channel Update Register
+#define AT91C_PWMC_CH1_CPRDR (AT91_CAST(AT91_REG *) 0xFFFCC228) // (PWMC_CH1) Channel Period Register
+#define AT91C_PWMC_CH1_CCNTR (AT91_CAST(AT91_REG *) 0xFFFCC22C) // (PWMC_CH1) Channel Counter Register
+#define AT91C_PWMC_CH1_CDTYR (AT91_CAST(AT91_REG *) 0xFFFCC224) // (PWMC_CH1) Channel Duty Cycle Register
+#define AT91C_PWMC_CH1_CMR (AT91_CAST(AT91_REG *) 0xFFFCC220) // (PWMC_CH1) Channel Mode Register
+// ========== Register definition for PWMC_CH0 peripheral ==========
+#define AT91C_PWMC_CH0_Reserved (AT91_CAST(AT91_REG *) 0xFFFCC214) // (PWMC_CH0) Reserved
+#define AT91C_PWMC_CH0_CPRDR (AT91_CAST(AT91_REG *) 0xFFFCC208) // (PWMC_CH0) Channel Period Register
+#define AT91C_PWMC_CH0_CDTYR (AT91_CAST(AT91_REG *) 0xFFFCC204) // (PWMC_CH0) Channel Duty Cycle Register
+#define AT91C_PWMC_CH0_CMR (AT91_CAST(AT91_REG *) 0xFFFCC200) // (PWMC_CH0) Channel Mode Register
+#define AT91C_PWMC_CH0_CUPDR (AT91_CAST(AT91_REG *) 0xFFFCC210) // (PWMC_CH0) Channel Update Register
+#define AT91C_PWMC_CH0_CCNTR (AT91_CAST(AT91_REG *) 0xFFFCC20C) // (PWMC_CH0) Channel Counter Register
+// ========== Register definition for PWMC peripheral ==========
+#define AT91C_PWMC_IDR (AT91_CAST(AT91_REG *) 0xFFFCC014) // (PWMC) PWMC Interrupt Disable Register
+#define AT91C_PWMC_DIS (AT91_CAST(AT91_REG *) 0xFFFCC008) // (PWMC) PWMC Disable Register
+#define AT91C_PWMC_IER (AT91_CAST(AT91_REG *) 0xFFFCC010) // (PWMC) PWMC Interrupt Enable Register
+#define AT91C_PWMC_VR (AT91_CAST(AT91_REG *) 0xFFFCC0FC) // (PWMC) PWMC Version Register
+#define AT91C_PWMC_ISR (AT91_CAST(AT91_REG *) 0xFFFCC01C) // (PWMC) PWMC Interrupt Status Register
+#define AT91C_PWMC_SR (AT91_CAST(AT91_REG *) 0xFFFCC00C) // (PWMC) PWMC Status Register
+#define AT91C_PWMC_IMR (AT91_CAST(AT91_REG *) 0xFFFCC018) // (PWMC) PWMC Interrupt Mask Register
+#define AT91C_PWMC_MR (AT91_CAST(AT91_REG *) 0xFFFCC000) // (PWMC) PWMC Mode Register
+#define AT91C_PWMC_ENA (AT91_CAST(AT91_REG *) 0xFFFCC004) // (PWMC) PWMC Enable Register
+// ========== Register definition for UDP peripheral ==========
+#define AT91C_UDP_IMR (AT91_CAST(AT91_REG *) 0xFFFB0018) // (UDP) Interrupt Mask Register
+#define AT91C_UDP_FADDR (AT91_CAST(AT91_REG *) 0xFFFB0008) // (UDP) Function Address Register
+#define AT91C_UDP_NUM (AT91_CAST(AT91_REG *) 0xFFFB0000) // (UDP) Frame Number Register
+#define AT91C_UDP_FDR (AT91_CAST(AT91_REG *) 0xFFFB0050) // (UDP) Endpoint FIFO Data Register
+#define AT91C_UDP_ISR (AT91_CAST(AT91_REG *) 0xFFFB001C) // (UDP) Interrupt Status Register
+#define AT91C_UDP_CSR (AT91_CAST(AT91_REG *) 0xFFFB0030) // (UDP) Endpoint Control and Status Register
+#define AT91C_UDP_IDR (AT91_CAST(AT91_REG *) 0xFFFB0014) // (UDP) Interrupt Disable Register
+#define AT91C_UDP_ICR (AT91_CAST(AT91_REG *) 0xFFFB0020) // (UDP) Interrupt Clear Register
+#define AT91C_UDP_RSTEP (AT91_CAST(AT91_REG *) 0xFFFB0028) // (UDP) Reset Endpoint Register
+#define AT91C_UDP_TXVC (AT91_CAST(AT91_REG *) 0xFFFB0074) // (UDP) Transceiver Control Register
+#define AT91C_UDP_GLBSTATE (AT91_CAST(AT91_REG *) 0xFFFB0004) // (UDP) Global State Register
+#define AT91C_UDP_IER (AT91_CAST(AT91_REG *) 0xFFFB0010) // (UDP) Interrupt Enable Register
+
+// *****************************************************************************
+// PIO DEFINITIONS FOR AT91SAM7S512
+// *****************************************************************************
+#define AT91C_PIO_PA0 (1 << 0) // Pin Controlled by PA0
+#define AT91C_PA0_PWM0 (AT91C_PIO_PA0) // PWM Channel 0
+#define AT91C_PA0_TIOA0 (AT91C_PIO_PA0) // Timer Counter 0 Multipurpose Timer I/O Pin A
+#define AT91C_PIO_PA1 (1 << 1) // Pin Controlled by PA1
+#define AT91C_PA1_PWM1 (AT91C_PIO_PA1) // PWM Channel 1
+#define AT91C_PA1_TIOB0 (AT91C_PIO_PA1) // Timer Counter 0 Multipurpose Timer I/O Pin B
+#define AT91C_PIO_PA2 (1 << 2) // Pin Controlled by PA2
+#define AT91C_PA2_PWM2 (AT91C_PIO_PA2) // PWM Channel 2
+#define AT91C_PA2_SCK0 (AT91C_PIO_PA2) // USART 0 Serial Clock
+#define AT91C_PIO_PA3 (1 << 3) // Pin Controlled by PA3
+#define AT91C_PA3_TWD (AT91C_PIO_PA3) // TWI Two-wire Serial Data
+#define AT91C_PA3_NPCS3 (AT91C_PIO_PA3) // SPI Peripheral Chip Select 3
+#define AT91C_PIO_PA4 (1 << 4) // Pin Controlled by PA4
+#define AT91C_PA4_TWCK (AT91C_PIO_PA4) // TWI Two-wire Serial Clock
+#define AT91C_PA4_TCLK0 (AT91C_PIO_PA4) // Timer Counter 0 external clock input
+#define AT91C_PIO_PA5 (1 << 5) // Pin Controlled by PA5
+#define AT91C_PA5_RXD0 (AT91C_PIO_PA5) // USART 0 Receive Data
+#define AT91C_PA5_NPCS3 (AT91C_PIO_PA5) // SPI Peripheral Chip Select 3
+#define AT91C_PIO_PA6 (1 << 6) // Pin Controlled by PA6
+#define AT91C_PA6_TXD0 (AT91C_PIO_PA6) // USART 0 Transmit Data
+#define AT91C_PA6_PCK0 (AT91C_PIO_PA6) // PMC Programmable Clock Output 0
+#define AT91C_PIO_PA7 (1 << 7) // Pin Controlled by PA7
+#define AT91C_PA7_RTS0 (AT91C_PIO_PA7) // USART 0 Ready To Send
+#define AT91C_PA7_PWM3 (AT91C_PIO_PA7) // PWM Channel 3
+#define AT91C_PIO_PA8 (1 << 8) // Pin Controlled by PA8
+#define AT91C_PA8_CTS0 (AT91C_PIO_PA8) // USART 0 Clear To Send
+#define AT91C_PA8_ADTRG (AT91C_PIO_PA8) // ADC External Trigger
+#define AT91C_PIO_PA9 (1 << 9) // Pin Controlled by PA9
+#define AT91C_PA9_DRXD (AT91C_PIO_PA9) // DBGU Debug Receive Data
+#define AT91C_PA9_NPCS1 (AT91C_PIO_PA9) // SPI Peripheral Chip Select 1
+#define AT91C_PIO_PA10 (1 << 10) // Pin Controlled by PA10
+#define AT91C_PA10_DTXD (AT91C_PIO_PA10) // DBGU Debug Transmit Data
+#define AT91C_PA10_NPCS2 (AT91C_PIO_PA10) // SPI Peripheral Chip Select 2
+#define AT91C_PIO_PA11 (1 << 11) // Pin Controlled by PA11
+#define AT91C_PA11_NPCS0 (AT91C_PIO_PA11) // SPI Peripheral Chip Select 0
+#define AT91C_PA11_PWM0 (AT91C_PIO_PA11) // PWM Channel 0
+#define AT91C_PIO_PA12 (1 << 12) // Pin Controlled by PA12
+#define AT91C_PA12_MISO (AT91C_PIO_PA12) // SPI Master In Slave
+#define AT91C_PA12_PWM1 (AT91C_PIO_PA12) // PWM Channel 1
+#define AT91C_PIO_PA13 (1 << 13) // Pin Controlled by PA13
+#define AT91C_PA13_MOSI (AT91C_PIO_PA13) // SPI Master Out Slave
+#define AT91C_PA13_PWM2 (AT91C_PIO_PA13) // PWM Channel 2
+#define AT91C_PIO_PA14 (1 << 14) // Pin Controlled by PA14
+#define AT91C_PA14_SPCK (AT91C_PIO_PA14) // SPI Serial Clock
+#define AT91C_PA14_PWM3 (AT91C_PIO_PA14) // PWM Channel 3
+#define AT91C_PIO_PA15 (1 << 15) // Pin Controlled by PA15
+#define AT91C_PA15_TF (AT91C_PIO_PA15) // SSC Transmit Frame Sync
+#define AT91C_PA15_TIOA1 (AT91C_PIO_PA15) // Timer Counter 1 Multipurpose Timer I/O Pin A
+#define AT91C_PIO_PA16 (1 << 16) // Pin Controlled by PA16
+#define AT91C_PA16_TK (AT91C_PIO_PA16) // SSC Transmit Clock
+#define AT91C_PA16_TIOB1 (AT91C_PIO_PA16) // Timer Counter 1 Multipurpose Timer I/O Pin B
+#define AT91C_PIO_PA17 (1 << 17) // Pin Controlled by PA17
+#define AT91C_PA17_TD (AT91C_PIO_PA17) // SSC Transmit data
+#define AT91C_PA17_PCK1 (AT91C_PIO_PA17) // PMC Programmable Clock Output 1
+#define AT91C_PIO_PA18 (1 << 18) // Pin Controlled by PA18
+#define AT91C_PA18_RD (AT91C_PIO_PA18) // SSC Receive Data
+#define AT91C_PA18_PCK2 (AT91C_PIO_PA18) // PMC Programmable Clock Output 2
+#define AT91C_PIO_PA19 (1 << 19) // Pin Controlled by PA19
+#define AT91C_PA19_RK (AT91C_PIO_PA19) // SSC Receive Clock
+#define AT91C_PA19_FIQ (AT91C_PIO_PA19) // AIC Fast Interrupt Input
+#define AT91C_PIO_PA20 (1 << 20) // Pin Controlled by PA20
+#define AT91C_PA20_RF (AT91C_PIO_PA20) // SSC Receive Frame Sync
+#define AT91C_PA20_IRQ0 (AT91C_PIO_PA20) // External Interrupt 0
+#define AT91C_PIO_PA21 (1 << 21) // Pin Controlled by PA21
+#define AT91C_PA21_RXD1 (AT91C_PIO_PA21) // USART 1 Receive Data
+#define AT91C_PA21_PCK1 (AT91C_PIO_PA21) // PMC Programmable Clock Output 1
+#define AT91C_PIO_PA22 (1 << 22) // Pin Controlled by PA22
+#define AT91C_PA22_TXD1 (AT91C_PIO_PA22) // USART 1 Transmit Data
+#define AT91C_PA22_NPCS3 (AT91C_PIO_PA22) // SPI Peripheral Chip Select 3
+#define AT91C_PIO_PA23 (1 << 23) // Pin Controlled by PA23
+#define AT91C_PA23_SCK1 (AT91C_PIO_PA23) // USART 1 Serial Clock
+#define AT91C_PA23_PWM0 (AT91C_PIO_PA23) // PWM Channel 0
+#define AT91C_PIO_PA24 (1 << 24) // Pin Controlled by PA24
+#define AT91C_PA24_RTS1 (AT91C_PIO_PA24) // USART 1 Ready To Send
+#define AT91C_PA24_PWM1 (AT91C_PIO_PA24) // PWM Channel 1
+#define AT91C_PIO_PA25 (1 << 25) // Pin Controlled by PA25
+#define AT91C_PA25_CTS1 (AT91C_PIO_PA25) // USART 1 Clear To Send
+#define AT91C_PA25_PWM2 (AT91C_PIO_PA25) // PWM Channel 2
+#define AT91C_PIO_PA26 (1 << 26) // Pin Controlled by PA26
+#define AT91C_PA26_DCD1 (AT91C_PIO_PA26) // USART 1 Data Carrier Detect
+#define AT91C_PA26_TIOA2 (AT91C_PIO_PA26) // Timer Counter 2 Multipurpose Timer I/O Pin A
+#define AT91C_PIO_PA27 (1 << 27) // Pin Controlled by PA27
+#define AT91C_PA27_DTR1 (AT91C_PIO_PA27) // USART 1 Data Terminal ready
+#define AT91C_PA27_TIOB2 (AT91C_PIO_PA27) // Timer Counter 2 Multipurpose Timer I/O Pin B
+#define AT91C_PIO_PA28 (1 << 28) // Pin Controlled by PA28
+#define AT91C_PA28_DSR1 (AT91C_PIO_PA28) // USART 1 Data Set ready
+#define AT91C_PA28_TCLK1 (AT91C_PIO_PA28) // Timer Counter 1 external clock input
+#define AT91C_PIO_PA29 (1 << 29) // Pin Controlled by PA29
+#define AT91C_PA29_RI1 (AT91C_PIO_PA29) // USART 1 Ring Indicator
+#define AT91C_PA29_TCLK2 (AT91C_PIO_PA29) // Timer Counter 2 external clock input
+#define AT91C_PIO_PA30 (1 << 30) // Pin Controlled by PA30
+#define AT91C_PA30_IRQ1 (AT91C_PIO_PA30) // External Interrupt 1
+#define AT91C_PA30_NPCS2 (AT91C_PIO_PA30) // SPI Peripheral Chip Select 2
+#define AT91C_PIO_PA31 (1 << 31) // Pin Controlled by PA31
+#define AT91C_PA31_NPCS1 (AT91C_PIO_PA31) // SPI Peripheral Chip Select 1
+#define AT91C_PA31_PCK2 (AT91C_PIO_PA31) // PMC Programmable Clock Output 2
+
+// *****************************************************************************
+// PERIPHERAL ID DEFINITIONS FOR AT91SAM7S512
+// *****************************************************************************
+#define AT91C_ID_FIQ ( 0) // Advanced Interrupt Controller (FIQ)
+#define AT91C_ID_SYS ( 1) // System Peripheral
+#define AT91C_ID_PIOA ( 2) // Parallel IO Controller
+#define AT91C_ID_3_Reserved ( 3) // Reserved
+#define AT91C_ID_ADC ( 4) // Analog-to-Digital Converter
+#define AT91C_ID_SPI ( 5) // Serial Peripheral Interface
+#define AT91C_ID_US0 ( 6) // USART 0
+#define AT91C_ID_US1 ( 7) // USART 1
+#define AT91C_ID_SSC ( 8) // Serial Synchronous Controller
+#define AT91C_ID_TWI ( 9) // Two-Wire Interface
+#define AT91C_ID_PWMC (10) // PWM Controller
+#define AT91C_ID_UDP (11) // USB Device Port
+#define AT91C_ID_TC0 (12) // Timer Counter 0
+#define AT91C_ID_TC1 (13) // Timer Counter 1
+#define AT91C_ID_TC2 (14) // Timer Counter 2
+#define AT91C_ID_15_Reserved (15) // Reserved
+#define AT91C_ID_16_Reserved (16) // Reserved
+#define AT91C_ID_17_Reserved (17) // Reserved
+#define AT91C_ID_18_Reserved (18) // Reserved
+#define AT91C_ID_19_Reserved (19) // Reserved
+#define AT91C_ID_20_Reserved (20) // Reserved
+#define AT91C_ID_21_Reserved (21) // Reserved
+#define AT91C_ID_22_Reserved (22) // Reserved
+#define AT91C_ID_23_Reserved (23) // Reserved
+#define AT91C_ID_24_Reserved (24) // Reserved
+#define AT91C_ID_25_Reserved (25) // Reserved
+#define AT91C_ID_26_Reserved (26) // Reserved
+#define AT91C_ID_27_Reserved (27) // Reserved
+#define AT91C_ID_28_Reserved (28) // Reserved
+#define AT91C_ID_29_Reserved (29) // Reserved
+#define AT91C_ID_IRQ0 (30) // Advanced Interrupt Controller (IRQ0)
+#define AT91C_ID_IRQ1 (31) // Advanced Interrupt Controller (IRQ1)
+#define AT91C_ALL_INT (0xC0007FF7) // ALL VALID INTERRUPTS
+
+// *****************************************************************************
+// BASE ADDRESS DEFINITIONS FOR AT91SAM7S512
+// *****************************************************************************
+#define AT91C_BASE_SYS (AT91_CAST(AT91PS_SYS) 0xFFFFF000) // (SYS) Base Address
+#define AT91C_BASE_AIC (AT91_CAST(AT91PS_AIC) 0xFFFFF000) // (AIC) Base Address
+#define AT91C_BASE_PDC_DBGU (AT91_CAST(AT91PS_PDC) 0xFFFFF300) // (PDC_DBGU) Base Address
+#define AT91C_BASE_DBGU (AT91_CAST(AT91PS_DBGU) 0xFFFFF200) // (DBGU) Base Address
+#define AT91C_BASE_PIOA (AT91_CAST(AT91PS_PIO) 0xFFFFF400) // (PIOA) Base Address
+#define AT91C_BASE_CKGR (AT91_CAST(AT91PS_CKGR) 0xFFFFFC20) // (CKGR) Base Address
+#define AT91C_BASE_PMC (AT91_CAST(AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address
+#define AT91C_BASE_RSTC (AT91_CAST(AT91PS_RSTC) 0xFFFFFD00) // (RSTC) Base Address
+#define AT91C_BASE_RTTC (AT91_CAST(AT91PS_RTTC) 0xFFFFFD20) // (RTTC) Base Address
+#define AT91C_BASE_PITC (AT91_CAST(AT91PS_PITC) 0xFFFFFD30) // (PITC) Base Address
+#define AT91C_BASE_WDTC (AT91_CAST(AT91PS_WDTC) 0xFFFFFD40) // (WDTC) Base Address
+#define AT91C_BASE_VREG (AT91_CAST(AT91PS_VREG) 0xFFFFFD60) // (VREG) Base Address
+#define AT91C_BASE_EFC0 (AT91_CAST(AT91PS_EFC) 0xFFFFFF60) // (EFC0) Base Address
+#define AT91C_BASE_EFC1 (AT91_CAST(AT91PS_EFC) 0xFFFFFF70) // (EFC1) Base Address
+#define AT91C_BASE_MC (AT91_CAST(AT91PS_MC) 0xFFFFFF00) // (MC) Base Address
+#define AT91C_BASE_PDC_SPI (AT91_CAST(AT91PS_PDC) 0xFFFE0100) // (PDC_SPI) Base Address
+#define AT91C_BASE_SPI (AT91_CAST(AT91PS_SPI) 0xFFFE0000) // (SPI) Base Address
+#define AT91C_BASE_PDC_ADC (AT91_CAST(AT91PS_PDC) 0xFFFD8100) // (PDC_ADC) Base Address
+#define AT91C_BASE_ADC (AT91_CAST(AT91PS_ADC) 0xFFFD8000) // (ADC) Base Address
+#define AT91C_BASE_PDC_SSC (AT91_CAST(AT91PS_PDC) 0xFFFD4100) // (PDC_SSC) Base Address
+#define AT91C_BASE_SSC (AT91_CAST(AT91PS_SSC) 0xFFFD4000) // (SSC) Base Address
+#define AT91C_BASE_PDC_US1 (AT91_CAST(AT91PS_PDC) 0xFFFC4100) // (PDC_US1) Base Address
+#define AT91C_BASE_US1 (AT91_CAST(AT91PS_USART) 0xFFFC4000) // (US1) Base Address
+#define AT91C_BASE_PDC_US0 (AT91_CAST(AT91PS_PDC) 0xFFFC0100) // (PDC_US0) Base Address
+#define AT91C_BASE_US0 (AT91_CAST(AT91PS_USART) 0xFFFC0000) // (US0) Base Address
+#define AT91C_BASE_TWI (AT91_CAST(AT91PS_TWI) 0xFFFB8000) // (TWI) Base Address
+#define AT91C_BASE_TC0 (AT91_CAST(AT91PS_TC) 0xFFFA0000) // (TC0) Base Address
+#define AT91C_BASE_TC1 (AT91_CAST(AT91PS_TC) 0xFFFA0040) // (TC1) Base Address
+#define AT91C_BASE_TC2 (AT91_CAST(AT91PS_TC) 0xFFFA0080) // (TC2) Base Address
+#define AT91C_BASE_TCB (AT91_CAST(AT91PS_TCB) 0xFFFA0000) // (TCB) Base Address
+#define AT91C_BASE_PWMC_CH3 (AT91_CAST(AT91PS_PWMC_CH) 0xFFFCC260) // (PWMC_CH3) Base Address
+#define AT91C_BASE_PWMC_CH2 (AT91_CAST(AT91PS_PWMC_CH) 0xFFFCC240) // (PWMC_CH2) Base Address
+#define AT91C_BASE_PWMC_CH1 (AT91_CAST(AT91PS_PWMC_CH) 0xFFFCC220) // (PWMC_CH1) Base Address
+#define AT91C_BASE_PWMC_CH0 (AT91_CAST(AT91PS_PWMC_CH) 0xFFFCC200) // (PWMC_CH0) Base Address
+#define AT91C_BASE_PWMC (AT91_CAST(AT91PS_PWMC) 0xFFFCC000) // (PWMC) Base Address
+#define AT91C_BASE_UDP (AT91_CAST(AT91PS_UDP) 0xFFFB0000) // (UDP) Base Address
+
+// *****************************************************************************
+// MEMORY MAPPING DEFINITIONS FOR AT91SAM7S512
+// *****************************************************************************
+// ISRAM
+#define AT91C_ISRAM (0x00200000) // Internal SRAM base address
+#define AT91C_ISRAM_SIZE (0x00010000) // Internal SRAM size in byte (64 Kbytes)
+// IFLASH
+#define AT91C_IFLASH (0x00100000) // Internal FLASH base address
+#define AT91C_IFLASH_SIZE (0x00080000) // Internal FLASH size in byte (512 Kbytes)
+#define AT91C_IFLASH_PAGE_SIZE (256) // Internal FLASH Page Size: 256 bytes
+#define AT91C_IFLASH_LOCK_REGION_SIZE (16384) // Internal FLASH Lock Region Size: 16 Kbytes
+#define AT91C_IFLASH_NB_OF_PAGES (2048) // Internal FLASH Number of Pages: 2048 bytes
+#define AT91C_IFLASH_NB_OF_LOCK_BITS (32) // Internal FLASH Number of Lock Bits: 32 bytes
+
+#endif
diff --git a/mfkey/src/main/cpp/bucketsort.c b/mfkey/src/main/cpp/bucketsort.c
new file mode 100644
index 00000000..162869e3
--- /dev/null
+++ b/mfkey/src/main/cpp/bucketsort.c
@@ -0,0 +1,47 @@
+#include "bucketsort.h"
+
+extern void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,
+ uint32_t* const ostart, uint32_t* const ostop,
+ bucket_info_t *bucket_info, bucket_array_t bucket)
+{
+ uint32_t *p1, *p2;
+ uint32_t *start[2];
+ uint32_t *stop[2];
+
+ start[0] = estart;
+ stop[0] = estop;
+ start[1] = ostart;
+ stop[1] = ostop;
+
+ // init buckets to be empty
+ for (uint32_t i = 0; i < 2; i++) {
+ for (uint32_t j = 0x00; j <= 0xff; j++) {
+ bucket[i][j].bp = bucket[i][j].head;
+ }
+ }
+
+ // sort the lists into the buckets based on the MSB (contribution bits)
+ for (uint32_t i = 0; i < 2; i++) {
+ for (p1 = start[i]; p1 <= stop[i]; p1++) {
+ uint32_t bucket_index = (*p1 & 0xff000000) >> 24;
+ *(bucket[i][bucket_index].bp++) = *p1;
+ }
+ }
+
+ // write back intersecting buckets as sorted list.
+ // fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets.
+ uint32_t nonempty_bucket;
+ for (uint32_t i = 0; i < 2; i++) {
+ p1 = start[i];
+ nonempty_bucket = 0;
+ for (uint32_t j = 0x00; j <= 0xff; j++) {
+ if (bucket[0][j].bp != bucket[0][j].head && bucket[1][j].bp != bucket[1][j].head) { // non-empty intersecting buckets only
+ bucket_info->bucket_info[i][nonempty_bucket].head = p1;
+ for (p2 = bucket[i][j].head; p2 < bucket[i][j].bp; *p1++ = *p2++);
+ bucket_info->bucket_info[i][nonempty_bucket].tail = p1 - 1;
+ nonempty_bucket++;
+ }
+ }
+ bucket_info->numbuckets = nonempty_bucket;
+ }
+}
diff --git a/mfkey/src/main/cpp/bucketsort.h b/mfkey/src/main/cpp/bucketsort.h
new file mode 100644
index 00000000..be504508
--- /dev/null
+++ b/mfkey/src/main/cpp/bucketsort.h
@@ -0,0 +1,24 @@
+#ifndef BUCKETSORT_H__
+#define BUCKETSORT_H__
+
+#include
+#include
+
+typedef struct bucket {
+ uint32_t *head;
+ uint32_t *bp;
+} bucket_t;
+
+typedef bucket_t bucket_array_t[2][0x100];
+
+typedef struct bucket_info {
+ struct {
+ uint32_t *head, *tail;
+ } bucket_info[2][0x100];
+ uint32_t numbuckets;
+} bucket_info_t;
+
+void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,
+ uint32_t* const ostart, uint32_t* const ostop,
+ bucket_info_t *bucket_info, bucket_array_t bucket);
+#endif
\ No newline at end of file
diff --git a/mfkey/src/main/cpp/common.h b/mfkey/src/main/cpp/common.h
new file mode 100644
index 00000000..998db64d
--- /dev/null
+++ b/mfkey/src/main/cpp/common.h
@@ -0,0 +1,34 @@
+//-----------------------------------------------------------------------------
+// Hagen Fritsch - June 2010
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+
+//-----------------------------------------------------------------------------
+// Interlib Definitions
+//-----------------------------------------------------------------------------
+
+#ifndef __COMMON_H
+#define __COMMON_H
+
+#include
+#include
+#include
+#include
+typedef unsigned char byte_t;
+
+#ifndef MIN
+# define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+#ifndef MAX
+# define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef ABS
+# define ABS(a) ( ((a)<0) ? -(a) : (a) )
+#endif
+
+
+#define RAMFUNC __attribute((long_call, section(".ramfunc")))
+
+#endif
diff --git a/mfkey/src/main/cpp/crapto1.c b/mfkey/src/main/cpp/crapto1.c
new file mode 100644
index 00000000..282ea9db
--- /dev/null
+++ b/mfkey/src/main/cpp/crapto1.c
@@ -0,0 +1,541 @@
+/* crapto1.c
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, US$
+
+ Copyright (C) 2008-2014 bla
+*/
+#include "crapto1.h"
+
+#include
+#include "parity.h"
+#include "bucketsort.h"
+
+#if !defined LOWMEM && defined __GNUC__
+static uint8_t filterlut[1 << 20];
+static void __attribute__((constructor)) fill_lut()
+{
+ uint32_t i;
+ for(i = 0; i < 1 << 20; ++i)
+ filterlut[i] = filter(i);
+}
+#define filter(x) (filterlut[(x) & 0xfffff])
+#endif
+
+/** binsearch
+ * Binary search for the first occurence of *stop's MSB in sorted [start,stop]
+ */
+/* static inline uint32_t* binsearch(uint32_t *start, uint32_t *stop)
+{
+ uint32_t mid, val = *stop & 0xff000000;
+ while(start != stop)
+ if(start[mid = (stop - start) >> 1] > val)
+ stop = &start[mid];
+ else
+ start += mid + 1;
+
+ return start;
+}
+ */
+/** update_contribution
+ * helper, calculates the partial linear feedback contributions and puts in MSB
+ */
+static inline void update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2)
+{
+ uint32_t p = *item >> 25;
+
+ p = p << 1 | evenparity32(*item & mask1);
+ p = p << 1 | evenparity32(*item & mask2);
+ *item = p << 24 | (*item & 0xffffff);
+}
+
+/** extend_table
+ * using a bit of the keystream extend the table of possible lfsr states
+ */
+static inline void extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in)
+{
+ in <<= 24;
+ for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)
+ if(filter(*tbl) ^ filter(*tbl | 1)) {
+ *tbl |= filter(*tbl) ^ bit;
+ update_contribution(tbl, m1, m2);
+ *tbl ^= in;
+ } else if(filter(*tbl) == bit) {
+ *++*end = tbl[1];
+ tbl[1] = tbl[0] | 1;
+ update_contribution(tbl, m1, m2);
+ *tbl++ ^= in;
+ update_contribution(tbl, m1, m2);
+ *tbl ^= in;
+ } else
+ *tbl-- = *(*end)--;
+}
+/** extend_table_simple
+ * using a bit of the keystream extend the table of possible lfsr states
+ */
+static inline void extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)
+{
+ for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1) {
+ if(filter(*tbl) ^ filter(*tbl | 1)) { // replace
+ *tbl |= filter(*tbl) ^ bit;
+ } else if(filter(*tbl) == bit) { // insert
+ *++*end = *++tbl;
+ *tbl = tbl[-1] | 1;
+ } else { // drop
+ *tbl-- = *(*end)--;
+}
+ }
+}
+/** recover
+ * recursively narrow down the search space, 4 bits of keystream at a time
+ */
+static struct Crypto1State*
+recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
+ uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,
+ struct Crypto1State *sl, uint32_t in, bucket_array_t bucket)
+{
+ uint32_t *o, *e;
+ bucket_info_t bucket_info;
+
+ if(rem == -1) {
+ for(e = e_head; e <= e_tail; ++e) {
+ *e = *e << 1 ^ evenparity32(*e & LF_POLY_EVEN) ^ !!(in & 4);
+ for(o = o_head; o <= o_tail; ++o, ++sl) {
+ sl->even = *o;
+ sl->odd = *e ^ evenparity32(*o & LF_POLY_ODD);
+ sl[1].odd = sl[1].even = 0;
+ }
+ }
+ return sl;
+ }
+
+ for(uint32_t i = 0; i < 4 && rem--; i++) {
+ oks >>= 1;
+ eks >>= 1;
+ in >>= 2;
+ extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1, 0);
+ if(o_head > o_tail)
+ return sl;
+
+ extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD, LF_POLY_EVEN << 1 | 1, in & 3);
+ if(e_head > e_tail)
+ return sl;
+ }
+
+ bucket_sort_intersect(e_head, e_tail, o_head, o_tail, &bucket_info, bucket);
+
+ for (int i = bucket_info.numbuckets - 1; i >= 0; i--) {
+ sl = recover(bucket_info.bucket_info[1][i].head, bucket_info.bucket_info[1][i].tail, oks,
+ bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks,
+ rem, sl, in, bucket);
+ }
+
+ return sl;
+}
+/** lfsr_recovery
+ * recover the state of the lfsr given 32 bits of the keystream
+ * additionally you can use the in parameter to specify the value
+ * that was fed into the lfsr at the time the keystream was generated
+ */
+struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)
+{
+ struct Crypto1State *statelist;
+ uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;
+ uint32_t *even_head = 0, *even_tail = 0, eks = 0;
+ int i;
+
+ // split the keystream into an odd and even part
+ for (i = 31; i >= 0; i -= 2)
+ oks = oks << 1 | BEBIT(ks2, i);
+ for (i = 30; i >= 0; i -= 2)
+ eks = eks << 1 | BEBIT(ks2, i);
+
+ odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);
+ even_head = even_tail = malloc(sizeof(uint32_t) << 21);
+ statelist = malloc(sizeof(struct Crypto1State) << 18);
+ if (!odd_tail-- || !even_tail-- || !statelist) {
+ free(statelist);
+ statelist = 0;
+ goto out;
+ }
+
+ statelist->odd = statelist->even = 0;
+
+ // allocate memory for out of place bucket_sort
+ bucket_array_t bucket;
+
+ for (uint32_t i = 0; i < 2; i++) {
+ for (uint32_t j = 0; j <= 0xff; j++) {
+ bucket[i][j].head = malloc(sizeof(uint32_t) << 14);
+ if (!bucket[i][j].head) {
+ goto out;
+ }
+ }
+ }
+
+ // initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream
+ for(i = 1 << 20; i >= 0; --i) {
+ if(filter(i) == (oks & 1))
+ *++odd_tail = i;
+ if(filter(i) == (eks & 1))
+ *++even_tail = i;
+ }
+
+ // extend the statelists. Look at the next 8 Bits of the keystream (4 Bit each odd and even):
+ for(i = 0; i < 4; i++) {
+ extend_table_simple(odd_head, &odd_tail, (oks >>= 1) & 1);
+ extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);
+ }
+
+ // the statelists now contain all states which could have generated the last 10 Bits of the keystream.
+ // 22 bits to go to recover 32 bits in total. From now on, we need to take the "in"
+ // parameter into account.
+ in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00); // Byte swapping
+ recover(odd_head, odd_tail, oks, even_head, even_tail, eks, 11, statelist, in << 1, bucket);
+
+out:
+ for (uint32_t i = 0; i < 2; i++)
+ for (uint32_t j = 0; j <= 0xff; j++)
+ free(bucket[i][j].head);
+ free(odd_head);
+ free(even_head);
+ return statelist;
+}
+
+static const uint32_t S1[] = { 0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214,
+ 0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83,
+ 0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA};
+static const uint32_t S2[] = { 0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60,
+ 0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8,
+ 0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20,
+ 0x7EC7EE90, 0x7F63F748, 0x79117020};
+static const uint32_t T1[] = {
+ 0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66,
+ 0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B,
+ 0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615,
+ 0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C};
+static const uint32_t T2[] = { 0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0,
+ 0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268,
+ 0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0,
+ 0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0,
+ 0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950,
+ 0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0};
+static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD};
+static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0};
+/** Reverse 64 bits of keystream into possible cipher states
+ * Variation mentioned in the paper. Somewhat optimized version
+ */
+struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3)
+{
+ struct Crypto1State *statelist, *sl;
+ uint8_t oks[32], eks[32], hi[32];
+ uint32_t low = 0, win = 0;
+ uint32_t *tail, table[1 << 16];
+ int i, j;
+
+ sl = statelist = malloc(sizeof(struct Crypto1State) << 4);
+ if(!sl)
+ return 0;
+ sl->odd = sl->even = 0;
+
+ for(i = 30; i >= 0; i -= 2) {
+ oks[i >> 1] = BEBIT(ks2, i);
+ oks[16 + (i >> 1)] = BEBIT(ks3, i);
+ }
+ for(i = 31; i >= 0; i -= 2) {
+ eks[i >> 1] = BEBIT(ks2, i);
+ eks[16 + (i >> 1)] = BEBIT(ks3, i);
+ }
+
+ for(i = 0xfffff; i >= 0; --i) {
+ if (filter(i) != oks[0])
+ continue;
+
+ *(tail = table) = i;
+ for(j = 1; tail >= table && j < 29; ++j)
+ extend_table_simple(table, &tail, oks[j]);
+
+ if(tail < table)
+ continue;
+
+ for(j = 0; j < 19; ++j)
+ low = low << 1 | evenparity32(i & S1[j]);
+ for(j = 0; j < 32; ++j)
+ hi[j] = evenparity32(i & T1[j]);
+
+ for(; tail >= table; --tail) {
+ for(j = 0; j < 3; ++j) {
+ *tail = *tail << 1;
+ *tail |= evenparity32((i & C1[j]) ^ (*tail & C2[j]));
+ if(filter(*tail) != oks[29 + j])
+ goto continue2;
+ }
+
+ for(j = 0; j < 19; ++j)
+ win = win << 1 | evenparity32(*tail & S2[j]);
+
+ win ^= low;
+ for(j = 0; j < 32; ++j) {
+ win = win << 1 ^ hi[j] ^ evenparity32(*tail & T2[j]);
+ if(filter(win) != eks[j])
+ goto continue2;
+ }
+
+ *tail = *tail << 1 | evenparity32(LF_POLY_EVEN & *tail);
+ sl->odd = *tail ^ evenparity32(LF_POLY_ODD & win);
+ sl->even = win;
+ ++sl;
+ sl->odd = sl->even = 0;
+ continue2:;
+ }
+ }
+ return statelist;
+}
+
+/** lfsr_rollback_bit
+ * Rollback the shift register in order to get previous states
+ */
+uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)
+{
+ int out;
+ uint8_t ret;
+ uint32_t t;
+
+ s->odd &= 0xffffff;
+ t = s->odd, s->odd = s->even, s->even = t;
+
+ out = s->even & 1;
+ out ^= LF_POLY_EVEN & (s->even >>= 1);
+ out ^= LF_POLY_ODD & s->odd;
+ out ^= !!in;
+ out ^= (ret = filter(s->odd)) & !!fb;
+
+ s->even |= evenparity32(out) << 23;
+ return ret;
+}
+/** lfsr_rollback_byte
+ * Rollback the shift register in order to get previous states
+ */
+uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb)
+{
+ /*
+ int i, ret=0;
+ for (i = 7; i >= 0; --i)
+ ret |= lfsr_rollback_bit(s, BIT(in, i), fb) << i;
+*/
+// unfold loop 20160112
+ uint8_t ret = 0;
+ ret |= lfsr_rollback_bit(s, BIT(in, 7), fb) << 7;
+ ret |= lfsr_rollback_bit(s, BIT(in, 6), fb) << 6;
+ ret |= lfsr_rollback_bit(s, BIT(in, 5), fb) << 5;
+ ret |= lfsr_rollback_bit(s, BIT(in, 4), fb) << 4;
+ ret |= lfsr_rollback_bit(s, BIT(in, 3), fb) << 3;
+ ret |= lfsr_rollback_bit(s, BIT(in, 2), fb) << 2;
+ ret |= lfsr_rollback_bit(s, BIT(in, 1), fb) << 1;
+ ret |= lfsr_rollback_bit(s, BIT(in, 0), fb) << 0;
+ return ret;
+}
+/** lfsr_rollback_word
+ * Rollback the shift register in order to get previous states
+ */
+uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb)
+{
+ /*
+ int i;
+ uint32_t ret = 0;
+ for (i = 31; i >= 0; --i)
+ ret |= lfsr_rollback_bit(s, BEBIT(in, i), fb) << (i ^ 24);
+*/
+// unfold loop 20160112
+ uint32_t ret = 0;
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 31), fb) << (31 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 30), fb) << (30 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 29), fb) << (29 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 28), fb) << (28 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 27), fb) << (27 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 26), fb) << (26 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 25), fb) << (25 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 24), fb) << (24 ^ 24);
+
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 23), fb) << (23 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 22), fb) << (22 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 21), fb) << (21 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 20), fb) << (20 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 19), fb) << (19 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 18), fb) << (18 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 17), fb) << (17 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 16), fb) << (16 ^ 24);
+
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 15), fb) << (15 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 14), fb) << (14 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 13), fb) << (13 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 12), fb) << (12 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 11), fb) << (11 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 10), fb) << (10 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 9), fb) << (9 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 8), fb) << (8 ^ 24);
+
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 7), fb) << (7 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 6), fb) << (6 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 5), fb) << (5 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 4), fb) << (4 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 3), fb) << (3 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 2), fb) << (2 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 1), fb) << (1 ^ 24);
+ ret |= lfsr_rollback_bit(s, BEBIT(in, 0), fb) << (0 ^ 24);
+ return ret;
+}
+
+/** nonce_distance
+ * x,y valid tag nonces, then prng_successor(x, nonce_distance(x, y)) = y
+ */
+static uint16_t *dist = 0;
+int nonce_distance(uint32_t from, uint32_t to)
+{
+ uint16_t x, i;
+ if(!dist) {
+ dist = malloc(2 << 16);
+ if(!dist)
+ return -1;
+ for (x = i = 1; i; ++i) {
+ dist[(x & 0xff) << 8 | x >> 8] = i;
+ x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
+ }
+ }
+ return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;
+}
+
+/** validate_prng_nonce
+ * Determine if nonce is deterministic. ie: Suspectable to Darkside attack.
+ * returns
+ * true = weak prng
+ * false = hardend prng
+ */
+bool validate_prng_nonce(uint32_t nonce) {
+ // init prng table:
+ nonce_distance(nonce, nonce);
+ return ((65535 - dist[nonce >> 16] + dist[nonce & 0xffff]) % 65535) == 16;
+}
+
+static uint32_t fastfwd[2][8] = {
+ { 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},
+ { 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};
+
+/** lfsr_prefix_ks
+ *
+ * Is an exported helper function from the common prefix attack
+ * Described in the "dark side" paper. It returns an -1 terminated array
+ * of possible partial(21 bit) secret state.
+ * The required keystream(ks) needs to contain the keystream that was used to
+ * encrypt the NACK which is observed when varying only the 3 last bits of Nr
+ * only correct iff [NR_3] ^ NR_3 does not depend on Nr_3
+ */
+uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)
+{
+ uint32_t *candidates = malloc(4 << 10);
+ if (!candidates) return 0;
+
+ uint32_t c, entry;
+ int size = 0, i, good;
+
+ for (i = 0; i < 1 << 21; ++i) {
+ for (c = 0, good = 1; good && c < 8; ++c) {
+ entry = i ^ fastfwd[isodd][c];
+ good &= (BIT(ks[c], isodd) == filter(entry >> 1));
+ good &= (BIT(ks[c], isodd + 2) == filter(entry));
+ }
+ if (good)
+ candidates[size++] = i;
+ }
+
+ candidates[size] = -1;
+
+ return candidates;
+}
+
+/** check_pfx_parity
+ * helper function which eliminates possible secret states using parity bits
+ */
+static struct Crypto1State* check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8], uint32_t odd, uint32_t even, struct Crypto1State* sl, uint32_t no_par)
+{
+ uint32_t ks1, nr, ks2, rr, ks3, c, good = 1;
+
+ for(c = 0; good && c < 8; ++c) {
+ sl->odd = odd ^ fastfwd[1][c];
+ sl->even = even ^ fastfwd[0][c];
+
+ lfsr_rollback_bit(sl, 0, 0);
+ lfsr_rollback_bit(sl, 0, 0);
+
+ ks3 = lfsr_rollback_bit(sl, 0, 0);
+ ks2 = lfsr_rollback_word(sl, 0, 0);
+ ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1);
+
+ if (no_par)
+ break;
+
+ nr = ks1 ^ (prefix | c << 5);
+ rr = ks2 ^ rresp;
+
+ good &= evenparity32(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);
+ good &= evenparity32(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);
+ good &= evenparity32(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2, 8);
+ good &= evenparity32(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2, 0);
+ good &= evenparity32(rr & 0x000000ff) ^ parities[c][7] ^ ks3;
+ }
+
+ return sl + good;
+}
+
+
+/** lfsr_common_prefix
+ * Implentation of the common prefix attack.
+ * Requires the 28 bit constant prefix used as reader nonce (pfx)
+ * The reader response used (rr)
+ * The keystream used to encrypt the observed NACK's (ks)
+ * The parity bits (par)
+ * It returns a zero terminated list of possible cipher states after the
+ * tag nonce was fed in
+ */
+
+struct Crypto1State* lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint32_t no_par)
+{
+ struct Crypto1State *statelist, *s;
+ uint32_t *odd, *even, *o, *e, top;
+
+ odd = lfsr_prefix_ks(ks, 1);
+ even = lfsr_prefix_ks(ks, 0);
+
+ s = statelist = malloc((sizeof *statelist) << 24); // was << 20. Need more for no_par special attack. Enough???
+ if (!s || !odd || !even) {
+ free(statelist);
+ statelist = 0;
+ goto out;
+ }
+
+ for (o = odd; *o + 1; ++o)
+ for (e = even; *e + 1; ++e)
+ for (top = 0; top < 64; ++top) {
+ *o += 1 << 21;
+ *e += (!(top & 7) + 1) << 21;
+ s = check_pfx_parity(pfx, rr, par, *o, *e, s, no_par);
+ }
+
+ s->odd = s->even = 0;
+out:
+ free(odd);
+ free(even);
+ return statelist;
+}
diff --git a/mfkey/src/main/cpp/crapto1.h b/mfkey/src/main/cpp/crapto1.h
new file mode 100644
index 00000000..c941879c
--- /dev/null
+++ b/mfkey/src/main/cpp/crapto1.h
@@ -0,0 +1,84 @@
+/* crapto1.h
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, US$
+
+ Copyright (C) 2008-2014 bla
+*/
+#ifndef CRAPTO1_INCLUDED
+#define CRAPTO1_INCLUDED
+#include
+#include
+#include "bucketsort.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Crypto1State {uint32_t odd, even;};
+#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
+void crypto1_create(struct Crypto1State *s, uint64_t key);
+#else
+struct Crypto1State *crypto1_create(uint64_t key);
+#endif
+void crypto1_destroy(struct Crypto1State*);
+void crypto1_get_lfsr(struct Crypto1State*, uint64_t*);
+uint8_t crypto1_bit(struct Crypto1State*, uint8_t, int);
+uint8_t crypto1_byte(struct Crypto1State*, uint8_t, int);
+uint32_t crypto1_word(struct Crypto1State*, uint32_t, int);
+uint32_t prng_successor(uint32_t x, uint32_t n);
+
+struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in);
+struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3);
+uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd);
+struct Crypto1State*
+lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint32_t no_par);
+
+
+uint8_t lfsr_rollback_bit(struct Crypto1State* s, uint32_t in, int fb);
+uint8_t lfsr_rollback_byte(struct Crypto1State* s, uint32_t in, int fb);
+uint32_t lfsr_rollback_word(struct Crypto1State* s, uint32_t in, int fb);
+int nonce_distance(uint32_t from, uint32_t to);
+extern bool validate_prng_nonce(uint32_t nonce);
+#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\
+ uint32_t __n = 0,__M = 0, N = 0;\
+ int __i;\
+ for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\
+ for(__i = FSIZE - 1; __i >= 0; __i--)\
+ if(BIT(FILTER, __i) ^ evenparity32(__M & 0xFF01))\
+ break;\
+ else if(__i)\
+ __M = prng_successor(__M, (__i == 7) ? 48 : 8);\
+ else
+
+#define LF_POLY_ODD (0x29CE5C)
+#define LF_POLY_EVEN (0x870804)
+#define BIT(x, n) ((x) >> (n) & 1)
+#define BEBIT(x, n) BIT(x, (n) ^ 24)
+static inline int filter(uint32_t const x)
+{
+ uint32_t f;
+
+ f = 0xf22c0 >> (x & 0xf) & 16;
+ f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8;
+ f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4;
+ f |= 0x1e458 >> (x >> 12 & 0xf) & 2;
+ f |= 0x0d938 >> (x >> 16 & 0xf) & 1;
+ return BIT(0xEC57E80A, f);
+}
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/mfkey/src/main/cpp/crypto1.c b/mfkey/src/main/cpp/crypto1.c
new file mode 100644
index 00000000..bc0e7337
--- /dev/null
+++ b/mfkey/src/main/cpp/crypto1.c
@@ -0,0 +1,168 @@
+/* crypto1.c
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, US
+
+ Copyright (C) 2008-2008 bla
+*/
+#include "crapto1.h"
+
+#include
+#include "parity.h"
+
+#define SWAPENDIAN(x)\
+ (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
+
+#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
+void crypto1_create(struct Crypto1State *s, uint64_t key)
+{
+ int i;
+
+ for(i = 47;s && i > 0; i -= 2) {
+ s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
+ s->even = s->even << 1 | BIT(key, i ^ 7);
+ }
+ return;
+}
+void crypto1_destroy(struct Crypto1State *state)
+{
+ state->odd = 0;
+ state->even = 0;
+}
+#else
+struct Crypto1State * crypto1_create(uint64_t key)
+{
+ struct Crypto1State *s = malloc(sizeof(*s));
+ if ( !s ) return NULL;
+
+ s->odd = s->even = 0;
+
+ int i;
+ //for(i = 47;s && i > 0; i -= 2) {
+ for(i = 47; i > 0; i -= 2) {
+ s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
+ s->even = s->even << 1 | BIT(key, i ^ 7);
+ }
+ return s;
+}
+void crypto1_destroy(struct Crypto1State *state)
+{
+ free(state);
+}
+#endif
+void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr)
+{
+ int i;
+ for(*lfsr = 0, i = 23; i >= 0; --i) {
+ *lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
+ *lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
+ }
+}
+uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted)
+{
+ uint32_t feedin, t;
+ uint8_t ret = filter(s->odd);
+
+ feedin = ret & !!is_encrypted;
+ feedin ^= !!in;
+ feedin ^= LF_POLY_ODD & s->odd;
+ feedin ^= LF_POLY_EVEN & s->even;
+ s->even = s->even << 1 | evenparity32(feedin);
+
+ t = s->odd;
+ s->odd = s->even;
+ s->even = t;
+
+ return ret;
+}
+uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted)
+{
+ /*
+ uint8_t i, ret = 0;
+
+ for (i = 0; i < 8; ++i)
+ ret |= crypto1_bit(s, BIT(in, i), is_encrypted) << i;
+ */
+// unfold loop 20161012
+ uint8_t ret = 0;
+ ret |= crypto1_bit(s, BIT(in, 0), is_encrypted) << 0;
+ ret |= crypto1_bit(s, BIT(in, 1), is_encrypted) << 1;
+ ret |= crypto1_bit(s, BIT(in, 2), is_encrypted) << 2;
+ ret |= crypto1_bit(s, BIT(in, 3), is_encrypted) << 3;
+ ret |= crypto1_bit(s, BIT(in, 4), is_encrypted) << 4;
+ ret |= crypto1_bit(s, BIT(in, 5), is_encrypted) << 5;
+ ret |= crypto1_bit(s, BIT(in, 6), is_encrypted) << 6;
+ ret |= crypto1_bit(s, BIT(in, 7), is_encrypted) << 7;
+ return ret;
+}
+uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted)
+{
+ /*
+ uint32_t i, ret = 0;
+
+ for (i = 0; i < 32; ++i)
+ ret |= crypto1_bit(s, BEBIT(in, i), is_encrypted) << (i ^ 24);
+*/
+//unfold loop 2016012
+ uint32_t ret = 0;
+ ret |= crypto1_bit(s, BEBIT(in, 0), is_encrypted) << (0 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 1), is_encrypted) << (1 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 2), is_encrypted) << (2 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 3), is_encrypted) << (3 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 4), is_encrypted) << (4 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 5), is_encrypted) << (5 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 6), is_encrypted) << (6 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 7), is_encrypted) << (7 ^ 24);
+
+ ret |= crypto1_bit(s, BEBIT(in, 8), is_encrypted) << (8 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 9), is_encrypted) << (9 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 10), is_encrypted) << (10 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 11), is_encrypted) << (11 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 12), is_encrypted) << (12 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 13), is_encrypted) << (13 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 14), is_encrypted) << (14 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 15), is_encrypted) << (15 ^ 24);
+
+ ret |= crypto1_bit(s, BEBIT(in, 16), is_encrypted) << (16 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 17), is_encrypted) << (17 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 18), is_encrypted) << (18 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 19), is_encrypted) << (19 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 20), is_encrypted) << (20 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 21), is_encrypted) << (21 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 22), is_encrypted) << (22 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 23), is_encrypted) << (23 ^ 24);
+
+ ret |= crypto1_bit(s, BEBIT(in, 24), is_encrypted) << (24 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 25), is_encrypted) << (25 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 26), is_encrypted) << (26 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 27), is_encrypted) << (27 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 28), is_encrypted) << (28 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 29), is_encrypted) << (29 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 30), is_encrypted) << (30 ^ 24);
+ ret |= crypto1_bit(s, BEBIT(in, 31), is_encrypted) << (31 ^ 24);
+ return ret;
+}
+
+/* prng_successor
+ * helper used to obscure the keystream during authentication
+ */
+uint32_t prng_successor(uint32_t x, uint32_t n)
+{
+ SWAPENDIAN(x);
+ while(n--)
+ x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
+
+ return SWAPENDIAN(x);
+}
diff --git a/mfkey/src/main/cpp/mfkey.c b/mfkey/src/main/cpp/mfkey.c
new file mode 100644
index 00000000..b35a3104
--- /dev/null
+++ b/mfkey/src/main/cpp/mfkey.c
@@ -0,0 +1,173 @@
+//-----------------------------------------------------------------------------
+// Merlok - June 2011
+// Roel - Dec 2009
+// Unknown author
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// MIFARE Darkside hack
+//-----------------------------------------------------------------------------
+#include "mfkey.h"
+
+// MIFARE
+int compare_uint64(const void *a, const void *b) {
+ if (*(uint64_t*)b == *(uint64_t*)a) return 0;
+ if (*(uint64_t*)b < *(uint64_t*)a) return 1;
+ return -1;
+}
+
+// create the intersection (common members) of two sorted lists. Lists are terminated by -1. Result will be in list1. Number of elements is returned.
+uint32_t intersection(uint64_t *listA, uint64_t *listB) {
+ if (listA == NULL || listB == NULL)
+ return 0;
+
+ uint64_t *p1, *p2, *p3;
+ p1 = p3 = listA;
+ p2 = listB;
+
+ while ( *p1 != -1 && *p2 != -1 ) {
+ if (compare_uint64(p1, p2) == 0) {
+ *p3++ = *p1++;
+ p2++;
+ }
+ else {
+ while (compare_uint64(p1, p2) < 0) ++p1;
+ while (compare_uint64(p1, p2) > 0) ++p2;
+ }
+ }
+ *p3 = -1;
+ return p3 - listA;
+}
+
+// Darkside attack (hf mf mifare)
+// if successful it will return a list of keys, not just one.
+uint32_t nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint32_t ar, uint64_t par_info, uint64_t ks_info, uint64_t **keys) {
+ struct Crypto1State *states;
+ uint32_t i, pos;
+ uint8_t bt, ks3x[8], par[8][8];
+ uint64_t key_recovered;
+ uint64_t *keylist;
+
+ // Reset the last three significant bits of the reader nonce
+ nr &= 0xFFFFFF1F;
+
+ for ( pos = 0; pos < 8; pos++ ) {
+ ks3x[7-pos] = (ks_info >> (pos*8)) & 0x0F;
+ bt = (par_info >> (pos*8)) & 0xFF;
+
+ par[7-pos][0] = (bt >> 0) & 1;
+ par[7-pos][1] = (bt >> 1) & 1;
+ par[7-pos][2] = (bt >> 2) & 1;
+ par[7-pos][3] = (bt >> 3) & 1;
+ par[7-pos][4] = (bt >> 4) & 1;
+ par[7-pos][5] = (bt >> 5) & 1;
+ par[7-pos][6] = (bt >> 6) & 1;
+ par[7-pos][7] = (bt >> 7) & 1;
+ }
+
+ states = lfsr_common_prefix(nr, ar, ks3x, par, (par_info == 0));
+
+ if (!states) {
+ *keys = NULL;
+ return 0;
+ }
+
+ keylist = (uint64_t*)states;
+
+ for (i = 0; keylist[i]; i++) {
+ lfsr_rollback_word(states+i, uid ^ nt, 0);
+ crypto1_get_lfsr(states+i, &key_recovered);
+ keylist[i] = key_recovered;
+ }
+ keylist[i] = -1;
+
+ *keys = keylist;
+ return i;
+}
+
+// recover key from 2 different reader responses on same tag challenge
+bool mfkey32(nonces_t data, uint64_t *outputkey) {
+ struct Crypto1State *s,*t;
+ uint64_t outkey = 0;
+ uint64_t key = 0; // recovered key
+ bool isSuccess = false;
+ uint8_t counter = 0;
+
+ uint32_t p640 = prng_successor(data.nonce, 64);
+ uint32_t p641 = prng_successor(data.nonce2, 64);
+ s = lfsr_recovery32(data.ar ^ p640, 0);
+
+ for(t = s; t->odd | t->even; ++t) {
+ lfsr_rollback_word(t, 0, 0);
+ lfsr_rollback_word(t, data.nr, 1);
+ lfsr_rollback_word(t, data.cuid ^ data.nonce, 0);
+ crypto1_get_lfsr(t, &key);
+ crypto1_word(t, data.cuid ^ data.nonce, 0);
+ crypto1_word(t, data.nr2, 1);
+ if (data.ar2 == (crypto1_word(t, 0, 0) ^ p641)) {
+ outkey = key;
+ counter++;
+ if (counter == 20) break;
+ }
+ }
+ isSuccess = (counter == 1);
+ *outputkey = ( isSuccess ) ? outkey : 0;
+ crypto1_destroy(s);
+ return isSuccess;
+}
+
+// recover key from 2 reader responses on 2 different tag challenges
+// skip "several found keys". Only return true if ONE key is found
+bool mfkey32_moebius(nonces_t data, uint64_t *outputkey) {
+ struct Crypto1State *s, *t;
+ uint64_t outkey = 0;
+ uint64_t key = 0; // recovered key
+ bool isSuccess = false;
+ int counter = 0;
+ uint32_t p640 = prng_successor(data.nonce, 64);
+ uint32_t p641 = prng_successor(data.nonce2, 64);
+
+ s = lfsr_recovery32(data.ar ^ p640, 0);
+
+ for(t = s; t->odd | t->even; ++t) {
+ lfsr_rollback_word(t, 0, 0);
+ lfsr_rollback_word(t, data.nr, 1);
+ lfsr_rollback_word(t, data.cuid ^ data.nonce, 0);
+ crypto1_get_lfsr(t, &key);
+
+ crypto1_word(t, data.cuid ^ data.nonce2, 0);
+ crypto1_word(t, data.nr2, 1);
+ if (data.ar2 == (crypto1_word(t, 0, 0) ^ p641)) {
+ outkey = key;
+ ++counter;
+ if (counter == 20) break;
+ }
+ }
+ isSuccess = (counter == 1);
+ *outputkey = ( isSuccess ) ? outkey : 0;
+ crypto1_destroy(s);
+ return isSuccess;
+}
+
+// recover key from reader response and tag response of one authentication sequence
+int mfkey64(nonces_t data, uint64_t *outputkey){
+ uint64_t key = 0; // recovered key
+ uint32_t ks2; // keystream used to encrypt reader response
+ uint32_t ks3; // keystream used to encrypt tag response
+ struct Crypto1State *revstate;
+
+ // Extract the keystream from the messages
+ ks2 = data.ar ^ prng_successor(data.nonce, 64);
+ ks3 = data.at ^ prng_successor(data.nonce, 96);
+ revstate = lfsr_recovery64(ks2, ks3);
+ lfsr_rollback_word(revstate, 0, 0);
+ lfsr_rollback_word(revstate, 0, 0);
+ lfsr_rollback_word(revstate, data.nr, 1);
+ lfsr_rollback_word(revstate, data.cuid ^ data.nonce, 0);
+ crypto1_get_lfsr(revstate, &key);
+ crypto1_destroy(revstate);
+ *outputkey = key;
+ return 0;
+}
diff --git a/mfkey/src/main/cpp/mfkey.h b/mfkey/src/main/cpp/mfkey.h
new file mode 100644
index 00000000..24c49dd1
--- /dev/null
+++ b/mfkey/src/main/cpp/mfkey.h
@@ -0,0 +1,30 @@
+//-----------------------------------------------------------------------------
+// Merlok - June 2011
+// Roel - Dec 2009
+// Unknown author
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// MIFARE Darkside hack
+//-----------------------------------------------------------------------------
+
+#ifndef MFKEY_H
+#define MFKEY_H
+
+#include
+#include
+#include
+#include "mifare.h"
+#include "crapto1.h"
+
+extern uint32_t nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint32_t ar, uint64_t par_info, uint64_t ks_info, uint64_t **keys);
+extern bool mfkey32(nonces_t data, uint64_t *outputkey);
+extern bool mfkey32_moebius(nonces_t data, uint64_t *outputkey);
+extern int mfkey64(nonces_t data, uint64_t *outputkey);
+
+extern int compare_uint64(const void *a, const void *b);
+extern uint32_t intersection(uint64_t *listA, uint64_t *listB);
+
+#endif
diff --git a/mfkey/src/main/cpp/mfkey32.c b/mfkey/src/main/cpp/mfkey32.c
new file mode 100644
index 00000000..9393a4ad
--- /dev/null
+++ b/mfkey/src/main/cpp/mfkey32.c
@@ -0,0 +1,151 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include "crapto1.h"
+#include "mfkey.h"
+#include "util_posix.h"
+#include "tools.h"
+
+jstring
+decrypt4Ints(JNIEnv *env, jobject instance,
+ jint uid,
+ jint nt0,
+ jint nr0,
+ jint ar0,
+ jint nt1,
+ jint nr1,
+ jint ar1) {
+ nonces_t data = {0};
+ uint64_t key; // recovered key
+ //判断是否可以忽略nt0
+ bool moebius_attack = nt0 != nt1;
+ data.cuid = (uint32_t) uid;
+ data.nonce = (uint32_t) nt0;
+ data.nonce2 = data.nonce;
+ data.nr = (uint32_t) nr0;
+ data.ar = (uint32_t) ar0;
+ //注: 此处系命名规范问题,本人是从0下标命名!
+ if (moebius_attack) {
+ data.nonce2 = (uint32_t) nt1;
+ data.nr2 = (uint32_t) nr1;
+ data.ar2 = (uint32_t) ar1;
+ } else {
+ data.nr2 = (uint32_t) nr1;
+ data.ar2 = (uint32_t) ar1;
+ }
+ bool success;
+ if (moebius_attack) {
+ success = mfkey32_moebius(data, &key);
+ } else {
+ success = mfkey32(data, &key);
+ }
+ if (success) {
+ char ret[13] = {0};
+ sprintf(ret, "%012"PRIx64, key);
+ return (*env)->NewStringUTF(env, ret);
+ } else {
+ return NULL;
+ }
+}
+
+jstring
+decrypt4Strs(JNIEnv *env, jobject instance,
+ jstring uid,
+ jstring nt0,
+ jstring nr0,
+ jstring ar0,
+ jstring nt1,
+ jstring nr1,
+ jstring ar1) {
+ //先将字符串转换为HEX字符!
+ const char *uidChars = (*env)->GetStringUTFChars(env, uid, 0);
+ const char *nt0Chars = (*env)->GetStringUTFChars(env, nt0, 0);
+ const char *nr0Chars = (*env)->GetStringUTFChars(env, nr0, 0);
+ const char *ar0Chars = (*env)->GetStringUTFChars(env, ar0, 0);
+ const char *nt1Chars = (*env)->GetStringUTFChars(env, nt1, 0);
+ const char *nr1Chars = (*env)->GetStringUTFChars(env, nr1, 0);
+ const char *ar1Chars = (*env)->GetStringUTFChars(env, ar1, 0);
+
+ nonces_t data = {0};
+ uint64_t key; // recovered key
+
+ //判断两个字符串是否为相同,也就是两个随机数是否相同!
+ bool moebius_attack = strcmp(nt0Chars, nt1Chars) == 0;
+
+ sscanf(uidChars, "%x", &data.cuid);
+ sscanf(nt0Chars, "%x", &data.nonce);
+ data.nonce2 = data.nonce;
+ sscanf(nr0Chars, "%x", &data.nr);
+ sscanf(ar0Chars, "%x", &data.ar);
+ if (moebius_attack) {
+ sscanf(nt1Chars, "%x", &data.nonce2);
+ sscanf(nr1Chars, "%x", &data.nr2);
+ sscanf(ar1Chars, "%x", &data.ar2);
+ } else {
+ sscanf(nr1Chars, "%x", &data.nr2);
+ sscanf(ar1Chars, "%x", &data.ar2);
+ }
+
+ //TODO 谨记释放本地引用!避免栈溢出!
+ (*env)->ReleaseStringUTFChars(env, uid, uidChars);
+ (*env)->ReleaseStringUTFChars(env, nt0, nt0Chars);
+ (*env)->ReleaseStringUTFChars(env, nr0, nr0Chars);
+ (*env)->ReleaseStringUTFChars(env, ar0, ar0Chars);
+ (*env)->ReleaseStringUTFChars(env, nt1, nt1Chars);
+ (*env)->ReleaseStringUTFChars(env, nr1, nr1Chars);
+ (*env)->ReleaseStringUTFChars(env, ar1, ar1Chars);
+
+ bool success;
+ if (moebius_attack) {
+ success = mfkey32_moebius(data, &key);
+ } else {
+ success = mfkey32(data, &key);
+ }
+ if (success) {
+ char ret[13] = {0};
+ sprintf(ret, "%012"PRIx64, key);
+ return (*env)->NewStringUTF(env, ret);
+ } else {
+ return NULL;
+ }
+}
+
+/*
+ * jvm加载so时的映射回调
+ * */
+JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+ JNIEnv *jniEnv = NULL;
+ //得到当前的jvm环境指针
+ if ((*vm)->GetEnv(vm, (void **) &jniEnv, JNI_VERSION_1_4) != JNI_OK) {
+ return -1;
+ }
+ //初始化全局的jvm函数指针
+ (*jniEnv)->GetJavaVM(jniEnv, &g_JavaVM);
+ //得到native函数的定义类
+ jclass clazz = (*jniEnv)->FindClass(jniEnv, "com/dxl/mfkey/NativeMfKey32");
+ if (clazz == NULL) {
+ return -1;
+ }
+ //构建和初始化函数结构体,分别是java层的函数名称,签名,对应的函数指针
+ JNINativeMethod methods[] = {
+ {"decrypt4IntParams", "(IIIIIII)Ljava/lang/String;", (void *) decrypt4Ints},
+ {"decrypt4StrParams", "(Ljava/lang/String;"
+ "Ljava/lang/String;"
+ "Ljava/lang/String;"
+ "Ljava/lang/String;"
+ "Ljava/lang/String;"
+ "Ljava/lang/String;"
+ "Ljava/lang/String;)"
+ "Ljava/lang/String;", (void *) decrypt4Strs}
+ };
+ //注册函数
+ if ((*jniEnv)->RegisterNatives(jniEnv, clazz, methods, sizeof(methods) / sizeof(methods[0])) !=
+ JNI_OK) {
+ return -1;
+ }
+ //最后一定要返回jni的版本。
+ return JNI_VERSION_1_4;
+}
diff --git a/mfkey/src/main/cpp/mfkey32v2.c b/mfkey/src/main/cpp/mfkey32v2.c
new file mode 100644
index 00000000..4206a91e
--- /dev/null
+++ b/mfkey/src/main/cpp/mfkey32v2.c
@@ -0,0 +1,184 @@
+#include
+#include "crapto1.h"
+#include
+#include
+#include
+#include
+
+
+uint64_t recoveryKey4Int(uint32_t uid, // serial number
+ uint32_t nt0, // tag challenge first
+ uint32_t nt1, // tag challenge second
+ uint32_t nr0_enc, // first encrypted reader challenge
+ uint32_t ar0_enc, // first encrypted reader response
+ uint32_t nr1_enc, // second encrypted reader challenge
+ uint32_t ar1_enc,// second encrypted reader response
+ bool *isSuccess // recovery result.
+) {
+ struct Crypto1State *s, *t;
+ uint64_t key = 0; // recovered key
+ //uint32_t ks2; // keystream used to encrypt reader response
+
+ // LOGD("Recovering key for:\n");
+ // LOGD(" uid: %08x\n", uid);
+ // LOGD(" nt_0: %08x\n", nt0);
+ // LOGD(" {nr_0}: %08x\n", nr0_enc);
+ // LOGD(" {ar_0}: %08x\n", ar0_enc);
+ // LOGD(" nt_1: %08x\n", nt1);
+ // LOGD(" {nr_1}: %08x\n", nr1_enc);
+ // LOGD(" {ar_1}: %08x\n", ar1_enc);
+
+ // Generate lfsr succesors of the tag challenge
+ //LOGD("\nLFSR succesors of the tag challenge:\n");
+ uint32_t p64 = prng_successor(nt0, 64);
+ uint32_t p64b = prng_successor(nt1, 64);
+
+ //LOGD(" nt': %08x\n", p64);
+ //LOGD(" nt'': %08x\n", prng_successor(p64, 32));
+
+ // Extract the keystream from the messages
+ //LOGD("\nKeystream used to generate {ar} and {at}:\n");
+ //ks2 = ar0_enc ^ p64;
+ //LOGD(" ks2: %08x\n", ks2);
+
+ s = lfsr_recovery32(ar0_enc ^ p64, 0);
+
+ for (t = s; t->odd | t->even; ++t) {
+ lfsr_rollback_word(t, 0, 0);
+ lfsr_rollback_word(t, nr0_enc, 1);
+ lfsr_rollback_word(t, uid ^ nt0, 0);
+ crypto1_get_lfsr(t, &key);
+
+ crypto1_word(t, uid ^ nt1, 0);
+ crypto1_word(t, nr1_enc, 1);
+ if (ar1_enc == (crypto1_word(t, 0, 0) ^ p64b)) {
+ LOGD("\nFound Key: [%012"
+ PRIx64
+ "]\n\n", key);
+ *isSuccess = true;
+ break;
+ }
+ }
+ free(s);
+ return key;
+}
+
+uint64_t recoveryKey(const char *argv[], bool *isSuccess) {
+ //struct Crypto1State *s, *t;
+ //uint64_t key; // recovered key
+ uint32_t uid; // serial number
+ uint32_t nt0; // tag challenge first
+ uint32_t nt1; // tag challenge second
+ uint32_t nr0_enc; // first encrypted reader challenge
+ uint32_t ar0_enc; // first encrypted reader response
+ uint32_t nr1_enc; // second encrypted reader challenge
+ uint32_t ar1_enc; // second encrypted reader response
+ //uint32_t ks2; // keystream used to encrypt reader response
+
+ sscanf(argv[1], "%x", &uid);
+ sscanf(argv[2], "%x", &nt0);
+ sscanf(argv[3], "%x", &nr0_enc);
+ sscanf(argv[4], "%x", &ar0_enc);
+ sscanf(argv[5], "%x", &nt1);
+ sscanf(argv[6], "%x", &nr1_enc);
+ sscanf(argv[7], "%x", &ar1_enc);
+
+ return recoveryKey4Int(uid, nt0, nt1, nr0_enc, ar0_enc, nr1_enc, ar1_enc, isSuccess);
+}
+
+jstring
+decrypt4Ints(JNIEnv *env, jobject instance,
+ jint uid,
+ jint nt0,
+ jint nr0,
+ jint ar0,
+ jint nt1,
+ jint nr1,
+ jint ar1) {
+ bool isSuccess = false;
+ uint64_t key = recoveryKey4Int((uint32_t) uid, (uint32_t) nt0, (uint32_t) nt1, (uint32_t) nr0,
+ (uint32_t) ar0, (uint32_t) nr1, (uint32_t) ar1, &isSuccess);
+ if (isSuccess) {
+ char ret[13] = {0};
+ sprintf(ret, "%012"PRIx64, key);
+ return (*env)->NewStringUTF(env, ret);
+ } else {
+ return NULL;
+ }
+}
+
+jstring
+decrypt4Strs(JNIEnv *env, jobject instance,
+ jstring uid,
+ jstring nt0,
+ jstring nr0,
+ jstring ar0,
+ jstring nt1,
+ jstring nr1,
+ jstring ar1) {
+ //先将字符串转换为HEX字符!
+ const char *uidChars = (*env)->GetStringUTFChars(env, uid, 0);
+ const char *nt0Chars = (*env)->GetStringUTFChars(env, nt0, 0);
+ const char *nr0Chars = (*env)->GetStringUTFChars(env, nr0, 0);
+ const char *ar0Chars = (*env)->GetStringUTFChars(env, ar0, 0);
+ const char *nt1Chars = (*env)->GetStringUTFChars(env, nt1, 0);
+ const char *nr1Chars = (*env)->GetStringUTFChars(env, nr1, 0);
+ const char *ar1Chars = (*env)->GetStringUTFChars(env, ar1, 0);
+
+ const char *array[] = {
+ uidChars,
+ nt0Chars,
+ nr0Chars,
+ ar0Chars,
+ nt1Chars,
+ nr1Chars,
+ ar1Chars
+ };
+
+ bool isSuccess = false;
+ uint64_t key = recoveryKey(array, &isSuccess);
+ if (isSuccess) {
+ char ret[13] = {0};
+ sprintf(ret, "%012"PRIx64, key);
+ return (*env)->NewStringUTF(env, ret);
+ } else {
+ return NULL;
+ }
+}
+
+/*
+ * jvm加载so时的映射回调
+ * */
+JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+ JNIEnv *jniEnv = NULL;
+//得到当前的jvm环境指针
+ if ((*vm)->GetEnv(vm, (void **) &jniEnv, JNI_VERSION_1_4) != JNI_OK) {
+ return -1;
+ }
+//初始化全局的jvm函数指针
+ (*jniEnv)->GetJavaVM(jniEnv, &g_JavaVM);
+//得到native函数的定义类
+ jclass clazz = (*jniEnv)->FindClass(jniEnv, "com/dxl/mfkey/NativeMfKey32V2");
+ if (clazz == NULL) {
+ return -1;
+ }
+//构建和初始化函数结构体,分别是java层的函数名称,签名,对应的函数指针
+ JNINativeMethod methods[] = {
+ {"decrypt4IntParams", "(IIIIIII)Ljava/lang/String;", (void *) decrypt4Ints},
+ {"decrypt4StrParams", "(Ljava/lang/String;"
+ "Ljava/lang/String;"
+ "Ljava/lang/String;"
+ "Ljava/lang/String;"
+ "Ljava/lang/String;"
+ "Ljava/lang/String;"
+ "Ljava/lang/String;)"
+ "Ljava/lang/String;", (void *) decrypt4Strs}
+ };
+//注册函数
+ if ((*jniEnv)->RegisterNatives(jniEnv, clazz, methods, sizeof(methods) / sizeof(methods[0])) !=
+ JNI_OK) {
+ return -1;
+ }
+//最后一定要返回jni的版本。
+ return JNI_VERSION_1_4;
+}
diff --git a/mfkey/src/main/cpp/mfkey64.c b/mfkey/src/main/cpp/mfkey64.c
new file mode 100644
index 00000000..d232aa01
--- /dev/null
+++ b/mfkey/src/main/cpp/mfkey64.c
@@ -0,0 +1,127 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include "crapto1.h"
+#include "tools.h"
+#include "util_posix.h"
+
+int main64(int argc, char *argv[]) {
+ uint32_t uid; // serial numDber
+ uint32_t nt; // tag challenge
+ uint32_t nr_enc; // encrypted reader challenge
+ uint32_t ar_enc; // encrypted reader response
+ uint32_t at_enc; // encrypted tag response
+ uint64_t key = 0; // recovered key
+ struct Crypto1State *revstate;
+ uint32_t ks2; // keystream used to encrypt reader response
+ uint32_t ks3; // keystream used to encrypt tag response
+
+ printf("MIFARE Classic key recovery - based on 64 bits of keystream\n");
+ printf("Recover key from only one complete authentication!\n\n");
+
+ if (argc < 6) {
+ printf(" syntax: %s <{nr}> <{ar}> <{at}> [enc] [enc...]\n\n", argv[0]);
+ return 1;
+ }
+
+ int encc = argc - 6;
+ int enclen[encc];
+ uint8_t enc[encc][120];
+
+ sscanf(argv[1], "%x", &uid);
+ sscanf(argv[2], "%x", &nt);
+ sscanf(argv[3], "%x", &nr_enc);
+ sscanf(argv[4], "%x", &ar_enc);
+ sscanf(argv[5], "%x", &at_enc);
+ for (int i = 0; i < encc; i++) {
+ enclen[i] = strlen(argv[i + 6]) / 2;
+ for (int i2 = 0; i2 < enclen[i]; i2++) {
+ sscanf(argv[i + 6] + i2 * 2, "%2x", (unsigned int *) &enc[i][i2]);
+ }
+ }
+
+ printf("Recovering key for:\n");
+ printf(" uid: %08x\n", uid);
+ printf(" nt: %08x\n", nt);
+ printf(" {nr}: %08x\n", nr_enc);
+ printf(" {ar}: %08x\n", ar_enc);
+ printf(" {at}: %08x\n", at_enc);
+ for (int i = 0; i < encc; i++) {
+ printf("{enc%d}: ", i);
+ for (int i2 = 0; i2 < enclen[i]; i2++) {
+ printf("%02x", enc[i][i2]);
+ }
+ printf("\n");
+ }
+
+ printf("\nLFSR successors of the tag challenge:\n");
+ printf(" nt' : %08x\n", prng_successor(nt, 64));
+ printf(" nt'': %08x\n", prng_successor(nt, 96));
+
+ // Extract the keystream from the messages
+ ks2 = ar_enc ^ prng_successor(nt, 64);
+ ks3 = at_enc ^ prng_successor(nt, 96);
+
+ uint64_t start_time = msclock();
+ revstate = lfsr_recovery64(ks2, ks3);
+ uint64_t time_spent = msclock() - start_time;
+ printf("Time spent in lfsr_recovery64(): %1.2f seconds\n", (float) time_spent / 1000.0);
+ printf("\nKeystream used to generate {ar} and {at}:\n");
+ printf(" ks2: %08x\n", ks2);
+ printf(" ks3: %08x\n", ks3);
+
+ // Decrypting communication using keystream if presented
+ if (argc > 6) {
+ printf("\nDecrypted communication:\n");
+ uint8_t ks4;
+ int rollb = 0;
+ for (int i = 0; i < encc; i++) {
+ printf("{dec%d}: ", i);
+ for (int i2 = 0; i2 < enclen[i]; i2++) {
+ ks4 = crypto1_byte(revstate, 0, 0);
+ printf("%02x", ks4 ^ enc[i][i2]);
+ rollb += 1;
+ }
+ printf("\n");
+ }
+ for (int i = 0; i < rollb; i++) {
+ lfsr_rollback_byte(revstate, 0, 0);
+ }
+ }
+
+ lfsr_rollback_word(revstate, 0, 0);
+ lfsr_rollback_word(revstate, 0, 0);
+ lfsr_rollback_word(revstate, nr_enc, 1);
+ lfsr_rollback_word(revstate, uid ^ nt, 0);
+ crypto1_get_lfsr(revstate, &key);
+ crypto1_destroy(revstate);
+
+ printf("\nFound Key: [%012" PRIx64"]\n\n", key);
+
+}
+
+/*
+ * jvm加载so时的映射回调
+ * */
+JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+ /*JNIEnv *jniEnv = NULL;
+ if ((*vm)->GetEnv(vm, (void **) &jniEnv, JNI_VERSION_1_4) != JNI_OK) {
+ return -1;
+ }
+ (*jniEnv)->GetJavaVM(jniEnv, &g_JavaVM);
+ jclass clazz = (*jniEnv)->FindClass(jniEnv, "com/dxl/mfkey/NativeMfKey64");
+ if (clazz == NULL) {
+ return -1;
+ }
+ JNINativeMethod methods[] = {
+ {"startExecute", "(Ljava/lang/String;)I", (void *) startExecute},
+ };
+ if ((*jniEnv)->RegisterNatives(jniEnv, clazz, methods, sizeof(methods) / sizeof(methods[0])) !=
+ JNI_OK) {
+ return -1;
+ }*/
+ return JNI_VERSION_1_4;
+}
\ No newline at end of file
diff --git a/mfkey/src/main/cpp/mifare.h b/mfkey/src/main/cpp/mifare.h
new file mode 100644
index 00000000..2ab7e374
--- /dev/null
+++ b/mfkey/src/main/cpp/mifare.h
@@ -0,0 +1,153 @@
+//-----------------------------------------------------------------------------
+// (c) 2012 Roel Verdult
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// MIFARE type prototyping
+//-----------------------------------------------------------------------------
+
+#ifndef _MIFARE_H_
+#define _MIFARE_H_
+
+#include "common.h"
+
+//-----------------------------------------------------------------------------
+// ISO 14443A
+//-----------------------------------------------------------------------------
+typedef struct {
+ byte_t uid[10];
+ byte_t uidlen;
+ byte_t atqa[2];
+ byte_t sak;
+ byte_t ats_len;
+ byte_t ats[256];
+} __attribute__((__packed__)) iso14a_card_select_t;
+
+typedef enum ISO14A_COMMAND {
+ ISO14A_CONNECT = (1 << 0),
+ ISO14A_NO_DISCONNECT = (1 << 1),
+ ISO14A_APDU = (1 << 2),
+ ISO14A_RAW = (1 << 3),
+ ISO14A_REQUEST_TRIGGER = (1 << 4),
+ ISO14A_APPEND_CRC = (1 << 5),
+ ISO14A_SET_TIMEOUT = (1 << 6),
+ ISO14A_NO_SELECT = (1 << 7),
+ ISO14A_TOPAZMODE = (1 << 8),
+ ISO14A_NO_RATS = (1 << 9)
+} iso14a_command_t;
+
+typedef struct {
+ uint8_t* response;
+ size_t response_n;
+ uint8_t* modulation;
+ size_t modulation_n;
+ uint32_t ProxToAirDuration;
+} tag_response_info_t;
+//-----------------------------------------------------------------------------
+// ISO 14443B
+//-----------------------------------------------------------------------------
+typedef struct {
+ byte_t uid[10];
+ byte_t uidlen;
+ byte_t atqb[7];
+ byte_t chipid;
+ byte_t cid;
+} __attribute__((__packed__)) iso14b_card_select_t;
+
+typedef enum ISO14B_COMMAND {
+ ISO14B_CONNECT = (1 << 0),
+ ISO14B_DISCONNECT = (1 << 1),
+ ISO14B_APDU = (1 << 2),
+ ISO14B_RAW = (1 << 3),
+ ISO14B_REQUEST_TRIGGER = (1 << 4),
+ ISO14B_APPEND_CRC = (1 << 5),
+ ISO14B_SELECT_STD = (1 << 6),
+ ISO14B_SELECT_SR = (1 << 7)
+} iso14b_command_t;
+
+typedef enum ISO15_COMMAND {
+ ISO15_CONNECT = (1 << 0),
+ ISO15_NO_DISCONNECT = (1 << 1),
+ ISO15_RAW = (1 << 2),
+ ISO15_APPEND_CRC = (1 << 3),
+ ISO15_HIGH_SPEED = (1 << 4),
+ ISO15_READ_RESPONSE = (1 << 5)
+} iso15_command_t;
+
+//-----------------------------------------------------------------------------
+// "hf 14a sim x", "hf mf sim x" attacks
+//-----------------------------------------------------------------------------
+typedef struct {
+ uint32_t cuid;
+ uint32_t nonce;
+ uint32_t ar;
+ uint32_t nr;
+ uint32_t at;
+ uint32_t nonce2;
+ uint32_t ar2;
+ uint32_t nr2;
+ uint8_t sector;
+ uint8_t keytype;
+ enum {
+ EMPTY,
+ FIRST,
+ SECOND,
+ } state;
+} nonces_t;
+
+//-----------------------------------------------------------------------------
+// ISO 7618 Smart Card
+//-----------------------------------------------------------------------------
+typedef struct {
+ uint8_t atr_len;
+ uint8_t atr[30];
+} __attribute__((__packed__)) smart_card_atr_t;
+
+typedef enum SMARTCARD_COMMAND {
+ SC_CONNECT = (1 << 0),
+ SC_NO_DISCONNECT = (1 << 1),
+ SC_RAW = (1 << 2),
+ SC_NO_SELECT = (1 << 3)
+} smartcard_command_t;
+
+//-----------------------------------------------------------------------------
+// FeliCa
+//-----------------------------------------------------------------------------
+// IDm = ID manufacturer
+// mc = manufactureCode
+// mc1 mc2 u1 u2 u3 u4 u5 u6
+// PMm = Product manufacturer
+// icCode =
+// ic1 = ROM
+// ic2 = IC
+// maximum response time =
+// B3(request service)
+// B4(request response)
+// B5(authenticate)
+// B6(read)
+// B7(write)
+// B8()
+
+// ServiceCode 2bytes (access-rights)
+// FileSystem = 1 Block = 16 bytes
+typedef struct {
+ uint8_t IDm[8];
+ uint8_t code[2];
+ uint8_t uid[6];
+ uint8_t PMm[8];
+ uint8_t iccode[2];
+ uint8_t mrt[6];
+ uint8_t servicecode[2];
+} __attribute__((__packed__)) felica_card_select_t;
+
+typedef enum FELICA_COMMAND {
+ FELICA_CONNECT = (1 << 0),
+ FELICA_NO_DISCONNECT = (1 << 1),
+ FELICA_RAW = (1 << 3),
+ FELICA_APPEND_CRC = (1 << 5),
+ FELICA_NO_SELECT = (1 << 6),
+} felica_command_t;
+
+#endif // _MIFARE_H_
diff --git a/mfkey/src/main/cpp/parity.c b/mfkey/src/main/cpp/parity.c
new file mode 100644
index 00000000..cd997ceb
--- /dev/null
+++ b/mfkey/src/main/cpp/parity.c
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------------
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// parity functions (all defined in parity.h)
+//-----------------------------------------------------------------------------
+#include
+#include
+
+const uint8_t OddByteParity[256] = {
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
+};
+
+const uint8_t EvenByteParity[256] = {
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
+};
+
diff --git a/mfkey/src/main/cpp/parity.h b/mfkey/src/main/cpp/parity.h
new file mode 100644
index 00000000..fe1c2504
--- /dev/null
+++ b/mfkey/src/main/cpp/parity.h
@@ -0,0 +1,61 @@
+//-----------------------------------------------------------------------------
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// Parity functions
+//-----------------------------------------------------------------------------
+
+// all functions defined in header file by purpose. Allows compiler optimizations.
+
+#ifndef __PARITY_H
+#define __PARITY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include
+
+extern const uint8_t OddByteParity[256];
+
+
+static inline bool oddparity8(const uint8_t x) {
+ return OddByteParity[x];
+}
+
+
+static inline bool evenparity8(const uint8_t x) {
+ return !OddByteParity[x];
+}
+
+
+static inline bool evenparity32(uint32_t x)
+{
+#if !defined __GNUC__
+ x ^= x >> 16;
+ x ^= x >> 8;
+ return evenparity8(x);
+#else
+ return __builtin_parity(x);
+#endif
+}
+
+
+static inline bool oddparity32(uint32_t x)
+{
+#if !defined __GNUC__
+ x ^= x >> 16;
+ x ^= x >> 8;
+ return oddparity8(x);
+#else
+ return !__builtin_parity(x);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PARITY_H */
diff --git a/mfkey/src/main/cpp/tools.c b/mfkey/src/main/cpp/tools.c
new file mode 100644
index 00000000..67585bc1
--- /dev/null
+++ b/mfkey/src/main/cpp/tools.c
@@ -0,0 +1,105 @@
+//
+// Created by DXL on 2017/9/1.
+//
+
+//including header
+#include
+#include
+#include "stdbool.h"
+
+//当前线程是否添加的标志位
+static bool g_IsAttach;
+
+//TODO 环境变量获取函数
+JNIEnv *getJniEnv() {
+ JNIEnv *currentThreadEnv;
+ g_IsAttach = false;
+ if ((*g_JavaVM)->GetEnv(g_JavaVM, (void **) ¤tThreadEnv, JNI_VERSION_1_4) != JNI_OK) {
+ LOGE("Get Env Fail!");
+ if ((*g_JavaVM)->AttachCurrentThread(g_JavaVM, ¤tThreadEnv, NULL) != JNI_OK) {
+ LOGE("Attach the current thread Fail!");
+ g_IsAttach = false;
+ return NULL;
+ } else {
+ g_IsAttach = true;
+ LOGE("Attach the current thread Success!");
+ return currentThreadEnv;
+ }
+ } else {
+ g_IsAttach = false;
+ //LOGE("Get Env Success!");
+ return currentThreadEnv;
+ }
+}
+
+//解绑线程env
+void deatchThread() {
+ if (g_IsAttach) {
+ LOGD("线程解绑成功!");
+ (*g_JavaVM)->DetachCurrentThread(g_JavaVM);
+ }
+}
+
+//TODO 命令行解析
+CMD *parse_command_line(const char *commandStr) {
+ //一个指针,指向传进来的命令字符串(const修饰的,我们需要复刻一份!)
+ CMD *cmd = (CMD *) malloc(sizeof(CMD));
+ if (!cmd) {
+ LOGD("申请空间失败!");
+ return NULL;
+ }
+ //拷贝字符串到堆空间!
+ char *pTmp = strdup(commandStr);
+ LOGD("拷贝参数字符串到临时堆!");
+ //返回的结果!先初始化为20个空间
+ int size = 20;
+ cmd->cmd = (char **) malloc(size * sizeof(char **));
+ if (cmd->cmd) {
+ LOGD("申请参数空间成功!");
+ } else {
+ LOGD("申请空间失败!");
+ }
+ //进行截取
+ char *pStr = strtok(pTmp, " ");
+ LOGD("第0次截取完成: %s", pStr);
+ //给结果数组进行下标为0的第一次初始化
+ cmd->cmd[0] = pStr;
+ //局部变量用于储存解析到的命令个数,下标移动为一
+ int count = 1;
+ //需要截取命令参数,以空格为限定符
+ for (; pStr != NULL; ++count) {
+ //如果容量不够,则扩容!
+ if (count == (size - 1)) {
+ size += 20;
+ cmd->cmd = (char **) realloc(cmd->cmd, size * sizeof(char **));
+ LOGD("超过初始容量,自动扩容!");
+ }
+ pStr = strtok(NULL, " ");
+ if (pStr) {
+ cmd->cmd[count] = pStr;
+ LOGD("第%d次截取完成: %s", count, pStr);
+ }
+ }
+ cmd->len = (count - 1);
+ LOGD("解析函数执行完成!");
+ return cmd;
+}
+
+//内存释放
+void free_command_line(CMD *cmd) {
+ //二级指针需要逐层释放!
+ LOGD("释放命令行字符串二级引用!");
+ free(cmd->cmd[0]);
+ LOGD("释放命令行一级引用!");
+ free(cmd->cmd);
+ LOGD("释放结构体内存");
+ free(cmd);
+}
+
+//重置getopt函数的参数
+void recovery_getopt_opt() {
+ optind = 0;
+ opterr = 1;
+ optopt = 0;
+ optarg = NULL;
+}
\ No newline at end of file
diff --git a/mfkey/src/main/cpp/tools.h b/mfkey/src/main/cpp/tools.h
new file mode 100644
index 00000000..c9274f59
--- /dev/null
+++ b/mfkey/src/main/cpp/tools.h
@@ -0,0 +1,44 @@
+//
+// Created by dell on 2017/9/1.
+//
+
+#ifndef DXL_TOOLS_H
+#define DXL_TOOLS_H
+
+#include
+#include
+#include
+#include
+
+//JNI LOG
+#define TAG "DXL"
+#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE,TAG,__VA_ARGS__)
+#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__)
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__)
+#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG,__VA_ARGS__)
+#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__)
+
+//全局的环境变量定义
+JavaVM *g_JavaVM;
+
+//线程环境指针获取函数
+JNIEnv *getJniEnv();
+
+//子线程释放函数,必须是native层创建的线程才可以调用
+void deatchThread();
+
+typedef struct {
+ char **cmd;
+ int len;
+} CMD;
+
+//命令行解析函数
+CMD *parse_command_line(const char *commandStr);
+
+//解析结果释放函数!
+void free_command_line(CMD *);
+
+//重置getopt函数
+void recovery_getopt_opt();
+
+#endif //DXL_TOOLS_H
\ No newline at end of file
diff --git a/mfkey/src/main/cpp/util_posix.c b/mfkey/src/main/cpp/util_posix.c
new file mode 100644
index 00000000..7704e9d4
--- /dev/null
+++ b/mfkey/src/main/cpp/util_posix.c
@@ -0,0 +1,136 @@
+//-----------------------------------------------------------------------------
+// Copyright (C) 2010 iZsh
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// utilities requiring Posix library functions
+//-----------------------------------------------------------------------------
+
+#if !defined(_WIN32)
+#define _POSIX_C_SOURCE 199309L // need nanosleep()
+#else
+#include
+#endif
+
+#include "util_posix.h"
+#include
+#include
+
+
+// Timer functions
+#if !defined (_WIN32)
+#include
+
+static void nsleep(uint64_t n) {
+ struct timespec timeout;
+ timeout.tv_sec = n/1000000000;
+ timeout.tv_nsec = n%1000000000;
+ while (nanosleep(&timeout, &timeout) && errno == EINTR);
+}
+
+void msleep(uint32_t n) {
+ nsleep(1000000 * (uint64_t)n);
+}
+#endif // _WIN32
+
+#ifdef __APPLE__
+
+#ifndef CLOCK_MONOTONIC
+ #define CLOCK_MONOTONIC (1)
+#endif
+#ifndef CLOCK_REALTIME
+ #define CLOCK_REALTIME (2)
+#endif
+
+ #include
+ #include
+ #include
+ #include
+
+ /* clock_gettime is not implemented on OSX prior to 10.12 */
+ int _civet_clock_gettime(int clk_id, struct timespec *t);
+
+ int _civet_clock_gettime(int clk_id, struct timespec *t)
+ {
+ memset(t, 0, sizeof(*t));
+ if (clk_id == CLOCK_REALTIME) {
+ struct timeval now;
+ int rv = gettimeofday(&now, NULL);
+ if (rv) {
+ return rv;
+ }
+ t->tv_sec = now.tv_sec;
+ t->tv_nsec = now.tv_usec * 1000;
+ return 0;
+
+ } else if (clk_id == CLOCK_MONOTONIC) {
+ static uint64_t clock_start_time = 0;
+ static mach_timebase_info_data_t timebase_info = {0, 0};
+
+ uint64_t now = mach_absolute_time();
+
+ if (clock_start_time == 0) {
+
+ mach_timebase_info(&timebase_info);
+ clock_start_time = now;
+ }
+
+ now = (uint64_t)((double)(now - clock_start_time)
+ * (double)timebase_info.numer
+ / (double)timebase_info.denom);
+
+ t->tv_sec = now / 1000000000;
+ t->tv_nsec = now % 1000000000;
+ return 0;
+ }
+ return -1; // EINVAL - Clock ID is unknown
+ }
+
+ /* if clock_gettime is declared, then __CLOCK_AVAILABILITY will be defined */
+ #ifdef __CLOCK_AVAILABILITY
+ /* If we compiled with Mac OSX 10.12 or later, then clock_gettime will be declared
+ * but it may be NULL at runtime. So we need to check before using it. */
+ int _civet_safe_clock_gettime(int clk_id, struct timespec *t);
+
+ int _civet_safe_clock_gettime(int clk_id, struct timespec *t) {
+ if( clock_gettime ) {
+ return clock_gettime(clk_id, t);
+ }
+ return _civet_clock_gettime(clk_id, t);
+ }
+ #define clock_gettime _civet_safe_clock_gettime
+ #else
+ #define clock_gettime _civet_clock_gettime
+ #endif
+
+#endif
+
+
+// a milliseconds timer for performance measurement
+uint64_t msclock(void) {
+#if defined(_WIN32)
+ #include
+
+ // WORKAROUND FOR MinGW (some versions - use if normal code does not compile)
+ // It has no _ftime_s and needs explicit inclusion of timeb.h
+ #include
+ struct _timeb t;
+ _ftime(&t);
+ return 1000 * (uint64_t)t.time + t.millitm;
+
+// NORMAL CODE (use _ftime_s)
+ //struct _timeb t;
+ //if (_ftime_s(&t)) {
+ // return 0;
+ //} else {
+ // return 1000 * t.time + t.millitm;
+ //}
+#else
+ struct timespec t;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ return (t.tv_sec * 1000 + t.tv_nsec / 1000000);
+#endif
+}
+
diff --git a/mfkey/src/main/cpp/util_posix.h b/mfkey/src/main/cpp/util_posix.h
new file mode 100644
index 00000000..dcf9d99a
--- /dev/null
+++ b/mfkey/src/main/cpp/util_posix.h
@@ -0,0 +1,26 @@
+//-----------------------------------------------------------------------------
+// Copyright (C) 2010 iZsh
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// utilities requiring Posix library functions
+//-----------------------------------------------------------------------------
+
+#ifndef UTIL_POSIX_H__
+#define UTIL_POSIX_H__
+
+#include
+
+#ifdef _WIN32
+# include
+# define sleep(n) Sleep(1000 *(n))
+# define msleep(n) Sleep((n))
+#else
+extern void msleep(uint32_t n); // sleep n milliseconds
+#endif // _WIN32
+
+extern uint64_t msclock(); // a milliseconds clock
+
+#endif
diff --git a/mfkey/src/main/java/com/dxl/mfkey/MfKey32.java b/mfkey/src/main/java/com/dxl/mfkey/MfKey32.java
new file mode 100644
index 00000000..96461f8b
--- /dev/null
+++ b/mfkey/src/main/java/com/dxl/mfkey/MfKey32.java
@@ -0,0 +1,31 @@
+package com.dxl.mfkey;
+
+public interface MfKey32 {
+ /**
+ * 单独实现一个原生函数,直接做计算操作,不走控制台实现!
+ *
+ * @return key
+ */
+ String decrypt4IntParams(
+ int uid, /* 计算的UID,整形类型 */
+ int nt0,
+ int nr0,
+ int ar0,
+ int nt1,
+ int nr1,
+ int ar1
+ );
+
+ /*
+ * 参数重写,传入的参数进行重新转换之类的!
+ * */
+ String decrypt4StrParams(
+ String uid, /* 计算的UID,16HEX字符类型 */
+ String nt0,
+ String nr0,
+ String ar0,
+ String nt1,
+ String nr1,
+ String ar1
+ );
+}
diff --git a/mfkey/src/main/java/com/dxl/mfkey/NativeMfKey32.java b/mfkey/src/main/java/com/dxl/mfkey/NativeMfKey32.java
new file mode 100644
index 00000000..89df8193
--- /dev/null
+++ b/mfkey/src/main/java/com/dxl/mfkey/NativeMfKey32.java
@@ -0,0 +1,36 @@
+package com.dxl.mfkey;
+
+public class NativeMfKey32 implements MfKey32 {
+
+ static {
+ System.loadLibrary("mfkey32");
+ }
+
+ /**
+ * 单独实现一个原生函数,直接做计算操作,不走控制台实现!
+ *
+ * @return key
+ */
+ public native String decrypt4IntParams(
+ int uid, /* 计算的UID,整形类型 */
+ int nt0,
+ int nr0,
+ int ar0,
+ int nt1,
+ int nr1,
+ int ar1
+ );
+
+ /*
+ * 参数重写,传入的参数进行重新转换之类的!
+ * */
+ public native String decrypt4StrParams(
+ String uid, /* 计算的UID,16HEX字符类型 */
+ String nt0,
+ String nr0,
+ String ar0,
+ String nt1,
+ String nr1,
+ String ar1
+ );
+}
diff --git a/mfkey/src/main/java/com/dxl/mfkey/NativeMfKey32V2.java b/mfkey/src/main/java/com/dxl/mfkey/NativeMfKey32V2.java
new file mode 100644
index 00000000..15db6701
--- /dev/null
+++ b/mfkey/src/main/java/com/dxl/mfkey/NativeMfKey32V2.java
@@ -0,0 +1,36 @@
+package com.dxl.mfkey;
+
+public class NativeMfKey32V2 implements MfKey32 {
+
+ static {
+ System.loadLibrary("mfkey32v2");
+ }
+
+ /**
+ * 单独实现一个原生函数,直接做计算操作,不走控制台实现!
+ *
+ * @return key
+ */
+ public native String decrypt4IntParams(
+ int uid, /* 计算的UID,整形类型 */
+ int nt0,
+ int nr0,
+ int ar0,
+ int nt1,
+ int nr1,
+ int ar1
+ );
+
+ /*
+ * 参数重写,传入的参数进行重新转换之类的!
+ * */
+ public native String decrypt4StrParams(
+ String uid, /* 计算的UID,16HEX字符类型 */
+ String nt0,
+ String nr0,
+ String ar0,
+ String nt1,
+ String nr1,
+ String ar1
+ );
+}
diff --git a/mfkey/src/main/java/com/dxl/mfkey/NativeMfKey64.java b/mfkey/src/main/java/com/dxl/mfkey/NativeMfKey64.java
new file mode 100644
index 00000000..50f84abc
--- /dev/null
+++ b/mfkey/src/main/java/com/dxl/mfkey/NativeMfKey64.java
@@ -0,0 +1,7 @@
+package com.dxl.mfkey;
+
+public class NativeMfKey64 {
+ static {
+ System.loadLibrary("mfkey64");
+ }
+}
diff --git a/mfkey/src/main/java/com/dxl/mfkey/Nonce32.java b/mfkey/src/main/java/com/dxl/mfkey/Nonce32.java
new file mode 100644
index 00000000..65fd3ddf
--- /dev/null
+++ b/mfkey/src/main/java/com/dxl/mfkey/Nonce32.java
@@ -0,0 +1,50 @@
+package com.dxl.mfkey;
+
+/**
+ * 32长度随机数恢复!
+ * 部分功能链式调用!
+ *
+ * @author DXL
+ */
+public class Nonce32 {
+ private int nt;
+ private int nr;
+ private int ar;
+
+ public Nonce32() {
+ //空构造!
+ }
+
+ public Nonce32(int nt, int nr, int ar) {
+ this.nt = nt;
+ this.nr = nr;
+ this.ar = ar;
+ }
+
+ public int getNt() {
+ return nt;
+ }
+
+ public Nonce32 setNt(int nt) {
+ this.nt = nt;
+ return this;
+ }
+
+ public int getNr() {
+ return nr;
+ }
+
+ public Nonce32 setNr(int nr) {
+ this.nr = nr;
+ return this;
+ }
+
+ public int getAr() {
+ return ar;
+ }
+
+ public Nonce32 setAr(int ar) {
+ this.ar = ar;
+ return this;
+ }
+}
diff --git a/mfkey/src/main/java/com/dxl/mfkey/Nonce64.java b/mfkey/src/main/java/com/dxl/mfkey/Nonce64.java
new file mode 100644
index 00000000..f0ee24ef
--- /dev/null
+++ b/mfkey/src/main/java/com/dxl/mfkey/Nonce64.java
@@ -0,0 +1,34 @@
+package com.dxl.mfkey;
+
+/**
+ * @author DXL
+ * Nonce64类比Nonce32类多了几个属性变量,
+ * 其他的一致相同,此时可以继承复用!
+ */
+public class Nonce64 extends Nonce32 {
+ private int at;
+ private int[] enc;
+
+ public Nonce64(int nt, int nr, int ar, int at) {
+ super(nt, nr, ar);
+ this.at = at;
+ }
+
+ public int getAt() {
+ return at;
+ }
+
+ public Nonce64 setAt(int at) {
+ this.at = at;
+ return this;
+ }
+
+ public int[] getEnc() {
+ return enc;
+ }
+
+ public Nonce64 setEnc(int[] enc) {
+ this.enc = enc;
+ return this;
+ }
+}
diff --git a/mfkey/src/main/res/values/strings.xml b/mfkey/src/main/res/values/strings.xml
new file mode 100644
index 00000000..e73bf4f6
--- /dev/null
+++ b/mfkey/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ mfkey
+
diff --git a/nfctag/.gitignore b/nfctag/.gitignore
new file mode 100644
index 00000000..3889eda0
--- /dev/null
+++ b/nfctag/.gitignore
@@ -0,0 +1,62 @@
+# Built application files
+*.apk
+*.ap_
+
+# Files for the ART/Dalvik VM
+*.dex
+
+# Java class files
+*.class
+
+# Generated files
+bin/
+gen/
+out/
+
+# Cmake gen
+.cxx/
+
+# Gradle files
+.gradle/
+build/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Proguard folder generated by Eclipse
+proguard/
+
+# Log Files
+*.log
+
+# Android Studio Navigation editor temp files
+.navigation/
+
+# Android Studio captures folder
+captures/
+
+# IntelliJ
+*.iml
+.idea/
+
+# Keystore files
+# Uncomment the following line if you do not want to check your keystore files in.
+#*.jks
+
+# External native build folder generated in Android Studio 2.2 and later
+.externalNativeBuild
+
+# Google Services (e.g. APIs or Firebase)
+google-services.json
+
+# Freeline
+freeline.py
+freeline/
+freeline_project_description.json
+
+# fastlane
+fastlane/report.xml
+fastlane/Preview.html
+fastlane/screenshots
+fastlane/test_output
+fastlane/readme.md
diff --git a/nfctag/build.gradle b/nfctag/build.gradle
new file mode 100644
index 00000000..ed9028da
--- /dev/null
+++ b/nfctag/build.gradle
@@ -0,0 +1,30 @@
+apply plugin: 'com.android.library'
+apply plugin: 'com.github.dcendents.android-maven'
+group = 'com.github.xianglin1998'
+version = '1.0'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.3"
+
+ defaultConfig {
+ minSdkVersion 19
+ targetSdkVersion 29
+ versionCode 1
+ versionName "1.0"
+
+ consumerProguardFiles 'consumer-rules.pro'
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+}
diff --git a/nfctag/consumer-rules.pro b/nfctag/consumer-rules.pro
new file mode 100644
index 00000000..e69de29b
diff --git a/nfctag/proguard-rules.pro b/nfctag/proguard-rules.pro
new file mode 100644
index 00000000..f1b42451
--- /dev/null
+++ b/nfctag/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/nfctag/src/main/AndroidManifest.xml b/nfctag/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..67676580
--- /dev/null
+++ b/nfctag/src/main/AndroidManifest.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/nfctag/src/main/java/cn/dxl/mifare/BatchAdapter.java b/nfctag/src/main/java/cn/dxl/mifare/BatchAdapter.java
new file mode 100644
index 00000000..e91400ee
--- /dev/null
+++ b/nfctag/src/main/java/cn/dxl/mifare/BatchAdapter.java
@@ -0,0 +1,50 @@
+package cn.dxl.mifare;
+
+import java.io.IOException;
+
+/**
+ * MifareClassic S50 & S70 batch verity and RW!
+ *
+ * @author DXL
+ * @version 1.0
+ */
+public interface BatchAdapter {
+ /**
+ * 读取标签
+ *
+ * @param block 读取的起始块
+ * 如果all为true,则将会读取该扇区所有块,此时参数一就是扇区的起始块,
+ * 如果all为false,则将会只读单个块,此时参数一就是块!
+ * @return 读取结果, 可能为null
+ */
+ byte[][] read(int block, boolean isKeyA, byte[] key, boolean isReadSector) throws IOException;
+
+ /**
+ * 写入标签
+ *
+ * @param sector 写入的扇区,
+ * @param data 将被写入的数据,单项必须是16字节长度的Hex字符串
+ * @return 写入结果!
+ */
+ boolean write(int sector, boolean isKeyA, byte[] key, byte[] data) throws IOException;
+
+ /**
+ * 验证标签,使用一定长度的秘钥组
+ *
+ * @param sector 需要验证的扇区号!
+ * @param keysGroup 被用来验证的秘钥组!
+ * @param isKeyA 是否是验证秘钥A的
+ * @return 验证成功的秘钥!
+ */
+ byte[] verity(int sector, byte[][] keysGroup, boolean isKeyA) throws IOException;
+
+ /**
+ * 获取批量操作的超时!
+ */
+ int getTimeout();
+
+ /**
+ * 设置批量操作的超时!
+ */
+ void setTimeout(int timeout);
+}
diff --git a/nfctag/src/main/java/cn/dxl/mifare/HardNestedAdapter.java b/nfctag/src/main/java/cn/dxl/mifare/HardNestedAdapter.java
new file mode 100644
index 00000000..6fd96408
--- /dev/null
+++ b/nfctag/src/main/java/cn/dxl/mifare/HardNestedAdapter.java
@@ -0,0 +1,14 @@
+package cn.dxl.mifare;
+
+public interface HardNestedAdapter extends TestTaskAdapter {
+ /**
+ * 以一个已知秘钥测试其他的秘钥,使用HardNested漏洞!
+ *
+ * @param srcSector 已知的秘钥的扇区
+ * @param srcKey 已知的秘钥
+ * @param isKeyA 已知的秘钥的类型
+ * @param targetSector 欲测试的扇区
+ * @param getKeyA 欲获得的扇区的秘钥类型
+ */
+ byte[] prepare(int srcSector, byte[] srcKey, boolean isKeyA, int targetSector, boolean getKeyA);
+}
diff --git a/nfctag/src/main/java/cn/dxl/mifare/MifareAdapter.java b/nfctag/src/main/java/cn/dxl/mifare/MifareAdapter.java
new file mode 100644
index 00000000..947113bb
--- /dev/null
+++ b/nfctag/src/main/java/cn/dxl/mifare/MifareAdapter.java
@@ -0,0 +1,179 @@
+package cn.dxl.mifare;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+/*
+ * MifareClassic定义
+ * */
+public interface MifareAdapter extends Serializable {
+ /*
+ * 一个标准的MifareClassic
+ * 是可以被链接,被验证,被读取,被写入,被增值,被减值,被重置的!
+ * */
+
+ /**
+ * 重新查找获取标签!
+ *
+ * @return 查找结果!
+ */
+ boolean rescantag() throws IOException;
+
+ /**
+ * 链接标签
+ *
+ * @return 链接结果!
+ */
+ boolean connect() throws IOException;
+
+ /**
+ * 断开标签
+ */
+ void close() throws IOException;
+
+ /**
+ * 读取标签
+ *
+ * @param block 读取的块
+ * @return 读取结果, 可能为null
+ */
+ byte[] read(int block) throws IOException;
+
+ /**
+ * 写入标签
+ *
+ * @param blockIndex 写入的块,
+ * @param data 将被写入的数据,必须是16字节长度的Hex字符串!
+ * @return 写入结果!
+ */
+ boolean write(int blockIndex, byte[] data) throws IOException;
+
+ /**
+ * 验证密钥A
+ *
+ * @param sectorIndex 被验证的块
+ * @param key 用来验证的密钥
+ * @return 验证结果!
+ */
+ boolean authA(int sectorIndex, byte[] key) throws IOException;
+
+ /**
+ * 验证密钥B
+ *
+ * @param sectorIndex 被验证的块
+ * @param key 用来验证的密钥
+ * @return 验证结果!
+ */
+ boolean authB(int sectorIndex, byte[] key) throws IOException;
+
+ /**
+ * 增值
+ *
+ * @param blockIndex 被增值的块
+ * @param value 非负递增的值
+ */
+ void increment(int blockIndex, int value) throws IOException;
+
+ /**
+ * 增值
+ *
+ * @param blockIndex 被增值的块
+ * @param value 非负递减的值
+ */
+ void decrement(int blockIndex, int value) throws IOException;
+
+ /**
+ * 恢复增值减值操作
+ *
+ * @param blockIndex 被恢复的块
+ */
+ void restore(int blockIndex) throws IOException;
+
+ /**
+ * 转移值数据到块
+ *
+ * @param blockIndex 被转移的块
+ */
+ void transfer(int blockIndex) throws IOException;
+
+ /**
+ * 获得UID
+ *
+ * @return UID字节数组
+ */
+ byte[] getUid();
+
+ byte[] getAts();
+
+ byte[] getAtqa();
+
+ byte[] getSak();
+
+ /**
+ * 获得类型
+ *
+ * @return 1024 or 2048 or 4096
+ */
+ int getType();
+
+ /**
+ * 获得扇区数量
+ *
+ * @return 卡片支持的扇区容量
+ */
+ int getSectorCount();
+
+ /**
+ * 获得块数量
+ *
+ * @return 卡片支持的块容量
+ */
+ int getBlockCount();
+
+ /**
+ * 设置操作超时
+ *
+ * @param ms 被设置的超时
+ */
+ void setTimeout(int ms);
+
+ /**
+ * 获取操作超时
+ *
+ * @return 超时参数
+ */
+ int getTimeout();
+
+ /**
+ * 获取批量操作的实现!
+ * 如果返回null,则不支持批量!
+ */
+ BatchAdapter getBatchImpl();
+
+ /**
+ * 是否是链接状态!
+ *
+ * @return 如果卡片已经链接(在部分实现机制上)
+ * 否则你可以获取结果为true的返回值,否则为false
+ */
+ boolean isConnected();
+
+ /**
+ * 是否是仿真卡
+ *
+ * @return true为仿真
+ */
+ boolean isEmulated();
+
+ /**
+ * 是否是后门卡!
+ *
+ * @return 是否是后门卡
+ */
+ boolean isSpecialTag();
+
+ /**
+ * 是否是支持测试!
+ */
+ boolean isTestSupported();
+}
diff --git a/nfctag/src/main/java/cn/dxl/mifare/MifareClassicUtils.java b/nfctag/src/main/java/cn/dxl/mifare/MifareClassicUtils.java
new file mode 100644
index 00000000..f82c77e9
--- /dev/null
+++ b/nfctag/src/main/java/cn/dxl/mifare/MifareClassicUtils.java
@@ -0,0 +1,105 @@
+package cn.dxl.mifare;
+
+/*
+ * MifareClassic标签用得到的工具!
+ * */
+public class MifareClassicUtils {
+
+ public static boolean validateSector(int sector) {
+ // Do not be too strict on upper bounds checking, since some cards
+ // have more addressable memory than they report. For example,
+ // MIFARE Plus 2k cards will appear as MIFARE Classic 1k cards when in
+ // MIFARE Classic compatibility mode.
+ // Note that issuing a command to an out-of-bounds block is safe - the
+ // tag should report error causing IOException. This validation is a
+ // helper to guard against obvious programming mistakes.
+
+ int NR_TRAILERS_4k = 40;
+ if (sector < 0 || sector >= NR_TRAILERS_4k) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean validateBlock(int block) {
+ // Just looking for obvious out of bounds...
+ int NR_BLOCKS_4k = 0xFF;
+ if (block < 0 || block >= NR_BLOCKS_4k) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean validateValueOperand(int value) {
+ if (value < 0) {
+ return false;
+ }
+ return true;
+ }
+
+ public static int blockToSector(int blockIndex) {
+ if (!validateBlock(blockIndex)) return 0;
+ if (blockIndex < 32 * 4) {
+ return (blockIndex / 4);
+ } else {
+ return (32 + (blockIndex - 32 * 4) / 16);
+ }
+ }
+
+ public static int sectorToBlock(int sectorIndex) {
+ if (!validateSector(sectorIndex)) {
+ return -1;
+ }
+ if (sectorIndex < 32) {
+ return (sectorIndex * 4);
+ } else {
+ return (32 * 4 + (sectorIndex - 32) * 16);
+ }
+ }
+
+ public static boolean isFirstBlock(int uiBlock) {
+ // 测试我们是否处于小扇区或者大扇区?
+ if (uiBlock < 128)
+ return ((uiBlock) % 4 == 0);
+ else
+ return ((uiBlock) % 16 == 0);
+ }
+
+ public static boolean isTrailerBlock(int uiBlock) {
+ // 测试我们处于小区块还是大扇区
+ if (uiBlock < 128)
+ return ((uiBlock + 1) % 4 == 0);
+ else
+ return ((uiBlock + 1) % 16 == 0);
+ }
+
+ public static int getBlockCountInSector(int sectorIndex) {
+ if (!validateSector(sectorIndex)) return -1;
+ if (sectorIndex < 32) {
+ return 4;
+ } else {
+ return 16;
+ }
+ }
+
+ public static int get_trailer_block(int uiFirstBlock) {
+ // Test if we are in the small or big sectors
+ int trailer_block;
+ if (uiFirstBlock < 128) {
+ trailer_block = uiFirstBlock + (3 - (uiFirstBlock % 4));
+ } else {
+ trailer_block = uiFirstBlock + (15 - (uiFirstBlock % 16));
+ }
+ return trailer_block;
+ }
+
+ public static int getIndexOnSector(int block, int sector) {
+ int index = 0;
+ //得到当前的块在扇区中的具体索引!
+ for (int i = 0; i < getBlockCountInSector(sector); i++) { //得到当前扇区的块总数!
+ if (block == (sectorToBlock(block) + i)) break;
+ ++index;
+ }
+ return index;
+ }
+}
diff --git a/nfctag/src/main/java/cn/dxl/mifare/NestedAdapter.java b/nfctag/src/main/java/cn/dxl/mifare/NestedAdapter.java
new file mode 100644
index 00000000..12b2dd65
--- /dev/null
+++ b/nfctag/src/main/java/cn/dxl/mifare/NestedAdapter.java
@@ -0,0 +1,14 @@
+package cn.dxl.mifare;
+
+public interface NestedAdapter extends TestTaskAdapter {
+ /**
+ * 以一个已知秘钥测试其他的秘钥!
+ *
+ * @param srcSector 已知的秘钥的扇区
+ * @param srcKey 已知的秘钥
+ * @param isKeyA 已知的秘钥的类型
+ * @param targetSector 欲测试的扇区
+ * @param getKeyA 欲获得的扇区的秘钥类型
+ */
+ void prepare(int srcSector, byte[] srcKey, boolean isKeyA, int targetSector, boolean getKeyA);
+}
diff --git a/nfctag/src/main/java/cn/dxl/mifare/NfcTagListenUtils.java b/nfctag/src/main/java/cn/dxl/mifare/NfcTagListenUtils.java
new file mode 100644
index 00000000..aca6e22e
--- /dev/null
+++ b/nfctag/src/main/java/cn/dxl/mifare/NfcTagListenUtils.java
@@ -0,0 +1,44 @@
+package cn.dxl.mifare;
+
+import android.nfc.Tag;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 全局的标签缓存!
+ */
+public class NfcTagListenUtils {
+ private static Tag tag = null;
+ private static List listeners = new ArrayList<>();
+
+ public static Tag getTag() {
+ return tag;
+ }
+
+ public static void setTag(Tag tag) {
+ NfcTagListenUtils.tag = tag;
+ }
+
+ public interface OnNewTagListener {
+ void onNewTag(Tag tag);
+ }
+
+ public static void addListener(OnNewTagListener listener) {
+ listeners.add(listener);
+ }
+
+ public static void removeListener(OnNewTagListener listener) {
+ listeners.remove(listener);
+ }
+
+ public static void notifyOnNewTag(Tag tag) {
+ //直接通知TAG的变化!
+ for (OnNewTagListener l : listeners) {
+ try {
+ l.onNewTag(tag);
+ } catch (Exception ignored) {
+ }
+ }
+ }
+}
diff --git a/nfctag/src/main/java/cn/dxl/mifare/PRNGAdapter.java b/nfctag/src/main/java/cn/dxl/mifare/PRNGAdapter.java
new file mode 100644
index 00000000..441a6824
--- /dev/null
+++ b/nfctag/src/main/java/cn/dxl/mifare/PRNGAdapter.java
@@ -0,0 +1,5 @@
+package cn.dxl.mifare;
+
+public interface PRNGAdapter extends TestTaskAdapter {
+ byte[] prepare(int sector, boolean getKeyA);
+}
\ No newline at end of file
diff --git a/nfctag/src/main/java/cn/dxl/mifare/StdMifareImpl.java b/nfctag/src/main/java/cn/dxl/mifare/StdMifareImpl.java
new file mode 100644
index 00000000..2fa46867
--- /dev/null
+++ b/nfctag/src/main/java/cn/dxl/mifare/StdMifareImpl.java
@@ -0,0 +1,333 @@
+package cn.dxl.mifare;
+
+import android.content.Context;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcManager;
+import android.nfc.Tag;
+import android.nfc.tech.MifareClassic;
+import android.os.Build;
+
+import java.io.File;
+import java.io.IOException;
+
+public class StdMifareImpl implements MifareAdapter, NfcTagListenUtils.OnNewTagListener {
+ private static MifareClassic mMfTag = null;
+ private final static StdMifareImpl stdMifareImpl = new StdMifareImpl();
+
+ /*
+ * 此方法需要传入一个TAG,这个TAG将被用来初始化一个MifareClassic标签!
+ * */
+ private StdMifareImpl() {
+ mMfTag = getMfOfGlobalTag();
+ NfcTagListenUtils.addListener(this);
+ }
+
+ public static StdMifareImpl getInstance() {
+ synchronized (stdMifareImpl) {
+ mMfTag = getMfOfGlobalTag();
+ }
+ return stdMifareImpl;
+ }
+
+ private static MifareClassic getMfOfGlobalTag() {
+ if (mMfTag != null) {
+ try {
+ mMfTag.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ Tag tag = NfcTagListenUtils.getTag();
+ if (tag != null) {
+ return MifareClassic.get(tag);
+ }
+ return null;
+ }
+
+ /**
+ * Check if the device supports the MIFARE Classic technology.
+ * In order to do so, there is a first check ensure the device actually has a NFC hardware
+ * After this, this function will check if there are files
+ * like "/dev/bcm2079x-i2c" or "/system/lib/libnfc-bcrm*". Files like
+ * these are indicators for a NFC controller manufactured by Broadcom.
+ * Broadcom chips don't support MIFARE Classic.
+ *
+ * @return True if the device supports MIFARE Classic. False otherwise.
+ */
+ public static boolean hasMifareClassicSupport(Context context) {
+
+ // Check for the MifareClassic class.
+ // It is most likely there on all NFC enabled phones.
+ // Therefore this check is not needed.
+ /*
+ try {
+ Class.forName("android.nfc.tech.MifareClassic");
+ } catch( ClassNotFoundException e ) {
+ // Class not found. Devices does not support MIFARE Classic.
+ return false;
+ }
+ */
+
+ // Check if ther is any NFC hardware at all.
+ if (NfcAdapter.getDefaultAdapter(context) == null) {
+ return false;
+ }
+
+ // Check if there is the NFC device "bcm2079x-i2c".
+ // Chips by Broadcom don't support MIFARE Classic.
+ // This could fail because on a lot of devices apps don't have
+ // the sufficient permissions.
+ // Another exception:
+ // The Lenovo P2 has a device at "/dev/bcm2079x-i2c" but is still
+ // able of reading/writing MIFARE Classic tags. I don't know why...
+ // https://github.com/ikarus23/MifareClassicTool/issues/152
+ boolean isLenovoP2 = Build.MANUFACTURER.equals("LENOVO")
+ && Build.MODEL.equals("Lenovo P2a42");
+ File device = new File("/dev/bcm2079x-i2c");
+ if (!isLenovoP2 && device.exists()) {
+ return false;
+ }
+
+ // Check if there is the NFC device "pn544".
+ // The PN544 NFC chip is manufactured by NXP.
+ // Chips by NXP support MIFARE Classic.
+ device = new File("/dev/pn544");
+ if (device.exists()) {
+ return true;
+ }
+
+ // Check if there are NFC libs with "brcm" in their names.
+ // "brcm" libs are for devices with Broadcom chips. Broadcom chips
+ // don't support MIFARE Classic.
+ File libsFolder = new File("/system/lib");
+ File[] libs = libsFolder.listFiles();
+ if (libs != null) {
+ for (File lib : libs) {
+ if (lib.isFile()
+ && lib.getName().startsWith("libnfc")
+ && lib.getName().contains("brcm")
+ // Add here other non NXP NFC libraries.
+ ) {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean isNfcOpened(Context context) {
+ if (hasMifareClassicSupport(context)) {
+ NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
+ //判断设备是否支持NFC!
+ if (manager != null) {
+ NfcAdapter adapter = manager.getDefaultAdapter();
+ // 可能出现adapter为空的情况!
+ if (adapter != null) {
+ return adapter.isEnabled();
+ }
+ }
+ }
+ return false;
+ }
+
+ public MifareClassic getMf() {
+ return mMfTag;
+ }
+
+ @Override
+ public boolean rescantag() throws IOException {
+ Tag tag = NfcTagListenUtils.getTag();
+ if (mMfTag != null) mMfTag.close();
+ if (tag != null) {
+ mMfTag = MifareClassic.get(tag);
+ }
+ return mMfTag != null;
+ }
+
+ @Override
+ public boolean connect() throws IOException {
+ if (mMfTag.isConnected()) mMfTag.close();
+ if (mMfTag != null && !isConnected()) {
+ mMfTag.connect();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (mMfTag != null)
+ if (isConnected())
+ mMfTag.close();
+ }
+
+ @Override
+ public byte[] read(int block) throws IOException {
+ if (mMfTag != null)
+ return mMfTag.readBlock(block);
+ return null;
+ }
+
+ @Override
+ public boolean write(int blockIndex, byte[] data) throws IOException {
+ if (mMfTag != null) {
+ mMfTag.writeBlock(blockIndex, data);
+ return true;
+ }
+ return false;
+ }
+
+ private boolean conTest() throws IOException {
+ boolean con = true;
+ if (!mMfTag.isConnected()) {
+ con = connect();
+ }
+ return con;
+ }
+
+ @Override
+ public boolean authA(int sectorIndex, byte[] key) throws IOException {
+ if (mMfTag != null) {
+ return conTest() && mMfTag.authenticateSectorWithKeyA(sectorIndex, key);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean authB(int sectorIndex, byte[] key) throws IOException {
+ if (mMfTag != null) {
+ return conTest() && mMfTag.authenticateSectorWithKeyB(sectorIndex, key);
+ }
+ return false;
+ }
+
+ @Override
+ public void increment(int blockIndex, int value) throws IOException {
+ if (mMfTag != null)
+ mMfTag.increment(blockIndex, value);
+ }
+
+ @Override
+ public void decrement(int blockIndex, int value) throws IOException {
+ if (mMfTag != null)
+ mMfTag.decrement(blockIndex, value);
+ }
+
+ @Override
+ public void restore(int blockIndex) throws IOException {
+ if (mMfTag != null)
+ mMfTag.restore(blockIndex);
+ }
+
+ @Override
+ public void transfer(int blockIndex) throws IOException {
+ if (mMfTag != null)
+ mMfTag.transfer(blockIndex);
+ }
+
+ @Override
+ public byte[] getUid() {
+ if (mMfTag != null)
+ return mMfTag.getTag().getId();
+ return null;
+ }
+
+ @Override
+ public byte[] getAts() {
+ return new byte[0];
+ }
+
+ @Override
+ public byte[] getAtqa() {
+ return new byte[0];
+ }
+
+ @Override
+ public byte[] getSak() {
+ return new byte[0];
+ }
+
+ @Override
+ public int getType() {
+ if (mMfTag != null)
+ return mMfTag.getType();
+ return -1;
+ }
+
+ @Override
+ public int getSectorCount() {
+ if (mMfTag != null)
+ return mMfTag.getSectorCount();
+ return -1;
+ }
+
+ @Override
+ public int getBlockCount() {
+ if (mMfTag != null)
+ return mMfTag.getBlockCount();
+ return -1;
+ }
+
+ @Override
+ public void setTimeout(int ms) {
+ if (mMfTag != null)
+ mMfTag.setTimeout(ms);
+ }
+
+ @Override
+ public int getTimeout() {
+ if (mMfTag != null)
+ return mMfTag.getTimeout();
+ return -1;
+ }
+
+ @Override
+ public BatchAdapter getBatchImpl() {
+ // 标准NFC不支持批量验证,所以需要返回null
+ return null;
+ }
+
+ @Override
+ public boolean isConnected() {
+ synchronized (stdMifareImpl) {
+ if (mMfTag == null) {
+ return false;
+ }
+ return mMfTag.isConnected();
+ }
+ }
+
+ @Override
+ public boolean isEmulated() {
+ return false;
+ }
+
+ @Override
+ public boolean isSpecialTag() {
+ //自带的NFC不支持特殊的后门标签直接读写,因此直接返回false即可!
+ return false;
+ }
+
+ @Override
+ public boolean isTestSupported() {
+ return false;
+ }
+
+ @Override
+ public void onNewTag(Tag tag) {
+ synchronized (stdMifareImpl) {
+ if (mMfTag != null) {
+ if (mMfTag.isConnected()) {
+ try {
+ mMfTag.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ mMfTag = getMfOfGlobalTag();
+ }
+ }
+ }
+}
diff --git a/nfctag/src/main/java/cn/dxl/mifare/StdMifareIntent.java b/nfctag/src/main/java/cn/dxl/mifare/StdMifareIntent.java
new file mode 100644
index 00000000..24596beb
--- /dev/null
+++ b/nfctag/src/main/java/cn/dxl/mifare/StdMifareIntent.java
@@ -0,0 +1,53 @@
+package cn.dxl.mifare;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcManager;
+import android.nfc.tech.MifareClassic;
+
+public class StdMifareIntent {
+
+ private NfcAdapter mAdapter = null;
+
+ public StdMifareIntent(Context context) {
+ NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
+ //判断设备是否支持NFC!
+ if (manager == null) return;
+ mAdapter = manager.getDefaultAdapter();
+ }
+
+ /*
+ * 获取当前操作的适配器!
+ * */
+ public NfcAdapter getAdapter() {
+ return mAdapter;
+ }
+
+ /*
+ * 注册前台
+ * */
+ public void enableForegroundDispatch(Activity targetAct) {
+ if (mAdapter == null) return;
+ //进行前台广播拦截!
+ Intent intent = new Intent(targetAct,
+ targetAct.getClass()).addFlags(
+ Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ PendingIntent pendingIntent = PendingIntent.getActivity(
+ targetAct, 0, intent, 0);
+ mAdapter.enableForegroundDispatch(targetAct, pendingIntent, null, new String[][]{
+ new String[]{MifareClassic.class.getName()}});
+ }
+
+ /*
+ * 解注册前台
+ * */
+ public void disableForegroundDispatch(Activity activity) {
+ if (mAdapter == null) return;
+ //解注册前台拦截
+ mAdapter.disableForegroundDispatch(activity);
+ }
+
+}
diff --git a/nfctag/src/main/java/cn/dxl/mifare/TagLeaksAdapter.java b/nfctag/src/main/java/cn/dxl/mifare/TagLeaksAdapter.java
new file mode 100644
index 00000000..0aa75c74
--- /dev/null
+++ b/nfctag/src/main/java/cn/dxl/mifare/TagLeaksAdapter.java
@@ -0,0 +1,28 @@
+package cn.dxl.mifare;
+
+import java.io.Serializable;
+
+/**
+ * @author DXL the TagLeaksAdapter can scan a leak for tag
+ * impl at subclass
+ */
+public interface TagLeaksAdapter extends Serializable {
+ /*
+ * Darkside test, form a nack(4bit) recovery a key.
+ * don't need any key.
+ * if tag no nack response, the darkside can't wrok.
+ * */
+ boolean isDarksideSupported();
+
+ /*
+ * Nested test, from a available auth data pack recovery a key.
+ * need a key
+ * if tag no prng available, the nested can't running.
+ * */
+ boolean isNestedSupported();
+
+ /*
+ * Harden nested, must have a key available and powerful processors.
+ * */
+ boolean isHardnestedSupported();
+}
\ No newline at end of file
diff --git a/nfctag/src/main/java/cn/dxl/mifare/TestTaskAdapter.java b/nfctag/src/main/java/cn/dxl/mifare/TestTaskAdapter.java
new file mode 100644
index 00000000..1723cbf1
--- /dev/null
+++ b/nfctag/src/main/java/cn/dxl/mifare/TestTaskAdapter.java
@@ -0,0 +1,23 @@
+package cn.dxl.mifare;
+
+import java.io.Serializable;
+
+public interface TestTaskAdapter extends Serializable {
+ // start work.
+ void start();
+
+ // call at start finished.
+ void onStart();
+
+ // on test progress
+ void progress(int max, int now);
+
+ // stop task and recycle source
+ void stop();
+
+ // call at stop finished.
+ void onStop(int status);
+
+ // return a key if exists.
+ byte[] getKeys();
+}
diff --git a/nfctag/src/main/res/values/strings.xml b/nfctag/src/main/res/values/strings.xml
new file mode 100644
index 00000000..e79fbce9
--- /dev/null
+++ b/nfctag/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ mifaretag
+
diff --git a/pm3flasher/build.gradle b/pm3flasher/build.gradle
index 70da35d8..0c2f35b8 100644
--- a/pm3flasher/build.gradle
+++ b/pm3flasher/build.gradle
@@ -41,7 +41,5 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':communication')
-
- implementation 'com.github.xianglin1998:ComBridge:1.0.7'
- // implementation project(path: ':iobridges')
+ implementation project(path: ':iobridges')
}
diff --git a/pm3rdv4rrg/build.gradle b/pm3rdv4rrg/build.gradle
index 5f310132..0d448b75 100644
--- a/pm3rdv4rrg/build.gradle
+++ b/pm3rdv4rrg/build.gradle
@@ -28,6 +28,12 @@ android {
}
}
+// sourceSets {
+// main {
+// jniLibs.srcDirs = ['jniLibs']
+// }
+// }
+
buildTypes {
release {
minifyEnabled false
@@ -38,11 +44,10 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'com.github.xianglin1998:nfctag:1.0'
- implementation 'com.github.xianglin1998:nfc_console:1.0'
- implementation 'com.github.xianglin1998:ComBridge:1.0.7'
- // implementation project(path: ':iobridges')
+ implementation project(path: ':iobridges')
+ implementation project(path: ':nfctag')
+ implementation project(path: ':console')
implementation project(':communication')
implementation project(path: ':utils')
diff --git a/pm3rdv4rrg/src/main/jniLibs/arm64-v8a/libpm3rrg_cmd.so b/pm3rdv4rrg/src/main/jniLibs/arm64-v8a/libpm3rrg_cmd.so
new file mode 100644
index 00000000..e0ded30d
Binary files /dev/null and b/pm3rdv4rrg/src/main/jniLibs/arm64-v8a/libpm3rrg_cmd.so differ
diff --git a/pm3rdv4rrg/src/main/jniLibs/armeabi-v7a/libpm3rrg_cmd.so b/pm3rdv4rrg/src/main/jniLibs/armeabi-v7a/libpm3rrg_cmd.so
new file mode 100644
index 00000000..1252694b
Binary files /dev/null and b/pm3rdv4rrg/src/main/jniLibs/armeabi-v7a/libpm3rrg_cmd.so differ
diff --git a/pm3rdv4rrg/src/main/jniLibs/x86/libpm3rrg_cmd.so b/pm3rdv4rrg/src/main/jniLibs/x86/libpm3rrg_cmd.so
new file mode 100644
index 00000000..365a76fc
Binary files /dev/null and b/pm3rdv4rrg/src/main/jniLibs/x86/libpm3rrg_cmd.so differ
diff --git a/pm3rdv4rrg/src/main/jniLibs/x86_64/libpm3rrg_cmd.so b/pm3rdv4rrg/src/main/jniLibs/x86_64/libpm3rrg_cmd.so
new file mode 100644
index 00000000..3b1200a1
Binary files /dev/null and b/pm3rdv4rrg/src/main/jniLibs/x86_64/libpm3rrg_cmd.so differ
diff --git a/redirector/.gitignore b/redirector/.gitignore
new file mode 100644
index 00000000..3889eda0
--- /dev/null
+++ b/redirector/.gitignore
@@ -0,0 +1,62 @@
+# Built application files
+*.apk
+*.ap_
+
+# Files for the ART/Dalvik VM
+*.dex
+
+# Java class files
+*.class
+
+# Generated files
+bin/
+gen/
+out/
+
+# Cmake gen
+.cxx/
+
+# Gradle files
+.gradle/
+build/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Proguard folder generated by Eclipse
+proguard/
+
+# Log Files
+*.log
+
+# Android Studio Navigation editor temp files
+.navigation/
+
+# Android Studio captures folder
+captures/
+
+# IntelliJ
+*.iml
+.idea/
+
+# Keystore files
+# Uncomment the following line if you do not want to check your keystore files in.
+#*.jks
+
+# External native build folder generated in Android Studio 2.2 and later
+.externalNativeBuild
+
+# Google Services (e.g. APIs or Firebase)
+google-services.json
+
+# Freeline
+freeline.py
+freeline/
+freeline_project_description.json
+
+# fastlane
+fastlane/report.xml
+fastlane/Preview.html
+fastlane/screenshots
+fastlane/test_output
+fastlane/readme.md
diff --git a/redirector/build.gradle b/redirector/build.gradle
new file mode 100644
index 00000000..30db136f
--- /dev/null
+++ b/redirector/build.gradle
@@ -0,0 +1,47 @@
+apply plugin: 'com.android.library'
+apply plugin: 'com.github.dcendents.android-maven'
+group = 'com.github.xianglin1998'
+version = '1.0'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.2"
+
+ defaultConfig {
+ minSdkVersion 19
+ targetSdkVersion 29
+ externalNativeBuild {
+ cmake {
+ arguments '-DANDROID_STL=c++_static'
+ abiFilters "x86", "x86_64", "armeabi-v7a", "arm64-v8a"
+ }
+ //abiFilters "armeabi"
+ /*abiFilters "arm64-v8a"*/
+ /*abiFilters "x86_64"*/
+ /*abiFilters "arm64-v8a"
+ abiFilters "mips"
+ abiFilters "mips64"
+ abiFilters "x86"
+ abiFilters "x86_64"*/
+ }
+ }
+ externalNativeBuild {
+ cmake {
+ version '3.10.2'
+ path 'src/main/cpp/CMakeLists.txt'
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+}
\ No newline at end of file
diff --git a/redirector/proguard-rules.pro b/redirector/proguard-rules.pro
new file mode 100644
index 00000000..f1b42451
--- /dev/null
+++ b/redirector/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/redirector/src/main/AndroidManifest.xml b/redirector/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..78f84e7a
--- /dev/null
+++ b/redirector/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/redirector/src/main/cpp/CMakeLists.txt b/redirector/src/main/cpp/CMakeLists.txt
new file mode 100644
index 00000000..b9c948c8
--- /dev/null
+++ b/redirector/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,11 @@
+#需要的最cmake版本
+cmake_minimum_required(VERSION 3.4.1)
+
+#添加动态库定义
+add_library(freopen SHARED util.c)
+
+#添加头文件配置
+target_include_directories(freopen PRIVATE)
+
+#添加动态库链接!
+target_link_libraries(freopen android)
\ No newline at end of file
diff --git a/redirector/src/main/cpp/util.c b/redirector/src/main/cpp/util.c
new file mode 100644
index 00000000..de78d738
--- /dev/null
+++ b/redirector/src/main/cpp/util.c
@@ -0,0 +1,228 @@
+//
+// Created by DXL on 2019/3/4.
+//
+#include
+#include
+#include
+#include
+#include
+
+/*
+ * 全局的重定向文件句柄缓存!
+ * */
+static FILE *ofp;
+static FILE *efp;
+static FILE *ifp;
+
+/*
+ * 从文件指针获得文件路径!
+ * *//*
+static char *GetPathFromFP(FILE *FP) {
+ if (!FP) return NULL;
+ //取得文件描述符!
+ int fdi = fileno(FP);
+ char proclnk[512] = {0};
+ char path[512] = {0};
+ //进行链接路径拼接!
+ sprintf(proclnk, "/proc/self/fd/%d", fdi);
+ ssize_t r = readlink(proclnk, path, sizeof(path));
+ //LOGD("底层打印ResetStdEO路径: %s", path);
+ if (r <= 0) {
+ //LOGD("GetPathFromFP获取路径失败!");
+ return NULL;
+ }
+ return strdup(path);
+}*/
+
+/*
+ * 标准输出重定向!
+ * */
+jboolean SetStdEO(JNIEnv *env, jclass clz, jstring file, jint type) {
+ //判断传入的参数的可用性!
+ if (!file) return false;
+ jboolean isCopy = false;
+ //解析为char *;
+ const char *_file = (*env)->GetStringUTFChars(env, file, &isCopy);
+ //尝试打开文件
+ switch (type) {
+ case 0:
+ //尝试关闭句柄!
+ if (ofp) {
+ fclose(ofp);
+ ofp = NULL;
+ }
+ if (!(ofp = freopen(_file, "w+", stdout))) {
+ //谨记释放内存!
+ (*env)->ReleaseStringUTFChars(env, file, _file);
+ return false;
+ }
+ //TODO 非常重要,必须清空文件!
+ ftruncate(fileno(ofp), 0);
+ setbuf(stdout, NULL);
+ break;
+ case 1:
+ //尝试关闭句柄!
+ if (efp) {
+ fclose(efp);
+ efp = NULL;
+ }
+ if (!(efp = freopen(_file, "w+", stderr))) {
+ //谨记释放内存!
+ (*env)->ReleaseStringUTFChars(env, file, _file);
+ return false;
+ }
+ //TODO 非常重要,必须清空文件!
+ ftruncate(fileno(efp), 0);
+ setbuf(stderr, NULL);
+ break;
+ default:
+ //谨记释放内存!
+ (*env)->ReleaseStringUTFChars(env, file, _file);
+ return false;
+ }
+ //谨记释放内存!
+ (*env)->ReleaseStringUTFChars(env, file, _file);
+ return true;
+}
+
+/*
+ * 标准输出重定向!
+ * */
+jboolean SetStdIN(JNIEnv *env, jclass clz, jstring file) {
+ //判断传入的参数的可用性!
+ if (!file) return false;
+ jboolean isCopy = false;
+ //解析为char *;
+ const char *_file = (*env)->GetStringUTFChars(env, file, &isCopy);
+ //尝试打开文件
+ //尝试关闭句柄!
+ if (ifp) {
+ fclose(ifp);
+ ifp = NULL;
+ }
+ if (!(ifp = freopen(_file, "w+", stdin))) {
+ //谨记释放内存!
+ (*env)->ReleaseStringUTFChars(env, file, _file);
+ return false;
+ }
+ //TODO 非常重要,必须清空文件!
+ ftruncate(fileno(ifp), 0);
+ setbuf(stdin, NULL);
+ //谨记释放内存!
+ (*env)->ReleaseStringUTFChars(env, file, _file);
+ return true;
+}
+
+/*
+ * 标准输出重定向!
+ * */
+jboolean Close(JNIEnv *env, jclass clz, jstring file, jint type) {
+ //判断传入的参数的可用性!
+ if (!file) return false;
+ jboolean isCopy = false;
+ //解析为char *;
+ const char *_file = (*env)->GetStringUTFChars(env, file, &isCopy);
+ bool ret = true;
+ //尝试打开文件
+ switch (type) {
+ case 0:
+ //尝试关闭句柄!
+ if (ofp) {
+ if (fclose(ofp) == 0) {
+ ret = false;
+ } else {
+ ret = true;
+ }
+ ofp = NULL;
+ }
+ break;
+ case 1:
+ //尝试关闭句柄!
+ if (efp) {
+ if (fclose(efp) == 0) {
+ ret = false;
+ } else {
+ ret = true;
+ }
+ efp = NULL;
+ }
+ break;
+ case 2:
+ //尝试关闭句柄!
+ if (ifp) {
+ if (fclose(ifp) == 0) {
+ ret = false;
+ } else {
+ ret = true;
+ }
+ ifp = NULL;
+ }
+ break;
+ default:
+ //谨记释放内存!
+ (*env)->ReleaseStringUTFChars(env, file, _file);
+ return false;
+ }
+ //谨记释放内存!
+ (*env)->ReleaseStringUTFChars(env, file, _file);
+ return (jboolean) ret;
+}
+
+//清空标准输入缓冲区!
+void clearStdIN(JNIEnv *env, jclass clz) {
+ if (ifp) {
+ //在循环中读取有效字符,相当于清空缓冲区!
+ char tmp[1];
+ int fd = fileno(ifp);
+ if (fd != -1) {
+ while (read(fd, tmp, 1) > 0);
+ }
+ }
+}
+
+/*
+ * 更改工作目录
+ * */
+jboolean chdir_m(JNIEnv *env, jclass clz, jstring path) {
+ //判断传入的参数的可用性!
+ if (!path) return false;
+ jboolean isCopy = false;
+ //解析为char *;
+ const char *_path = (*env)->GetStringUTFChars(env, path, &isCopy);
+ // 更改工作目录
+ jboolean ret = (jboolean) (chdir(_path) != 0);
+ //谨记释放内存!
+ (*env)->ReleaseStringUTFChars(env, path, _path);
+ return ret;
+}
+
+/*
+ * jvm加载so时的映射回调
+ * */
+JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+ JNIEnv *jniEnv = NULL;
+ //得到当前的jvm环境指针
+ if ((*vm)->GetEnv(vm, (void **) &jniEnv, JNI_VERSION_1_4) != JNI_OK) return -1;
+ //初始化全局的jvm函数指针
+ (*jniEnv)->GetJavaVM(jniEnv, &vm);
+ //得到native函数的定义类
+ jclass clazz = (*jniEnv)->FindClass(jniEnv, "cn/rrg/freo/IORedirector");
+ if (clazz == NULL) {
+ return -1;
+ }
+ //构建和初始化函数结构体,分别是java层的函数名称,签名,对应的函数指针
+ JNINativeMethod methods[] = {
+ {"setStdEO", "(Ljava/lang/String;I)Z", (void *) SetStdEO},
+ {"setStdIN", "(Ljava/lang/String;)Z", (void *) SetStdIN},
+ {"clearStdIN", "()V", (void *) clearStdIN},
+ {"close", "(Ljava/lang/String;I)Z", (void *) Close},
+ {"chdir", "(Ljava/lang/String;)Z", (void *) chdir_m}
+ };
+ //注册函数
+ if ((*jniEnv)->RegisterNatives(jniEnv, clazz, methods, sizeof(methods) / sizeof(methods[0])) !=
+ JNI_OK) {
+ return -1;
+ }
+ //最后一定要返回jni的版本。
+ return JNI_VERSION_1_4;
+}
\ No newline at end of file
diff --git a/redirector/src/main/java/cn/rrg/freo/IORedirector.java b/redirector/src/main/java/cn/rrg/freo/IORedirector.java
new file mode 100644
index 00000000..6a73f62c
--- /dev/null
+++ b/redirector/src/main/java/cn/rrg/freo/IORedirector.java
@@ -0,0 +1,69 @@
+package cn.rrg.freo;
+
+/*
+ * 标准流重定向工具!
+ * */
+public class IORedirector {
+
+ static {
+ //加载动态库!
+ System.loadLibrary("freopen");
+ }
+
+ /**
+ * 规范化类型传递!
+ * STD_OUT 标准输出
+ * STD_ERR 标准异常
+ * STD_IN 标准输入!
+ */
+ public static final int STD_OUT = 0;
+ public static final int STD_ERR = 1;
+ public static final int STD_IN = 2;
+
+ /**
+ * 设置STDOUT、STDERR的重定向!
+ *
+ * @param file 文件地址,绝对路径!
+ * @param type 类型,O或者E,对应{STD_OUT}、{STD_ERR}
+ * @return 设置结果,可能的结果:文件不存在、文件无权限、文件被占用 or 成功!
+ */
+ public static native boolean setStdEO(String file, int type);
+
+ /**
+ * 设置的STD_IN重定向!
+ *
+ * @param file 文件地址,绝对路径!
+ * @return 设置结果,可能的结果:文件不存在、文件无权限、文件被占用 or 成功!
+ */
+ public static native boolean setStdIN(String file);
+
+ //清空标准输入的缓冲区,防止多次执行stop的误判!
+ public static native void clearStdIN();
+
+ /**
+ * 关闭重定向,实际是关闭底层的文件!
+ * * @param file 文件地址,绝对路径!
+ */
+ public static native boolean close(String file, int type);
+
+ /* *//*
+ * 进行重定向的流的flush,根据系统的实现不一定可用!
+ * @param 0 = out, 1 = err
+ * *//*
+ public static native void flushStdEO(int type);
+
+ *//*
+ * 进行重定向文件的清空,与BUF的清空
+ * @param type 需要被清空的标准流的类型,同上!
+ * *//*
+ public static native void resetStdEO(int type);*/
+
+ /**
+ * 更改工作目录,使一些相对路径的函数可以发现相关的文件
+ *
+ * @param path 绝对路径,最终程序的工作目录
+ * @return 设置结果,如果参数不符合需求或者没有权限将会返回false,
+ * 设置成功返回true
+ */
+ public static native boolean chdir(String path);
+}
diff --git a/redirector/src/main/res/values/strings.xml b/redirector/src/main/res/values/strings.xml
new file mode 100644
index 00000000..2c5844dd
--- /dev/null
+++ b/redirector/src/main/res/values/strings.xml
@@ -0,0 +1 @@
+
diff --git a/settings.gradle b/settings.gradle
index 61d556df..1e5b7277 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,4 +1,4 @@
include ':app_main', ':chameleon', ':communication', ':libnfc_pn53x'
-include ':pm3flasher', ':pm3rdv4rrg'
-include ':xmodem', ':utils'
-include ':termux-app', ':terminal-emulator', ':terminal-view'
\ No newline at end of file
+include ':pm3flasher', ':pm3rdv4rrg', ':utils'
+include ':termux-app', ':terminal-emulator', ':terminal-view'
+include ':console', ':crapto1', ':iobridges', ':redirector', ':mfkey', ':nfctag'
\ No newline at end of file
diff --git a/termux-app/src/main/java/com/termux/app/TermuxActivity.java b/termux-app/src/main/java/com/termux/app/TermuxActivity.java
index ed525dd6..6b3776c2 100644
--- a/termux-app/src/main/java/com/termux/app/TermuxActivity.java
+++ b/termux-app/src/main/java/com/termux/app/TermuxActivity.java
@@ -165,8 +165,8 @@ public final class TermuxActivity extends Activity implements ServiceConnection
void checkForFontAndColors() {
try {
- @SuppressLint("SdCardPath") File fontFile = new File("/data/data/" + TermuxService.packageName + "/files/home/.termux/font.ttf");
- @SuppressLint("SdCardPath") File colorsFile = new File("/data/data/" + TermuxService.packageName + "/files/home/.termux/colors.properties");
+ @SuppressLint("SdCardPath") File fontFile = new File("/data/data/" + TermuxService.PACKAGE_NAME + "/files/home/.termux/font.ttf");
+ @SuppressLint("SdCardPath") File colorsFile = new File("/data/data/" + TermuxService.PACKAGE_NAME + "/files/home/.termux/colors.properties");
final Properties props = new Properties();
if (colorsFile.isFile()) {
@@ -630,19 +630,22 @@ public final class TermuxActivity extends Activity implements ServiceConnection
return null;
}
- public static String getPM3ClientPath() {
- String file = TermuxService.HOME_PATH +
+ /**
+ * Get pm3 client file path
+ * old path is on app internal file path
+ * now we are use jnilib path
+ */
+ public String getPM3ClientPath() {
+ return getNativePath() +
File.separator +
- "proxmark3" +
- File.separator +
- "proxmark3_" +
- getABISupported(true);
- try {
- Os.chmod(file, 0700);
- } catch (ErrnoException e) {
- e.printStackTrace();
- }
- return file;
+ "libpm3rrg_cmd.so";
+ }
+
+ public String getNativePath() {
+ String ss = getApplicationInfo().nativeLibraryDir;
+ if (ss == null)
+ ss = getFilesDir().getPath() + "/lib";
+ return ss;
}
void addNewSession(boolean failSafe, String sessionName) {
diff --git a/termux-app/src/main/java/com/termux/app/TermuxService.java b/termux-app/src/main/java/com/termux/app/TermuxService.java
index b8ec27a3..8fbed3e7 100644
--- a/termux-app/src/main/java/com/termux/app/TermuxService.java
+++ b/termux-app/src/main/java/com/termux/app/TermuxService.java
@@ -47,31 +47,31 @@ public final class TermuxService extends Service implements SessionChangedCallba
private static final String NOTIFICATION_CHANNEL_ID = "termux_notification_channel";
// My main app package name.(important)
- public static final String packageName = "com.rfidresearchgroup.rfidtools";
+ public static final String PACKAGE_NAME = "com.rfidresearchgroup.rfidtools";
/**
* Note that this is a symlink on the Android M preview.
*/
@SuppressLint("SdCardPath")
- public static final String FILES_PATH = "/data/data/" + packageName + "/files";
+ public static final String FILES_PATH = "/data/data/" + PACKAGE_NAME + "/files";
public static final String PREFIX_PATH = FILES_PATH + "/usr";
public static final String HOME_PATH = FILES_PATH + "/home";
public static String PM3_CWD = null;
private static final int NOTIFICATION_ID = 1337;
- public static final String ACTION_STOP_SERVICE = packageName + ".service_stop";
- public static final String ACTION_LOCK_WAKE = packageName + ".service_wake_lock";
- public static final String ACTION_UNLOCK_WAKE = packageName + ".service_wake_unlock";
+ public static final String ACTION_STOP_SERVICE = PACKAGE_NAME + ".service_stop";
+ public static final String ACTION_LOCK_WAKE = PACKAGE_NAME + ".service_wake_lock";
+ public static final String ACTION_UNLOCK_WAKE = PACKAGE_NAME + ".service_wake_unlock";
/**
* Intent action to launch a new terminal session. Executed from TermuxWidgetProvider.
*/
- public static final String ACTION_EXECUTE = packageName + ".service_execute";
+ public static final String ACTION_EXECUTE = PACKAGE_NAME + ".service_execute";
- public static final String EXTRA_ARGUMENTS = packageName + ".execute.arguments";
+ public static final String EXTRA_ARGUMENTS = PACKAGE_NAME + ".execute.arguments";
- public static final String EXTRA_CURRENT_WORKING_DIRECTORY = packageName + ".execute.cwd";
- private static final String EXTRA_EXECUTE_IN_BACKGROUND = packageName + ".execute.background";
+ public static final String EXTRA_CURRENT_WORKING_DIRECTORY = PACKAGE_NAME + ".execute.cwd";
+ private static final String EXTRA_EXECUTE_IN_BACKGROUND = PACKAGE_NAME + ".execute.background";
/**
* This service is only bound from inside the same process and never uses IPC.
diff --git a/utils/src/main/java/cn/dxl/common/util/AssetsUtil.java b/utils/src/main/java/cn/dxl/common/util/AssetsUtil.java
index 9bd9fb91..e1b8dc92 100644
--- a/utils/src/main/java/cn/dxl/common/util/AssetsUtil.java
+++ b/utils/src/main/java/cn/dxl/common/util/AssetsUtil.java
@@ -3,25 +3,22 @@ package cn.dxl.common.util;
import android.content.Context;
import android.content.res.AssetManager;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
/*
* 针对Assets进行操作的类!
* */
public class AssetsUtil {
- private AssetManager manager;
-
- public AssetsUtil(Context context) {
- manager = context.getAssets();
- }
-
- // 得到 assets指定目录下的所有文件!
- public String[] getFiles(String root) {
+ public static String[] getFiles(Context context, String root) {
String[] files = new String[0];
+ AssetManager manager = context.getAssets();
try {
files = manager.list(root);
} catch (IOException e) {
@@ -31,13 +28,11 @@ public class AssetsUtil {
return files;
}
- // 复制 assets中的文件到指定目录
- public boolean copyFile(String asFile, String targetPath) {
+ public static boolean copyFile(Context context, String asFile, String targetPath) {
File file = new File(targetPath);
if (!FileUtils.createFile(file)) return false;
boolean ret = false;
- //移动默认key文件
- AssetManager am = manager;
+ AssetManager am = context.getAssets();
InputStream is = null;
try (FileOutputStream fos = new FileOutputStream(file)) {
byte[] buffer = new byte[1024 * 1024];
@@ -60,9 +55,10 @@ public class AssetsUtil {
return ret;
}
- public boolean isFile(String path) {
+ public static boolean isFile(Context context, String path) {
+ AssetManager am = context.getAssets();
try {
- IOUtils.close(manager.open(path));
+ IOUtils.close(am.open(path));
return true;
} catch (IOException e) {
// e.printStackTrace();
@@ -70,13 +66,13 @@ public class AssetsUtil {
return false;
}
- public void copyDirs(File sourcePath, File targetPath) {
+ public static void copyDirs(Context context, File sourcePath, File targetPath) {
// create target path!
final String rawPath = targetPath.getPath();
targetPath = new File(targetPath + File.separator + sourcePath.getPath());
FileUtils.createPaths(targetPath);
// list files!
- String[] files = getFiles(sourcePath.getPath());
+ String[] files = getFiles(context, sourcePath.getPath());
if (files == null) {
return;
}
@@ -84,11 +80,24 @@ public class AssetsUtil {
for (String fileStr : files) {
File file = new File(sourcePath + File.separator + fileStr);
// if is file, we need copy to target path!
- if (isFile(file.getPath())) {
- copyFile(file.getPath(), targetPath.getPath() + File.separator + file.getName());
+ if (isFile(context, file.getPath())) {
+ copyFile(context, file.getPath(), targetPath.getPath() + File.separator + file.getName());
} else {
- copyDirs(file, new File(rawPath));
+ copyDirs(context, file, new File(rawPath));
}
}
}
+
+ public static String readLines(Context context, String file) {
+ StringBuilder builder = new StringBuilder();
+ AssetManager am = context.getAssets();
+ try {
+ BufferedReader br = new BufferedReader(new InputStreamReader(am.open(file)));
+ String line;
+ while ((line = br.readLine()) != null) builder.append(line);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return builder.toString();
+ }
}
diff --git a/utils/src/main/java/cn/dxl/common/util/FileUtils.java b/utils/src/main/java/cn/dxl/common/util/FileUtils.java
index 84b65468..c0b8a00e 100644
--- a/utils/src/main/java/cn/dxl/common/util/FileUtils.java
+++ b/utils/src/main/java/cn/dxl/common/util/FileUtils.java
@@ -32,6 +32,7 @@ import java.io.OutputStream;
import java.nio.channels.FileChannel;
import java.text.DecimalFormat;
import java.util.ArrayList;
+import java.util.List;
import cn.dxl.common.R;
@@ -132,6 +133,20 @@ public class FileUtils {
return ArrayUtils.list2Arr(resultList);
}
+ // read all lines to a line
+ public static String readLine(File file) {
+ StringBuilder builder = new StringBuilder();
+ try {
+ String[] lines = readLines(file);
+ for (String line : lines) {
+ builder.append(line);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return builder.toString();
+ }
+
//按匹配的行读取文件
public static String[] readLines(File file, String regex) throws IOException {
String[] resultArray = readLines(file);