クラス構成図
using System; using System.IO.Ports; using System.Linq; using System.Text; using Util; namespace BluetoothModule { public class Bluetooth { public delegate void Delegate(string message); Delegate callback; SerialPort serialPort; StringBuilder receiveDataLengthBuffer; StringBuilder receiveDataBuffer; bool receiveFlg;
コンストラクタ
string portName ポート名
Delegate function ファンクション
なし
・指定したポート名、ボーレート、パリティビット、データビット(Archでは8ビット固定)、およびストップビット(Archでは1ビット固定)を使用して、SerialPort クラスのインスタンスを初期化
・初期処理
・コールバック登録
・データ受信イベントハンドラ登録
// コンストラクタ
public BlueTooth(string portName, int bauRate, string p, Delegate function) {
serialPort = new SerialPort(portName, bauRate, parity, 8, StopBits.One);
serialPort.WriteBufferSize = 32 * 1024; // 送信データサイズ(32KB)
serialPort.ReadBufferSize = 32 * 1024; // 受信データサイズ(32KB)
callback = function;
serialPort.DataReceived += new SerialDataReceivedEventHandler(ReceiveMsg);
}
シリアルポートを開く
なし
Boolean処理結果
・ポートオープン
// シリアルポートオープン
public bool PortOpen() {
bool isOpen = false;
// ポートが開放されていない場合は開放する
if (!serialPort.IsOpen) {
serialPort.Open();
}
if (serialPort.IsOpen) {
receiveDataLengthBuffer = new StringBuilder();
receiveDataBuffer = new StringBuilder();
receiveFlg = false;
isOpen = true;
}
return isOpen;
}
シリアルポートを閉じる
なし
なし
・ポートクローズ
// シリアルポートクローズ
public void PortClose() {
// ポートオープン前はオブジェクトが無い為何もしない
if (serialPort.IsOpen) {
serialPort.Close();
}
}
要求電文を送信する
string msg 要求電文
※各サービスの要求電文の設定内容については接続仕様書参照
int 処理結果(0:正常、1:エラー)
・Base64エンコード処理呼び出し
・JIS-8単位符号化処理呼び出し
・TVL形式変換処理呼び出し
・ブロック分割(32KB)
・シリアル送信処理呼び出し
// 電文送信 public int SendMsg(string msg) { // シリアルポートがオープンされていれば電文を送信する。 if (serialPort.IsOpen) { if (!string.IsNullOrEmpty(msg)) { // 引数がnullもしくは""でなければ送信 // Base64エンコード msg = Utility.EncodeBase64(msg); // JIS-8単位符号化 byte[] msgArray = Utility.EncodeJis8(msg); // TLV形式に変換 string tlvString = Utility.CreateMassageTLV(msgArray); // 32KBで分割して送信 int stringSize = 2 * 32 * 1024; // 最大送信データサイズ:1バイト当り2文字×32KB int subStringIndex = 0; while (subStringIndex < tlvString.Length) { // 未送信の電文が残っている場合 string tempStr; if (tlvString.Substring(subStringIndex).Length > stringSize) { // 残りの電文内容の文字数が最大送信データサイズより大きい場合 // 残りの文字列から最大送信データサイズ分だけ取り出す tempStr = tlvString.Substring(subStringIndex, stringSize); } else { // 残りの電文内容の文字数が最大送信データサイズに収まる場合 // 残りの文字列を取り出す tempStr = tlvString.Substring(subStringIndex); } // 電文送信 byte[] sendDataByte = Utility.HexToByte(tempStr); SendData(sendDataByte, 0, sendDataByte.Length); // 未送信の電文の開始位置の更新 subStringIndex += tempStr.Length; } return 0; } else { // 引数がnullもしくは""であれば1(エラー)を返却 return 1; } } else { // ポートが開いてなければ1(エラー)を返却 return 1; } }
シリアル送信する
byte[] data 送信電文
int i 開始位置
int length バイト数
なし
・シリアル送信
// シリアル送信
void SendData(byte[] data, int i, int length) {
serialPort.Write(data, i, length);
}
応答電文を受信する
object sender
System.IO.Ports.
SerialDataReceivedEventArgs e
なし
・シリアル受信
・32KB分割を結合
・TLV形式を解析
・JIS-8単位符号復号化
・Base64デコード
・コールバック処理
// 電文受信 void ReceiveMsg(object sender, SerialDataReceivedEventArgs e) { string outmsg = ""; // 受信データを読み込む int rbyte = serialPort.BytesToRead; byte[] buffer = new byte[rbyte]; int read = 0; while (read < rbyte) { int length = serialPort.Read(buffer, read, rbyte - read); read += length; } string readDataStr = Utility.ToHexString(buffer, buffer.Length); // 受信データの識別子をチェックする if (readDataStr.Substring(0, 2) == "ff") { receiveDataLengthBuffer.Clear(); receiveDataBuffer.Clear(); readDataStr = readDataStr.Substring(2); receiveFlg = true; } // 受信データのデータ部レングスをチェックする if (receiveFlg) { for (int i = 0; i < readDataStr.Length; i++) { if (receiveDataLengthBuffer.Length < 8) { // 受信データのデータ部レングスが8バイトになるまで、データ部レングスバッファに1バイトずつ積込む receiveDataLengthBuffer.Append(readDataStr[i]); } else { // データ部レングスが8バイトに満たした場合、残りのデータをデータ部バッファに積込む receiveDataBuffer.Append(readDataStr[i]); } } } // 受信データのデータ部をチェックする if (receiveDataBuffer.Length == int.Parse(receiveDataLengthBuffer.ToString())) { receiveFlg = false; byte[] msgArray = Utility.HexToByte(receiveDataBuffer.ToString()); // JIS-8単位符号復号化 string msg = Utility.DecodeJis8(msgArray); // Base64デコード outmsg = Utility.DecodeBase64(msg); // 電文を返却 callback(outmsg); } } } }
Base64エンコードする
string msg 変換前文字列
string 変換後文字列
・Base64エンコード(76文字ごとに改行を挿入)
namespace Util {
public static class Utility {
// Base64エンコード
public static string EncodeBase64(string msg) {
return Convert.ToBase64String(Encoding.UTF8.GetBytes(msg), Base64FormattingOptions.InsertLineBreaks);
}
Base64デコードする
string msg 変換前文字列
string 変換後文字列
・Base64デコード
// Base64デコード
public static string DecodeBase64(string msg) {
return Encoding.UTF8.GetString(Convert.FromBase64String(msg));
}
JIS-8単位符号化する
string msg 変換前文字列
byte[] 変換後バイト型配列
・JIS-8単位符号化
// JIS8単位符号化
public static byte[] EncodeJis8(string msg) {
return Encoding.UTF8.GetBytes(msg);
}
JIS-8単位符号復号化する
byte[] msgArray 変換前バイト型配列
string msg 変換後文字列
・JIS-8単位符号復号化
// JIS8単位符号復号化
public static string DecodeJis8(byte[] msgArray) {
return Encoding.UTF8.GetString(msgArray);
}
16進数復元処理を行う
string hexStr 変換前文字列
byte[] 変換後バイト型配列
・16進数復元処理
//16進数復元処理
public static byte[] HexToByte(string hexStr) {
int strLength = hexStr.Length / 2;
byte[] bytes = new byte[strLength];
int j = 0;
for (int i = 0; i < strLength; i++) {
bytes[i] = Convert.ToByte(hexStr.Substring(j, 2), 16);
j += 2;
}
return bytes;
}
16進数文字列変換処理を行う
byte[]bytes 変換前バイト型配列
int size 変換前バイト型配列の長さ
string変換後文字列
・16進文字列変換処理
//16進文字列変換処理
public static string ToHexString(byte[] bytes, int size) {
StringBuilder sb = new StringBuilder(size * 2);
for (int i = 0; i < size; i++) {
if (bytes[i] < 16) {
sb.Append('0');
}
sb.Append(Convert.ToString(bytes[i], 16));
}
return sb.ToString();
}
送信電文(TLV形式)の作成を行う
byte[]msgArray 変換前バイト型配列
string変換後文字列
・TLV形式変換処理
//TLV形式変換
public static string CreateMassageTLV(byte[] msgArray) {
StringBuilder sendDataSb = new StringBuilder();
string hexStr = BitConverter.ToString(msgArray);
hexStr = hexStr.Replace("-", "");
sendDataSb.Append("ff");
sendDataSb.Append(string.Format("{0:00000000}", hexStr.Length));
sendDataSb.Append(hexStr);
return sendDataSb.ToString();
}
}
}
コードをコピーしました