北海道情報専門学校 ライフハック研究所のエンベデッドUSBチーム松葉和仁により開発されたUSBSecのmbedに使用するソースコード by 和仁
Dependencies: SDFileSystem MusicEngine
Fork of mbed-os-example-ble-LED by
北海道情報専門学校 ライフハック研究所 エンベデッドUSB USBSec用mbedプログラム
松葉和仁
source/main.cpp
- Committer:
- kazu0o2
- Date:
- 2017-02-03
- Revision:
- 23:64df5e4f1c0c
- Parent:
- 22:ad986f13599d
- Child:
- 24:c0cc460aadef
File content as of revision 23:64df5e4f1c0c:
#include <events/mbed_events.h> #include <mbed.h> #include "SDFileSystem.h" #include "MusicEngine.h" #include "ble/BLE.h" #include "INITService.h"//初期設定とその状態の送信を行う 0x01 #include "PINService.h"//パスワードの認証を行う0x02 #include "USBService.h"//USB機器の接続、切断を行う 0x03 #include "STATEService.h"//認証、電源、USB状態の送信を行う 0x04 #define NEED_CONSOLE_OUTPUT 1 /* Set this if you need debug messages on the console; * it will have an impact on code-size and power consumption. */ #if NEED_CONSOLE_OUTPUT Serial pc(USBTX, USBRX); #define DEBUG(...) { pc.printf(__VA_ARGS__); } #else #define DEBUG(...) /* nothing */ #endif /* #if NEED_CONSOLE_OUTPUT */ DigitalOut alivenessLED(LED1, 0);//システム生存確認LED DigitalOut actuatedLED(LED2, 0);//USB用リレーピン InterruptIn powerSwitch(p17);//パワー検出コード InterruptIn resetSwitch(p18);//リセットボタン DigitalOut speakerD(LED3, 0);//スピーカ省電力化デジタル MusicEngine Speaker(LED4); //SDFileSystem local("local");//SDカードを定義する SDFileSystem sd(p13,p14,p15,p19,"sd"); const static char DEVICE_NAME[] = "USBSec"; static const uint16_t uuid16_list[] = {USBService::USB_SERVICE_UUID,PINService::PIN_SERVICE_UUID,STATEService::STATE_SERVICE_UUID,INITService::INIT_SERVICE_UUID};//testcode static EventQueue eventQueue( /* event count */ 10 * /* event size */ 32 ); USBService *usbServicePtr; PINService *pinServicePtr; STATEService *stateServicePtr; INITService *initServicePtr; bool authenticationInformation = false;//パスワードは登録されているか bool authenticated = false;//パスワード認証を行ったか char password[] = {0x00,0x00,0x00,0x00,0x00,0x00};//デバッグパスワード //http://mag.switch-science.com/2015/06/17/fathersday2015/ void connectAlertOff(); /** *接続時発音 *接続時に発音されるためのキュー */ void connectAlertOn() { DEBUG("connectAlertOn\r\n"); Speaker.play("T160L4CDEFEDC");//非同期だった//7秒? eventQueue.call_in(3000.0f, &connectAlertOff); } /** *接続時発音 *接続時に発音されるためのキュー */ void connectAlertOff() { DEBUG("connectAlertOff\r\n"); speakerD = 0; } /** *接続時発音 *接続時に発音を開始するためのキュー */ void connectAlertStart() { DEBUG("connectAlertStart\r\n"); speakerD = 1; eventQueue.call(&connectAlertOn); } void disconnectAlertOff(); /** *切断時発音 *切断時に発音されるためのキュー */ void disconnectAlertOn() { DEBUG("disconnectAlertOn\r\n"); Speaker.play("T160L4CR4CR4CR4CR4");//非同期だった//非同期じゃないとすべての処理が止まるから当たり前か eventQueue.call_in(3000.0f, &disconnectAlertOff); } /** *切断時発音 *切断時に発音されるためのキュー */ void disconnectAlertOff() { DEBUG("disconnectAlertOff\r\n"); speakerD = 0; } /** *切断時発音 *切断時に発音を開始するためのキュー */ void disconnectAlertStart() { DEBUG("disconnectAlertStart\r\n"); speakerD = 1; eventQueue.call(&disconnectAlertOn); } /** *パワー検出コード *タクトスイッチが押されたときに実行されるキュー */ void togglePowerUp() { DEBUG("PowerUp\r\n"); stateServicePtr->powerStateUpdate(0x01); } /** *パワー検出コード *タクトスイッチが離されたときに実行されるキュー */ void togglePowerDown() { DEBUG("PowerDown\r\n"); stateServicePtr->powerStateUpdate(0x00); //USBの無効化 actuatedLED = 0x00; stateServicePtr->usbStateUpdate(0x00); } /** *パワー検出コード *タクトスイッチが押されたときに実行される関数 */ void powerUp() { // 即実行されるイベント eventQueue.call(&togglePowerUp); } /** *パワー検出コード *タクトスイッチが離されたときに実行される関数 */ void powerDown() { // 即実行されるイベント eventQueue.call(&togglePowerDown); } /** *リセットボタン *タクトスイッチが離されたときに実行されるキュー */ void toggleResetDown() { DEBUG("ResetDown\r\n"); DEBUG("パスワードのリセットを行います\r\n"); //リセットパスワードの書き込み FILE *fp = fopen("/sd/sdtest.txt", "w"); if(fp == NULL) { DEBUG("Could not open file for write\n"); }else{ fprintf(fp, "00\n00\n00\n00\n00\n00\n"); fclose(fp); } //パスワード登録状態のリセット authenticationInformation = false; initServicePtr->stateUpdate(0x00); //パスワード認証状態のリセット authenticated=false; stateServicePtr->authStateUpdate(0x00); DEBUG("パスワードのリセットが完了しました\r\n"); } /** *リセットボタン *タクトスイッチが離されたときに実行される関数 */ void resetDown() { // 即実行されるイベント eventQueue.call(&toggleResetDown); } /** * Bluetooth接続時の操作 */ void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { char mac[6]; DEBUG("peerMAC:%d\r\n",params->peerAddr); DEBUG("peerMAC_length:%d\r\n",sizeof(params->peerAddr)); DEBUG("peerMAC:"); for(int i = 0;i<sizeof(params->peerAddr);i+=1){ mac[i]=params->peerAddr[i]; DEBUG("%02x ", params->peerAddr[i]); } DEBUG("\r\n"); /* DEBUG("peerArrayMAC:%d\r\n",mac); DEBUG("peerArrayMAC_length:%d\r\n",sizeof(mac)); DEBUG("peerArrayMAC:"); for(int i = 0;i<sizeof(mac);i+=1){ DEBUG("%d ", mac[i]); } DEBUG("\r\n"); */ DEBUG("ownAddrMAC:%d\r\n",params->ownAddr); DEBUG("ownAddrMAC_length:%d\r\n",sizeof(params->ownAddr)); DEBUG("ownAddrMAC:"); for(int i = 0;i<sizeof(params->ownAddr);i+=1){ DEBUG("%d ", params->ownAddr[i]); } DEBUG("\r\n"); eventQueue.call(&connectAlertStart); DEBUG("BluetoothConnection!\r\n"); } /** * Bluetooth切断時の操作 */ void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { (void) params; //認証状態の無効化 authenticated = false; stateServicePtr->authStateUpdate(0x00); //USBの無効化 actuatedLED = 0x00; stateServicePtr->usbStateUpdate(0x00); BLE::Instance().gap().startAdvertising(); eventQueue.call(&disconnectAlertStart); DEBUG("BluetoothDisconnection!\r\n"); } /** *動作確認ランプの状態変更 */ void blinkCallback(void) { alivenessLED = !alivenessLED; /* Do blinky on LED1 to indicate system aliveness. */ } /** *パスワードSDカード書き込み *パスワードが変更されたときに実行されるキュー */ void writeSD() { //SDへの書き込み処理 DEBUG("SDカードを開きます\r\n"); FILE *fp = fopen("/sd/sdtest.txt", "w"); if(fp == NULL) { DEBUG("Could not open file for write\n"); }else{ for(int i = 0;i<sizeof(password);i+=1){ fprintf(fp,"%02x", password[i]); fprintf(fp, "\n"); } fclose(fp); } DEBUG("SDカードを閉じます\r\n"); } /** * This callback allows the LEDService to receive updates to the ledState Characteristic. * LEDサービスにて状態変更を受信した際に呼び出されるコールバック * * @param[in] params * Information about the characterisitc being updated. */ void onDataWrittenCallback(const GattWriteCallbackParams *params) { DEBUG("onDataWrittenCallback:"); if (params->handle == initServicePtr->getValueHandle()) { DEBUG("INITService\r\n"); DEBUG("length:%d\r\n",params->len); for(int i = 0;i<params->len;i+=1){ DEBUG("%02x ", params->data[i]); } DEBUG("\r\n"); //認証情報の確認 if(authenticationInformation){ //認証情報が登録されていた場合は登録を行わない DEBUG("認証情報登録済みのため、認証情報の登録を中止します\r\n"); return; } DEBUG("認証情報の登録を開始します\r\n"); for(int i = 0;i<params->len;i+=1){ password[i] = params->data[i]; } DEBUG("PasswordLength:%d\r\n",sizeof(password)); for(int i = 0;i<sizeof(password);i+=1){ DEBUG("%02x ", password[i]); } DEBUG("\r\n"); authenticationInformation = true; initServicePtr->stateUpdate(0x01); // 即実行されるイベント eventQueue.call(&writeSD); DEBUG("認証情報の登録を終了します\r\n"); return; } if(!authenticationInformation){ //認証情報が登録されていない場合は操作を行わない DEBUG("\r\n認証情報未登録のため、操作を中止します\r\n"); return; } if (params->handle == pinServicePtr->getValueHandle()) { DEBUG("PINService\r\n"); DEBUG("length:%d\r\n",params->len); for(int i = 0;i<params->len;i+=1){ DEBUG("%02x ", params->data[i]); } DEBUG("\r\n"); DEBUG("認証を開始します\r\n"); DEBUG("VerificationLength:%d\r\n",params->len); DEBUG("RegisterLength:%d\r\n",sizeof(password)); if(params->len != sizeof(password)){ DEBUG("認証に失敗しました\r\n"); return; } DEBUG("Verification:Register\r\n"); for(int i = 0;i<params->len;i+=1){ DEBUG("%02x", params->data[i]); DEBUG(":"); DEBUG("%02x", password[i]); DEBUG("\r\n"); if(params->data[i]!= password[i]){ DEBUG("認証に失敗しました\r\n"); return; } } authenticated=true; stateServicePtr->authStateUpdate(0x01); DEBUG("認証が完了しました\r\n"); return; } if(!authenticated){ //認証が行われていない場合は操作を行わない DEBUG("\r\n認証がされていないため、操作を中止します\r\n"); return; } if ((params->handle == usbServicePtr->getValueHandle()) && (params->len == 1)) { DEBUG("USBService\r\n"); DEBUG("length:%d\r\n",params->len); for(int i = 0;i<params->len;i+=1){ DEBUG("%d ", params->data[i]); } DEBUG("\r\n"); actuatedLED = *(params->data); stateServicePtr->usbStateUpdate(*(params->data)); return; } } /** * This function is called when the ble initialization process has failled * BLEの初期化失敗のコールバック */ void onBleInitError(BLE &ble, ble_error_t error) { DEBUG("BluetoothError!\r\n"); /* Initialization error handling should go here */ } /** * Callback triggered when the ble initialization process has finished * BLEの初期化が完了したときに呼び出されるコールバック */ void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) { BLE& ble = params->ble; ble_error_t error = params->error; if (error != BLE_ERROR_NONE) { /* In case of error, forward the error handling to onBleInitError */ /* エラーがあった場合はここから上の'onBleInitError'が呼び出される */ onBleInitError(ble, error); return; } /* Ensure that it is the default instance of BLE */ /* BLEのデフォルトインスタンスであることを確認 */ if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { return; } ble.gap().onDisconnection(disconnectionCallback); ble.gap().onConnection(connectionCallback); ble.gattServer().onDataWritten(onDataWrittenCallback); bool initialValueForUSBUSBCharacteristic = false; usbServicePtr = new USBService(ble, initialValueForUSBUSBCharacteristic); char initialValueForPINPINCharacteristic[] = {0x00,0x00,0x00,0x00,0x00,0x00}; pinServicePtr = new PINService(ble, initialValueForPINPINCharacteristic); char initialValueForSTATEAUTHCharacteristic = 0x00; char initialValueForSTATEPOWERCharacteristic = 0x00; char initialValueForSTATEUSBCharacteristic = 0x00; stateServicePtr = new STATEService(ble, initialValueForSTATEAUTHCharacteristic, initialValueForSTATEPOWERCharacteristic, initialValueForSTATEUSBCharacteristic); char initialValueForINITSETCharacteristic[] = {0x00,0x00,0x00,0x00,0x00,0x00}; char initialValueForINITGETCharacteristic = authenticationInformation; initServicePtr = new INITService(ble, initialValueForINITSETCharacteristic,initialValueForINITGETCharacteristic); /* setup advertising */ /* BLEクライアントへの広告の設定 */ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.gap().setAdvertisingInterval(1000); /* 1000ms. */ ble.gap().startAdvertising(); DEBUG("BluetoothStart!\r\n"); } void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { BLE &ble = BLE::Instance(); eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); } int main() { //SDカードパスワードの取得 char charpass;//SDカードから取得されたパスワード FILE *fp = fopen("/sd/sdtest.txt", "r"); if(fp == NULL) { DEBUG("Could not open file for write\n"); }else{ int passwordindex = 0; //パスワードを取り出しパスワード変数へ while( fscanf( fp, "%02x",&charpass ) != EOF ){ DEBUG("%02x\r\n",charpass); password[passwordindex] = charpass; passwordindex+=1; } fclose(fp); } //起動時の認証情報状態の設定 authenticationInformation = false; DEBUG("PasswordLength:%d\r\n",sizeof(password)); for(int i = 0;i<sizeof(password);i+=1){ DEBUG("%d ", password[i]); if(password[i] != 0x00){ authenticationInformation = true; } } DEBUG("\r\n"); powerSwitch.mode(PullUp);//パワー検出コード_スイッチピンをPullUpに powerSwitch.fall(&powerUp);//パワー検出コード_スイッチが押されたときの割り込み処理 powerSwitch.rise(&powerDown);//パワー検出コード_スイッチが離されたときの割り込み処理 resetSwitch.mode(PullUp);//リセットボタン_スイッチピンをPullUpに resetSwitch.rise(&resetDown);//リセットボタン_スイッチが離されたときの割り込み処理 eventQueue.call_every(500, blinkCallback); BLE &ble = BLE::Instance(); ble.onEventsToProcess(scheduleBleEventsProcessing); ble.init(bleInitComplete); //パスワード設定情報のBluetoothへの反映 if(authenticationInformation){ initServicePtr->stateUpdate(0x01); } eventQueue.dispatch_forever(); return 0; }