龙亿

------ 细细口味人生中的每一杯苦咖啡.

导航

(原创)-智能电能表SM1算法开发套件(主站接口) 开发篇

Posted on 2009-12-12 16:32  龙亿  阅读(2714)  评论(12编辑  收藏  举报

前几天把智能电能表开发中基础大概说了下,今天把如何开发控制远程费程智能电表的跳闸,合闸,报警,报警解除,保电和取消保电;

我们再来看一下TestZhuzhan.dll 中的函数

1. 身份认证函数
函数名称 IdentityAuthentication(char *Div,char *RandAndEndata)
函数功能身份认证取随机数和密文
Div,输入参数,8 字节分散因子,16 进制字符串。
参数说明 RandAndEndata,输出参数,字符型,8 字节随机数+8 字节
密文。
成功标志 0,成功;
200,连接加密机失败;
201,取随机数1 失败;
202,取随机数2 失败;
203,密钥分散失败;
204,数据加密失败;
205,取密文失败;
2.远程控制函数
函数名称 UserControl(char *RandDivEsamNumData,char *dataOut)
函数功能远程控制
RandDivEsamNumData,输入参数,字符型,4 字节随机数
参数说明 +8字节分散因子+8字节ESAM序列号+数据明文。
dataOut,字符型,20 字节密文
成功标志 0,成功;
200,连接加密机失败;
201,写卡失败;
202,读卡失败;
203,计算密文失败;

说明:以上函数测试时需在RD-1000 读卡器中插上测试母卡。

以下为C#代码

先引用DLL:

 /// <summary>
/// 身份认证函数  作者:龙亿
/// </summary>
/// <param name="div">8 字节分散因子,16 进制字符串</param>
/// <param name="RandAndEndata">8 字节随机数+8 字节密文。</param>
/// <returns>0,成功;200,连接加密机失败;201,取随机数1 失败;202,取随机数2 失败;203,密钥分散失败;204,数据加密失败;205,取密文失败;</returns>
[DllImport("TestZhuzhan.dll")]
public static extern int IdentityAuthentication(string div, byte[] RandAndEndata);

/// <summary>
/// 远程控制函数 作者:龙亿
/// </summary>
/// <param name="RandDivEsamNumData">4 字节随机数+8字节分散因子+8字节ESAM序列号+数据明文</param>
/// <param name="dataOut">20 字节密文</param>
/// <returns>0,成功;200,连接加密机失败;201,写卡失败;202,读卡失败;203,计算密文失败;</returns>
[DllImport("TestZhuzhan.dll", CharSet = CharSet.Ansi)]
public static extern int UserControl(string RandDivEsamNumData, byte[] dataOut);

调用DLL文件

string div = "0000000000000008";

/// <summary>
/// 身份认证取随机数和密文 作者:龙亿
/// </summary>
/// <param name="randAndEndata">返回8 字节随机数+8 字节密文。</param>
/// <returns>0,成功;200,连接加密机失败;201,取随机数1 失败;202,取随机数2 失败;203,密钥分散失败;204,数据加密失败;205,取密文失败</returns>
public  int GetIdentityAuthentication(out string randAndEndata)
{
    byte[] value = new byte[32];
    int index = TestZhuZhan.IdentityAuthentication(div, value);

    randAndEndata = Encoding.UTF8.GetString(value);
    return index;
}

/// <summary>
/// 取得20 字节密文 作者:龙亿
/// </summary>
/// <param name="n1">控制码</param>
/// <param name="random2">随机数2</param>
/// <param name="esamId">Esam序列号</param>
/// <param name="date">命令有效截止时间</param>
/// <param name="ciphertext">返回:20字节密文</param>
/// <returns>0,成功;200,连接加密机失败;201,写卡失败;202,读卡失败;203,计算密文失败</returns>
public int GetPassword2(string n1, byte[] random2, byte[] esamId, DateTime date, out string ciphertext)
{
    //4字节随机数+8字节分散因子+8字节ESAM序列号+数据明文(N1-Nm)。
    StringBuilder str = new StringBuilder();
    //4字节随机数
    str.Append(Common.GetHex(random2[3]));
    str.Append(Common.GetHex(random2[2]));
    str.Append(Common.GetHex(random2[1]));
    str.Append(Common.GetHex(random2[0]));
    //8字节分散因子"0000000000000002"
    str.Append(div);
    //8字节ESAM序列号
    str.Append(Common.GetHex(esamId[7]));
    str.Append(Common.GetHex(esamId[6]));
    str.Append(Common.GetHex(esamId[5]));
    str.Append(Common.GetHex(esamId[4]));
    str.Append(Common.GetHex(esamId[3]));
    str.Append(Common.GetHex(esamId[2]));
    str.Append(Common.GetHex(esamId[1]));
    str.Append(Common.GetHex(esamId[0]));
    //n1控制码
    str.Append(n1);
    //保留字符
    str.Append("00");
    //命令有效截止日期
    str.Append(date.ToString("yyMMddHHmmss"));

    byte[] readData = new byte[40];
    int index = TestZhuZhan.UserControl(str.ToString(), readData);

    ciphertext = Encoding.UTF8.GetString(readData);
    return index;
}