내 프로그램과 RS232 통신을 수행하는 하드웨어간 메시지 정상 전송의 무결성을 검증하기 위한 체크섬 기능 도입이 필요하다.
체크섬이란 우리말로 검사합. 직역하면 무언가의 검사 결과, 그 값의 합이 서로 일치되는지 판단할 수 있는 약속을 의미한다.
예를 들어 설명하면...
Send : < OOO >
Recv : [ XXX ]
로 규약된 상호가 통신이 있다고 가정해보자.
이때, ex) < Hello^00 >라는 전송하고자 하는 메시지의 끝에 해당 메시지를 암호화(진수화)한 체크섬 데이터(^00)를 삽입하여 Send의 주체는 자신이 메시지를 정상적으로 보냈다는 일종의 증거를 남기고,
Recv 주체는 수신 받은 메시지 끝의 체크섬 데이터를 다시 암호화하여 체크섬 데이터인 ^00에 맞는 메시지가 정상적으로 들어왔는지 검증하는 과정을 의미하는 것이다.
Send : < Hello^00> ← Hello 메시지의 체크섬 데이터 ^00도 같이 전송
Recv : [ Hello^00 ] ← Recv한 Hello 메시지의 체크섬 데이터를 다시 암호화한 결과, ^00가 맞다는걸 확인하면 [ Hello^00 ]를 Send 주체에게 Recv.
체크섬이 필요한 이유?
데이터 베이스 등의 수학을 통해 데이터 무결성을 배운 사람이라면 이해가 빠를 것이다.
일단 이론은 이쯤 설명하고...
일단 나의 체크섬은 위의 예시처럼 전송하고자하는 데이터의 총합값을 사용하는 방법으로 정해졌다.
소프트웨어가 자동 전송하고자하는 데이터 : < EEP,WRITE,DOWN,PLUS>
이 데이터는 하드웨어가 1회 동작할때마다 하드웨어 내부 칩셋 펌웨어에 동작횟수를 +1 카운트하는 명령어이다.
이외 여러가지 펌웨어에 내리는 명령어가 있지만...
CheckSum이라는 것이 Dll 형식으로 함수만 구현해놓고 갖다 쓰면 되기에...
먼저 테스트를 겸한 프로그래밍을 진행해보도록 하자.
이런저런 체크섬 함수와 기법에 대해 공부 및 테스트 코드 작성을 이어나가다가, 차장님으로부터 Hex값 뒤 2자리를 리턴하는것으로 프로토콜이 정의되었다는 인폼을 듣게 되었다.
그럼 이제 String 값을 Hex 값으로 변환하는 함수를 구현해보도록 하자.
public string GetHexChecksum(string input)
{
int sum = 0;
foreach (char c in input)
{
sum += (int)c;
}
string hexValue = sum.ToString("X");
return hexValue.Substring(0, 2);
}
보다시피 함수 자체는 굉장히 심플하다.
(input 받은 string 값을 모두 Sum하고, 이것을 hexValue로 변환한 뒤 대문자 전환하고, 뒷자리 2자리만 잘라서 return.)
해당 함수를 통해 " [OK "를 CheckSum 변환하면 " F5 "라는 값을 확인할 수 있게 된다.
그런데 잠깐, 여기서 'string의 요소를 다 더하고 뭔가 했더니 F5가 나오네? 뭐지...? 뭔말이지...?' 라는 생각을 할 수 있을 것이다.
(적어도 난 그랬다.)
예를 들어 우리가 보고 사용하는 알파벳 텍스트 A는 16진수(Hex)로 변환시 41이라는 값을 갖게 된다.
그렇기에 위에 내가 적었던 [OK의 각 요소 "[" "O" "K"를 16진수로 변환시 5B 4F 4B 라는 값을 갖게 되는 것이다.
그럼 이제 여기서 나온 Hex값 5B 4F 4B 들을 윈도우가 지원하는 막강한 프로그래머용 계산기를 사용하여
Hex 값을 선택하고
모두 더하면...
위에 CheckSum 함수가 변환했던 F5의 값이 나오는 것을 확인할 수 있게 되는 것이다.
아무튼 그렇게...
내가 보낸 메시지+체크섬과 상대방이 받아서 계산한 메시지+체크섬이 일치할 시 SEND/RECV 통신이 정상적으로 이루어졌다고 보는 것이다.
// 실 사용 예시
string input1 = "<CONTACT1";
string checksum1 = GetHexChecksum(input1);
Store.getInstance().topSerial.Send("<CONTACT1^" + checksum1 + ">");
요구사항: 이라는 메시지의 CheckSum 메시지 <CONTACT1^OO>를 보내고 싶다.
1. ^ 앞자리 문자열을 합하여 CheckSum을 계산하는 것이므로
<CONTACT1 까지를 input1 변수값으로 지정.
2. GetHexChecksumdp input1값을 적용하여 Checksum checksum1를 반환.
3. 보드에 완성된 CheckSum 메시지 "<CONTACT1^" + checksum1 + ">"를 전송.
프로그램 로그 상에는 <CONTACT1^79>를 Send한 것으로 확인.
16진수화 후 계산기를 뚜들겨 보면...
279의 끝자리 2자리이므로~ 정상적으로 CheckSum이 구현되었음을 확인할 수 있다!