Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

905 řádky
20 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Runtime.InteropServices;
  6. using System.Diagnostics.Contracts;
  7. using System.Net;
  8. using Gps.Plugin.Common.Helpers;
  9. using System.IO;
  10. using System.Collections;
  11. namespace Gps.Plugin.Tcp.GT808
  12. {
  13. public class PackHelper
  14. {
  15. public static byte[] ToBytes(string deviceId, MessageIds messageId, ushort seqNO, byte[] bodyBytesReturn)
  16. {
  17. HeadPack head = new HeadPack()
  18. {
  19. BodyProp = 0,
  20. MessageId = (ushort)messageId,
  21. SeqNO = seqNO
  22. };
  23. head.SetDeviceId(deviceId);
  24. //BodyPropertyHelper.SetMessageLength(ref head.BodyProp,(ushort)bodyBytesReturn.Length);
  25. BodyPropertyHelper.SetMessageLength(ref head.BodyProp, (ushort)bodyBytesReturn.Length);
  26. return RawFormatter.Instance.Struct2Bytes(head).Concat(bodyBytesReturn).ToArray();
  27. }
  28. public static byte[] DecodeBytes(byte[] buffer)
  29. {
  30. return DecodeBytes(buffer, 0, buffer.Length);
  31. }
  32. public static byte[] DecodeBytes(byte[] bytes, int offset, int length)
  33. {
  34. int index = 0;
  35. int endOffset = Math.Min(length, bytes.Length - offset) + offset;
  36. for (int i = offset; i < endOffset; )
  37. {
  38. if (bytes[i] == 0x7d && bytes[i + 1] == 0x02)
  39. {
  40. bytes[index++] = 0x7e;
  41. i += 2;
  42. }
  43. else if (bytes[i] == 0x7d && bytes[i + 1] == 0x01)
  44. {
  45. bytes[index++] = 0x7d;
  46. i += 2;
  47. }
  48. else
  49. {
  50. bytes[index++] = bytes[i++];
  51. }
  52. }
  53. return bytes.Take(index).ToArray();
  54. }
  55. public static byte[] EncodeBytes(IEnumerable<byte> bytes)
  56. {
  57. MemoryStream ms = new MemoryStream();
  58. foreach (var b in bytes)
  59. {
  60. if (b == 0x7e)
  61. {
  62. ms.WriteByte(0x7d);
  63. ms.WriteByte(0x02);
  64. }
  65. else if (b == 0x7d)
  66. {
  67. ms.WriteByte(0x7d);
  68. ms.WriteByte(0x01);
  69. }
  70. else
  71. {
  72. ms.WriteByte(b);
  73. }
  74. }
  75. return ms.ToArray();
  76. }
  77. /// <summary>
  78. /// 计算校验位
  79. /// </summary>
  80. /// <param name="bytes"></param>
  81. /// <param name="offset"></param>
  82. /// <param name="count"></param>
  83. /// <returns></returns>
  84. public static byte CalcCheckByte(byte[] bytes, int offset, int count)
  85. {
  86. if (count == 0)
  87. return 0;
  88. byte ret = bytes[offset];
  89. for (int i = offset + 1; i < offset + count; ++i)
  90. {
  91. ret ^= bytes[i];
  92. }
  93. return ret;
  94. }
  95. /// <summary>
  96. /// 计算校验位
  97. /// </summary>
  98. /// <param name="bytes"></param>
  99. public static void CalcCheckByte(byte[] bytes)
  100. {
  101. if (bytes.Length == 0)
  102. return;
  103. bytes[bytes.Length - 1] = CalcCheckByte(bytes, 0, bytes.Length - 1);
  104. }
  105. }
  106. /*
  107. 车载GPS定位器通信协议(GT808)(TCP_6004).pdf
  108. P2
  109. *
  110. * 7E-01-02-00-06-00-20-47-05-52-32-00-00-30-31-32-33-34-35-06-7E
  111. */
  112. [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  113. public class HeadPack
  114. {
  115. public static byte FixPrefix = 0x7e;
  116. public static Int32 PackSize = Marshal.SizeOf(typeof(HeadPack));
  117. /// <summary>
  118. /// 消息 ID
  119. /// </summary>
  120. public BigEndianUInt16 MessageId;
  121. /// <summary>
  122. /// 消息体属性
  123. /// </summary>
  124. public BigEndianUInt16 BodyProp;
  125. /// <summary>
  126. /// 终端手机号
  127. /// </summary>
  128. protected BCD8421_6BytesString DeviceId;
  129. /// <summary>
  130. /// 自增一序列号
  131. /// </summary>
  132. public BigEndianUInt16 SeqNO;
  133. public string GetDeviceId()
  134. {
  135. //return string.Concat("460", DeviceId);
  136. return DeviceId;
  137. }
  138. public void SetDeviceId(string value)
  139. {
  140. if (value.Length > 12)
  141. {
  142. DeviceId = value.Substring(value.Length - 12, 12);
  143. }
  144. else
  145. {
  146. DeviceId = value.PadLeft(12, '0');
  147. }
  148. }
  149. }
  150. public static class BodyPropertyHelper
  151. {
  152. /// <summary>
  153. /// 9-0 BIT
  154. /// </summary>
  155. /// <param name="val"></param>
  156. /// <returns></returns>
  157. public static Int16 GetMessageLength(BigEndianUInt16 val)
  158. {
  159. return (Int16)((UInt16)val & 0x03ff);
  160. }
  161. /// <summary>
  162. /// 9-0 BIT
  163. /// </summary>
  164. /// <param name="val"></param>
  165. /// <returns></returns>
  166. public static void SetMessageLength(ref BigEndianUInt16 val, UInt16 length)
  167. {
  168. val = (UInt16)(((UInt16)val & (~0x03ff)) + length);
  169. }
  170. /// <summary>
  171. /// 12-10 BIT
  172. /// </summary>
  173. /// <param name="val"></param>
  174. /// <returns></returns>
  175. public static Byte GetEncodeType(BigEndianUInt16 val)
  176. {
  177. return (Byte)((val >> 10) & 0x03);
  178. }
  179. public static void SetEncodeType(ref BigEndianUInt16 val, byte encType)
  180. {
  181. ushort v = val;
  182. v = (ushort)(v & ~(0x03 << 10) + encType << 10);
  183. val = v;
  184. }
  185. /// <summary>
  186. /// 13 BIT
  187. /// </summary>
  188. /// <param name="val"></param>
  189. /// <returns></returns>
  190. public static bool IsMutliPack(this BigEndianUInt16 val)
  191. {
  192. return ((val >> 13) & 0x01) == 0x0001;
  193. }
  194. }
  195. [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  196. public class PackProperty
  197. {
  198. public static Int32 PackSize = Marshal.SizeOf(typeof(PackProperty));
  199. public BigEndianUInt16 Total;
  200. public BigEndianUInt16 Index;
  201. }
  202. [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  203. public class ServerAnswerPack
  204. {
  205. public static Int32 PackSize = Marshal.SizeOf(typeof(ServerAnswerPack));
  206. /// <summary>
  207. /// 流水
  208. /// </summary>
  209. public BigEndianUInt16 SeqNO;
  210. /// <summary>
  211. /// 消息ID
  212. /// </summary>
  213. public BigEndianUInt16 MessageId;
  214. /// <summary>
  215. /// 结果 0:成功/确认 1:失败 2:消息有误 3:不支持 4:报警处理确认
  216. /// </summary>
  217. public byte Result;
  218. }
  219. /// <summary>
  220. /// 终端通用应答
  221. /// </summary>
  222. [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  223. public class ClientAnswerPack
  224. {
  225. public static Int32 PackSize = Marshal.SizeOf(typeof(ServerAnswerPack));
  226. /// <summary>
  227. /// 流水
  228. /// </summary>
  229. public BigEndianUInt16 SeqNO;
  230. /// <summary>
  231. /// 消息ID
  232. /// </summary>
  233. public BigEndianUInt16 MessageId;
  234. /// <summary>
  235. /// 结果 0:成功/确认 1:失败 2:消息有误 3:不支持
  236. /// </summary>
  237. public byte Result;
  238. }
  239. /// <summary>
  240. /// 终端注册 最后是GBK字串,车牌号
  241. /// </summary>
  242. [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  243. public class ClientRegistPack
  244. {
  245. public static Int32 PackSize = Marshal.SizeOf(typeof(ClientRegistPack));
  246. /// <summary>
  247. /// 省
  248. /// </summary>
  249. public BigEndianUInt16 Province;
  250. /// <summary>
  251. /// 市
  252. /// </summary>
  253. public BigEndianUInt16 City;
  254. /// <summary>
  255. /// 制造商
  256. /// </summary>
  257. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
  258. public byte[] Manufacturer;
  259. /// <summary>
  260. /// 终端型号
  261. /// </summary>
  262. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
  263. public byte[] DeviceModel;
  264. /// <summary>
  265. /// 终端ID
  266. /// </summary>
  267. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
  268. public byte[] DeviceId;
  269. /// <summary>
  270. /// 车牌颜色
  271. /// </summary>
  272. public byte CarColor;
  273. //最后是GBK字串,车牌号
  274. }
  275. [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  276. public class ClientRegistReturnPack
  277. {
  278. /// <summary>
  279. /// 自增一序列号
  280. /// </summary>
  281. public BigEndianUInt16 SeqNum;
  282. /// <summary>
  283. /// 0成功, 1车辆已经注册, 2数据库中无此车辆, 3终端已经被注册, 4数据库中无该终端
  284. /// </summary>
  285. public Byte Result;
  286. }
  287. /// <summary>
  288. /// 位置包汇报
  289. /// </summary>
  290. [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  291. public class PositionReportPack
  292. {
  293. public static Int32 PackSize = Marshal.SizeOf(typeof(PositionReportPack));
  294. /// <summary>
  295. /// 报警标志
  296. /// </summary>
  297. public BigEndianUInt32 AlermFlags;
  298. /// <summary>
  299. /// 状态
  300. /// </summary>
  301. public BigEndianUInt32 State;
  302. /// <summary>
  303. /// 纬度 度*10^6
  304. /// </summary>
  305. public BigEndianUInt32 Latitude;
  306. /// <summary>
  307. /// 经度 度*10^6
  308. /// </summary>
  309. public BigEndianUInt32 Longitude;
  310. /// <summary>
  311. /// 高程 单位为米
  312. /// </summary>
  313. public BigEndianUInt16 Altitude;
  314. /// <summary>
  315. /// 速度 1/10KM/H
  316. /// </summary>
  317. public BigEndianUInt16 Speed;
  318. /// <summary>
  319. /// 方向 0~359 正北为0 顺时针
  320. /// </summary>
  321. public BigEndianUInt16 Direction;
  322. /// <summary>
  323. /// 时间
  324. /// </summary>
  325. public BCD8421_6BytesString Time;
  326. }
  327. /// <summary>
  328. /// 立即拍照命令
  329. /// </summary>
  330. [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  331. public class CmdPhotographePack
  332. {
  333. /// <summary>
  334. /// 通道ID > 0
  335. /// </summary>
  336. public Byte Channel;
  337. /// <summary>
  338. /// 拍摄命令 0表示停止拍摄;0xffff表示录像;其它表示拍摄张数
  339. /// </summary>
  340. public BigEndianUInt16 Cmd;
  341. /// <summary>
  342. /// 拍照间隔,录像时间。 单位为秒,0表示最小间隔拍照或者一直录像
  343. /// </summary>
  344. public BigEndianUInt16 Interval;
  345. /// <summary>
  346. /// 保存标志 1保存 0立即上传
  347. /// </summary>
  348. public byte Deal;
  349. /// <summary>
  350. /// 图像分辨率 0x01:320*240 0x02:640*480 0x03:800*600 0x04:1024*768
  351. /// 0x05:176*144(Qcif) 0x06:352*288(Cif) 0x07:704*288(HALF D1) 0x08:704*546(D1)
  352. /// </summary>
  353. public byte Resolution;
  354. /// <summary>
  355. /// 图像质量 1 ~ 10 1表示质量损失最小, 10表示压缩最大
  356. /// </summary>
  357. public byte Quality;
  358. /// <summary>
  359. /// 亮度 0 ~ 255
  360. /// </summary>
  361. public byte Brightness;
  362. /// <summary>
  363. /// 对比度 0 ~ 127
  364. /// </summary>
  365. public byte Contrast;
  366. /// <summary>
  367. /// 饱和度 0 ~ 127
  368. /// </summary>
  369. public byte Saturation;
  370. /// <summary>
  371. /// 色度 0 ~ 255
  372. /// </summary>
  373. public byte Chroma;
  374. }
  375. [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  376. public class CmdSendTextPack
  377. {
  378. public byte Flag;
  379. /// <summary>
  380. /// 紧急
  381. /// </summary>
  382. public bool IsUrgent
  383. {
  384. get { return (Flag & 0x01) == 0x01; }
  385. set { Flag = (byte)(Flag | 0x01); }
  386. }
  387. /// <summary>
  388. /// 终端显示器显示
  389. /// </summary>
  390. public bool IsDisplay
  391. {
  392. get { return (Flag & 0x04) == 0x04; }
  393. set { Flag = (byte)(Flag | 0x04); }
  394. }
  395. /// <summary>
  396. /// 终端显示器显示
  397. /// </summary>
  398. public bool IsTTS
  399. {
  400. get { return (Flag & 0x08) == 0x08; }
  401. set { Flag = (byte)(Flag | 0x08); }
  402. }
  403. /// <summary>
  404. /// 终端显示器显示
  405. /// </summary>
  406. public bool IsAD
  407. {
  408. get { return (Flag & 0x10) == 0x10; }
  409. set { Flag = (byte)(Flag | 0x10); }
  410. }
  411. //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
  412. //public byte[] MessageBytes;
  413. }
  414. /// <summary>
  415. /// 多媒体数据上传
  416. /// </summary>
  417. [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  418. public class GpsMultimediaUploadPack
  419. {
  420. public static Int32 PackSize = Marshal.SizeOf(typeof(GpsMultimediaUploadPack));
  421. /// <summary>
  422. /// 多媒体ID >0
  423. /// </summary>
  424. public BigEndianUInt32 ID;
  425. /// <summary>
  426. /// 多媒体类型 0:图像 1:音频 2:视频
  427. /// </summary>
  428. public Byte Type;
  429. /// <summary>
  430. /// 多媒体格式编码 0:JPEG 1:TIF 2:MP3 3:WAV 4:WMV
  431. /// </summary>
  432. public byte Format;
  433. /// <summary>
  434. /// 事件项编码 0:平台下发指令 1:定时动作 2:抢劫报警触发 3:碰撞侧翻触发报警 4:保留
  435. /// </summary>
  436. public byte EventCode;
  437. /// <summary>
  438. /// 通道ID > 0
  439. /// </summary>
  440. public Byte Channel;
  441. }
  442. /// <summary>
  443. /// 多媒体数据上传
  444. /// </summary>
  445. [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  446. public class GpsMultimediaReUploadPack
  447. {
  448. public static Int32 PackSize = Marshal.SizeOf(typeof(GpsMultimediaReUploadPack));
  449. /// <summary>
  450. /// 多媒体ID >0
  451. /// </summary>
  452. public BigEndianUInt32 ID;
  453. /// <summary>
  454. /// 多媒体类型 0:图像 1:音频 2:视频
  455. /// </summary>
  456. public Byte Count;
  457. ///// <summary>
  458. ///// 要求重发的下一个包
  459. ///// </summary>
  460. //public Byte NextIndex;
  461. }
  462. public class BitValueState
  463. {
  464. private BitArray bitArray;
  465. public BitValueState(ushort state)
  466. {
  467. this.bitArray = new BitArray(BitConverter.GetBytes(state));
  468. }
  469. /// <summary>
  470. /// ACC 开关
  471. /// </summary>
  472. bool ACC
  473. {
  474. get
  475. {
  476. return bitArray[0];
  477. }
  478. set
  479. {
  480. bitArray[0] = value;
  481. }
  482. }
  483. /// <summary>
  484. /// 是否定位
  485. /// </summary>
  486. //Position = 0x0002,
  487. bool Position
  488. {
  489. get
  490. {
  491. return bitArray[1];
  492. }
  493. set
  494. {
  495. bitArray[1] = value;
  496. }
  497. }
  498. /// <summary>
  499. /// 0北纬 1南纬
  500. /// </summary>
  501. //NorthOrSouth = 0x0004,
  502. bool IsSouth
  503. {
  504. get
  505. {
  506. return bitArray[2];
  507. }
  508. set
  509. {
  510. bitArray[2] = value;
  511. }
  512. }
  513. /// <summary>
  514. /// 0东经 1西经
  515. /// </summary>
  516. //EastOrWest = 0x0008,
  517. bool IsWest
  518. {
  519. get
  520. {
  521. return bitArray[3];
  522. }
  523. set
  524. {
  525. bitArray[3] = value;
  526. }
  527. }
  528. /// <summary>
  529. /// 0运营状态 1停运
  530. /// </summary>
  531. //OperationState = 0x0010,
  532. bool OperationStoped
  533. {
  534. get
  535. {
  536. return bitArray[4];
  537. }
  538. set
  539. {
  540. bitArray[4] = value;
  541. }
  542. }
  543. /// <summary>
  544. /// 经纬度是否加密
  545. /// </summary>
  546. //EncodeLongitudeLatitude = 0x0020,
  547. bool EncodeLongitudeLatitude
  548. {
  549. get
  550. {
  551. return bitArray[5];
  552. }
  553. set
  554. {
  555. bitArray[5] = value;
  556. }
  557. }
  558. /// <summary>
  559. /// 0车辆油路正常 1断开
  560. /// </summary>
  561. //CarOilchannel = 0x0400,
  562. bool CarOilchannelBreaked
  563. {
  564. get
  565. {
  566. return bitArray[10];
  567. }
  568. set
  569. {
  570. bitArray[10] = value;
  571. }
  572. }
  573. /// <summary>
  574. /// 0车辆电子正常 1断开
  575. /// </summary>
  576. //CarCircuit = 0x0800,
  577. bool CarCircuitBreaked
  578. {
  579. get
  580. {
  581. return bitArray[11];
  582. }
  583. set
  584. {
  585. bitArray[11] = value;
  586. }
  587. }
  588. /// <summary>
  589. /// 0车辆车门解锁 1加锁
  590. /// </summary>
  591. //CarDoorLock = 0x1000
  592. bool CarDoorLocked
  593. {
  594. get
  595. {
  596. return bitArray[12];
  597. }
  598. set
  599. {
  600. bitArray[12] = value;
  601. }
  602. }
  603. }
  604. public class BitValueAlerm
  605. {
  606. //private uint data;
  607. private BitArray bitArray;
  608. public BitValueAlerm(UInt32 alerm)
  609. {
  610. //this.data = alerm;
  611. bitArray = new BitArray(new int[] { (int)alerm });
  612. }
  613. /// <summary>
  614. /// 紧急报警, 触动报警开关后触发 收到答应后清除
  615. /// </summary>
  616. bool Urgent
  617. {
  618. get
  619. {
  620. return bitArray[0];
  621. }
  622. set
  623. {
  624. bitArray[0] = value;
  625. }
  626. }
  627. /// <summary>
  628. /// 超速报警 标志维持到报警条件解除
  629. /// </summary>
  630. bool Speeding
  631. {
  632. get
  633. {
  634. return bitArray[1];
  635. }
  636. set
  637. {
  638. bitArray[1] = value;
  639. }
  640. }
  641. /// <summary>
  642. /// 疲劳驾驶 标志维持到报警条件解除
  643. /// </summary>
  644. bool Fatigue
  645. {
  646. get
  647. {
  648. return bitArray[2];
  649. }
  650. set
  651. {
  652. bitArray[2] = value;
  653. }
  654. }
  655. /// <summary>
  656. /// 预警 收到答应后清除
  657. /// </summary>
  658. bool Forewarning
  659. {
  660. get
  661. {
  662. return bitArray[3];
  663. }
  664. set
  665. {
  666. bitArray[3] = value;
  667. }
  668. }
  669. //TODO:未完, 以后用到添加
  670. }
  671. public enum MessageIds : ushort
  672. {
  673. /// <summary>
  674. /// 终端通用应答
  675. /// </summary>
  676. ClientAnswer = 0x0001,
  677. /// <summary>
  678. /// 终端心跳
  679. /// </summary>
  680. ClientPump = 0x0002,
  681. /// <summary>
  682. /// 终端注销
  683. /// </summary>
  684. ClientUnregist = 0x0003,
  685. /// <summary>
  686. /// 终端注册
  687. /// </summary>
  688. ClientRegist = 0x0100,
  689. /// <summary>
  690. /// 终端鉴权
  691. /// </summary>
  692. ClientAuth = 0x0102,
  693. /// <summary>
  694. /// 位置信息汇报
  695. /// </summary>
  696. PositionReport = 0x0200,
  697. /// <summary>
  698. /// 多媒体事件信息上传
  699. /// </summary>
  700. MultimediaEventUpload = 0x0800,
  701. /// <summary>
  702. /// 多媒体数据上传
  703. /// </summary>
  704. MultimediaUpload = 0x0801,
  705. /// <summary>
  706. /// 多媒体数据上传
  707. /// </summary>
  708. MultimediaUploadAnswer = 0x8800,
  709. /// <summary>
  710. /// 平台通用应答
  711. /// </summary>
  712. ServerAnswer = 0x8001,
  713. /// <summary>
  714. /// 终端注册应答
  715. /// </summary>
  716. ClientRegistReturn = 0x8100,
  717. /// <summary>
  718. /// 立即拍照
  719. /// </summary>
  720. Photographe = 0x8801,
  721. /// <summary>
  722. /// 下发文本
  723. /// </summary>
  724. SendTextMessage = 0x8300
  725. }
  726. }