using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace BroadcastModule
{
public class BroadcastBoard
{
private UdpClient DUCP_NetSocket;
private IPAddress DeviceIP;
private IPEndPoint RPoint = null;
private IPEndPoint TPoint = null;
private int volume = 10;
//*********************************************** 动态引用dll ******************************************
//实现协议栈数据输出回调函数
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
unsafe delegate byte cbDUCP_DataOutType(byte* Data, int Size);
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
extern static void MB_STK_SetOutCallback(cbDUCP_DataOutType cb);
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe extern static sbyte MB_STK_In(byte* Data, int Size);
//回调对象
private cbDUCP_DataOutType cbDuCP_dataout;
//回调函数实现
unsafe byte cbDUCP_DataOut(byte* Data, int Size)
{
sbyte Ret;
byte[] buff = new byte[256];
byte[] RxBuff = new byte[256];
for (int i = 0; i < Size; i++)
{
buff[i] = Data[i];
}
/*发送数据到显示屏*/
DUCP_NetSocket.Send(buff, Size, TPoint);
/*接收显示屏回复的数据*/
RxBuff = DUCP_NetSocket.Receive(ref RPoint);
/*将显示屏的回复的数据传输给协议栈*/
unsafe
{
fixed (byte* pArray = RxBuff)
Ret = MB_STK_In(pArray, RxBuff.Length);
}
return (byte)Ret;
}
//调节音量
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe extern static byte DUCP_HOST_SYS_SetVol(int vol);
//播放语音
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe extern static byte DUCP_HOST_TTS_Play(byte* pText, byte Opt);
//停止播放语音
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe extern static byte DUCP_HOST_TTS_Stop();
//重启系统
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe extern static byte DUCP_HOST_SYS_Reset();
//显示已存文件
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe extern static byte DUCP_HOST_TWIN_DisFile(int WinID, int FileID);
//显示文本
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe extern static byte DUCP_HOST_TWIN_DisText(int WinID,
byte* pText,
int EnterMode,
int EnterSpeed,
int DelayMode,
int DelayTime,
int EixtMode,
int EixtSpeed,
int FontIndex,
int TextColor,
int BkColor,
int DisTimes);
//创建文本控件
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
extern static byte DUCP_HOST_TWIN_Create(int WinID, int Stile, int x0, int y0, int xSize, int ySize);
//删除文本控件中文本文件
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
extern static byte DUCP_HOST_TWIN_DelFile(int WinID, int FileID);
//删除文本控件
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
extern static byte DUCP_HOST_TWIN_Del(int WinID);
//删除图片控件
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
extern static byte DUCP_HOST_PIC_Del(int WinID);
//设置绘图颜色
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
extern static byte DUCP_HOST_2D_SetColor(int Color);
//填充矩形
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
extern static byte DUCP_HOST_2D_FillRect(int x0, int y0, int x1, int y1);
//绘制系统自带位图
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
extern static byte DUCP_HOST_2D_DrawSysIcon(int x0, int y0, int Num, int Denom, int IconIndex);
//创建图片控件
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
extern static byte DUCP_HOST_PIC_Create(int WinID, int x0, int y0, int xSize, int ySize);
//图片控件追加图片
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
extern static byte DUCP_HOST_PIC_Add(int WinID, int FID, byte EnterMode, byte EnterSpeed,
byte StopMode, byte StopTime, byte ExitMode, byte ExitSpeed);
//更新本地时间
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
extern static byte DUCP_HOST_SYS_UpdateTime(short Year, byte Month, byte Day, byte Week, byte Hour, byte Minute, byte Second);
//更新端口(更新ip方法异常,手动更新)
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe extern static byte DUCP_HOST_SYS_SetPort(int port);
//下载文本文件并与文本控件关联
[DllImport("DUCP.dll", CallingConvention = CallingConvention.Cdecl)]
unsafe extern static byte DUCP_HOST_TWIN_DownTextFile(int WinID,
int FileID,
byte* pText,
int EnterMode,
int EnterSpeed,
int DelayMode,
int DelayTime,
int EixtMode,
int EixtSpeed,
int FontIndex,
int TextColor,
int BkColor);
//************************************************ 方法块 **************************************************
// *************** 私有方法 ***************
///
/// 显示特定行文字
///
///
///
///
private bool DispString(int winID, string str, int time)
{
byte[] buffer = Encoding.Default.GetBytes(str);
if (winID < 0 || winID > 3) { return false; }
unsafe
{
fixed (byte* pArray = buffer)
{
try
{
if (time >= 0 && time <= 255)
{
DUCP_HOST_TWIN_DisText(winID, pArray,
0X15, 1,
0X00, time,
0X15, 1,
3, 0Xff, 0X00, 0);
}
else
{
DUCP_HOST_TWIN_DisText(winID, pArray,
0X15, 1,
0X02, 255,
0X15, 1,
3, 0Xff, 0X00, 0);
}
}
catch (Exception ex) { Console.WriteLine(ex.Message); return false; }
}
}
return true;
}
///
/// 显示多行文字
///
///
///
private bool DispString(string[] strs, int time)
{
bool normal = true;
for (int i = 0; i < 4; i++)
{
normal = DispString(i, strs[i], time);
if (!normal)
{
break;
}
}
return normal;
}
///
/// 配置需循环显示的文字,将导致存储器擦写,请勿频繁调用
///
///
///
private void DownloadString(int winID, string str, int index)
{
unsafe
{
byte[] Buff;
if (str.Equals("time"))
{
Buff = Encoding.Default.GetBytes("`H:`N:`S");
fixed (byte* pArray = Buff)
DUCP_HOST_TWIN_DownTextFile(winID,
index >= 0 ? (index <= 15 ? index : 15) : 0,
pArray,
0X15,
1,
0X08,
255,
0X15,
1,
3,
0XFF,
0);
}
else if (str.Equals("date"))
{
Buff = Encoding.Default.GetBytes("`M月`D日");
fixed (byte* pArray = Buff)
DUCP_HOST_TWIN_DownTextFile(winID,
index >= 0 ? (index <= 15 ? index : 15) : 0,
pArray,
0X15,
1,
0X09,
255,
0X15,
1,
3,
0XFF,
0);
}
else
{
Buff = Encoding.Default.GetBytes(str);
fixed (byte* pArray = Buff)
DUCP_HOST_TWIN_DownTextFile(winID,
index >= 0 ? (index <= 15 ? index : 15) : 0,
pArray,
0X15,
1,
0X02,
255,
0X15,
1,
3,
0XFF,
0);
}
}
}
///
/// 配置需循环显示的文字,将导致存储器擦写,请勿频繁调用。写入多个字符串
///
///
///
private void DownloadString(int winID, string[] strs)
{
for (int i = 0; i < Math.Min(16, strs.Length) && strs[i] != ""; i++)
{
DownloadString(winID, strs[i], i);
}
}
///
/// 显示已载入文本文件
///
///
///
private void DispDownStr(int winID, int fieldID)
{
DUCP_HOST_TWIN_DisFile(winID, fieldID);
}
///
/// 播放语音
///
///
private void AudioPlay(string str)
{
unsafe
{
try
{
byte[] Buff = System.Text.Encoding.Default.GetBytes(str);
fixed (byte* pArray = Buff)
{
DUCP_HOST_TTS_Stop();
DUCP_HOST_TTS_Play(pArray, 0x01);
}
}
catch (Exception ex)
{ Console.WriteLine(ex.Message); }
}
}
///
/// 删除已下载文本文件
///
///
///
///
private void DelFile(int winID, int startIndex, int endIndex)
{
if (winID >= 0 && winID < 4)
{
for (int i = (startIndex >= 0 ? startIndex : 0); i < (endIndex >= 15 ? 15 : endIndex); i++)
{
DUCP_HOST_TWIN_DelFile(winID, i);
}
}
}
///
/// CRC16
///
/// 要进行计算的数组
/// 计算后的数组
private static byte[] CRC16(byte[] crcbuf)
{
int crc = 0xffff;
int len = crcbuf.Length;
byte[] redata = new byte[2];
for (int n = 0; n < len; n++)
{
byte i;
crc = crc ^ crcbuf[n];
for (i = 0; i < 8; i++)
{
int TT;
TT = crc & 1;
crc = crc >> 1;
crc = crc & 0x7fff;
if (TT == 1)
{
crc = crc ^ 0xa001;
}
crc = crc & 0xffff;
}
}
redata[1] = (byte)((crc >> 8) & 0xff);
redata[0] = (byte)((crc & 0xff));
return redata;
}
// *************** 公有方法 ***************
public BroadcastBoard(string ip, int port, int volume = 10)
{
//初始化网络连接配置
DeviceIP = IPAddress.Parse(ip);
RPoint = new IPEndPoint(DeviceIP, port);
TPoint = new IPEndPoint(DeviceIP, port);
//设置协议栈的回调函数
unsafe
{
cbDuCP_dataout = new cbDUCP_DataOutType(cbDUCP_DataOut);
MB_STK_SetOutCallback(cbDuCP_dataout);
}
//GC.KeepAlive(cbDuCP_dataout);
/*#2.创建UDP网络套接字*/
DUCP_NetSocket = new UdpClient();
this.volume = volume;
DUCP_HOST_SYS_SetVol(volume);
//Refresh();
}
public void UpdateTime()
{
DateTime dt = DateTime.Now;
DUCP_HOST_SYS_UpdateTime((short)dt.Year, (byte)dt.Month, (byte)dt.Day, (byte)dt.DayOfWeek, (byte)dt.Hour, (byte)dt.Minute, (byte)dt.Second);
}
///
/// 刷新屏幕
///
public void Refresh()
{
DUCP_HOST_TWIN_Del(0);
DUCP_HOST_TWIN_Del(1);
DUCP_HOST_TWIN_Del(2);
DUCP_HOST_TWIN_Del(3);
DUCP_HOST_TWIN_Create(0, 0, 0, 0, 64, 16);
DUCP_HOST_TWIN_Create(1, 0, 0, 16, 64, 16);
DUCP_HOST_TWIN_Create(2, 0, 0, 32, 64, 16);
DUCP_HOST_TWIN_Create(3, 0, 0, 48, 64, 16);
}
///
/// 音量控制
///
///
public void VolumeControl(int offset, out int vol)
{
volume += offset;
DUCP_HOST_SYS_SetVol(volume);
vol = volume;
}
public void VolumeControl(int vol)
{
DUCP_HOST_SYS_SetVol(volume >= 0 ? (volume <= 50 ? volume : 50) : 0);
}
///
/// 重启机器
///
public void Restart()
{
DUCP_HOST_SYS_Reset();
}
///
/// 配置ip与端口
///
///
///
public void IpConfig(string ip, int port)
{
IPAddress ipa = null;
try
{
ipa = IPAddress.Parse(ip);
if (ipa != null)
{
unsafe
{
try
{
byte[] protocol = new byte[] {
0x00,0x64,0xff,0xff,0x08,0x04,
0x00,0x00,0x00,0x00,
0xE6,0x17
};
byte[] Buff = ipa.GetAddressBytes();
Buff.CopyTo(protocol, 6);
byte[] temp = new byte[10];
Array.Copy(protocol, temp, 10);
byte[] crc = CRC16(temp);
Array.Copy(crc, 0, protocol, 10, 2);
fixed (byte* pArray = protocol)
{
cbDUCP_DataOut(pArray, 12);
}
}
catch (Exception ex)
{ Console.WriteLine(ex.Message); }
}
DUCP_HOST_SYS_SetPort(port);
}
}
catch (Exception ex) { Console.WriteLine(ex.Message); }
}
public enum PlayMode {temporary, download, delete, readBuffer, audio}
///
/// 播放方法
///
/// 显示屏窗口ID
/// 播放模式
/// 待显示或播语音字符串
/// 保持时间
/// 存储块ID
/// 开始下标
/// 结束下标
public void Play(int winID, PlayMode mode, string str,int time=0, int fieldID=0, int startIndex=0, int endIndex=0)
{
switch (mode)
{
case PlayMode.temporary:
DispString(winID, str, time);
break;
case PlayMode.download:
DownloadString(winID, str, fieldID);
break;
case PlayMode.readBuffer:
DispDownStr(winID, fieldID);
break;
case PlayMode.delete:
DelFile(winID, startIndex, endIndex);
break;
case PlayMode.audio:
AudioPlay(str);
break;
}
}
}
}