北海道情報専門学校 ライフハック研究所のエンベデッドUSBチーム松葉和仁により開発されたUSBSecのmbedに使用するソースコード by 和仁
Dependencies: SDFileSystem MusicEngine
Fork of mbed-os-example-ble-LED by
北海道情報専門学校 ライフハック研究所 エンベデッドUSB USBSec用mbedプログラム
松葉和仁
Diff: source/main.cpp
- Revision:
- 14:be4e43ce1578
- Parent:
- 11:7404978b24e7
- Child:
- 15:c65fdaa7bfc0
diff -r c09d82cd2e87 -r be4e43ce1578 source/main.cpp --- a/source/main.cpp Fri Oct 28 13:45:42 2016 +0100 +++ b/source/main.cpp Wed Dec 21 02:56:24 2016 +0000 @@ -1,69 +1,375 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - #include <events/mbed_events.h> #include <mbed.h> +#include "SDFileSystem.h" #include "ble/BLE.h" -#include "LEDService.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); -DigitalOut actuatedLED(LED2, 0); +#define mC 261.626 +#define mD 293.665 +#define mE 329.628 +#define mF 349.228 +#define mG 391.995 +#define mA 440.000 +#define mB 493.883 + +DigitalOut alivenessLED(LED1, 0);//システム生存確認LED +DigitalOut actuatedLED(LED2, 0);//USB用リレーピン -const static char DEVICE_NAME[] = "LED"; -static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID}; +InterruptIn powerSwitch(p17);//パワー検出コード +InterruptIn resetSwitch(p18);//リセットボタン + +PwmOut speaker(LED3);//スピーカ + +//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 ); -LEDService *ledServicePtr; +USBService *usbServicePtr; +PINService *pinServicePtr; +STATEService *stateServicePtr; +INITService *initServicePtr; + +bool authenticationInformation = false;//パスワードは登録されているか +bool authenticated = false;//パスワード認証を行ったか + +char password[] = {0x00,0x00,0x00,0x00,0x00,0x00};//デバッグパスワード + +int connectAlertCount = 0; +float connectAlert[]={mE,mF,mG,mA,mB}; +float disconnectAlert[]={mB,mA,mG,mF,mE}; + +void connectAlertOff(); + +/** + *接続時発音 + *接続時に発音されるためのキュー + */ +void connectAlertOn() { + DEBUG("connectAlertOn\r\n"); + speaker.period(1.0/connectAlert[connectAlertCount]); + speaker.write(0.5f); + queue.call_in(600, &connectAlertOff); +} + +/** + *接続時発音 + *接続時に発音されるためのキュー + */ +void connectAlertOff() { + DEBUG("connectAlertOff\r\n"); + speaker.write(0.0f); + if(connectAlertCount<4){ + queue.call_in(600, &connectAlertOn); + connectAlertCount += 1; + }else{ + DEBUG("connectAlertStop\r\n"); + } +} + +/** + *接続時発音 + *接続時に発音を開始するためのキュー + */ +void connectAlertStart() { + DEBUG("connectAlertStart\r\n"); + connectAlertCount = 0; + queue.call(&connectAlertOn); +} + +/** + *パワー検出コード + *タクトスイッチが押されたときに実行されるキュー + */ +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"); + + 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(); + 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) { - if ((params->handle == ledServicePtr->getValueHandle()) && (params->len == 1)) { + 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) { @@ -72,28 +378,46 @@ 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 initialValueForLEDCharacteristic = false; - ledServicePtr = new LEDService(ble, initialValueForLEDCharacteristic); + 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_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) { @@ -103,11 +427,50 @@ 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();