北海道情報専門学校 ライフハック研究所のエンベデッドUSBチーム松葉和仁により開発されたUSBSecのmbedに使用するソースコード by 和仁

Dependencies:   SDFileSystem MusicEngine

Fork of mbed-os-example-ble-LED by mbed-os-examples

北海道情報専門学校 ライフハック研究所 エンベデッドUSB USBSec用mbedプログラム

松葉和仁

Revision:
14:be4e43ce1578
Parent:
11:7404978b24e7
Child:
15:c65fdaa7bfc0
--- 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();