嵌入式linux之go语言开发(四)go语言8583协议报文解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 嵌入式linux之go语言开发(四)go语言8583协议报文解析

原来的pos用c语言开发的,与银联后台通信走的是8583协议。那么用go来做,得实现个go语言8583协议报文解析


且若想在电脑上跑交易,做个工具。用c语音处理起来不方便。用go还可以在电脑上跑交易。


于是用go语言做一个8583解析,方便使用


https://github.com/yangyongzhen/go8583/


package up8583
import (
  "errors"
  "fmt"
  "go8583/byteutil"
  "go8583/desutil"
  "go8583/easy8583"
  "strconv"
)
var (
  ManNum  string = "000000000000000"
  PosNum  string = "00000000"
  MainKey string = "00000000000000000000000000000000"
  TPDU    string = "6000000000"
  CommSn     int    = 1
  RecSn      int    = 1
  PiciNum    []byte = make([]byte, 3)
  LicenceNum        = []byte{0x33, 0x30, 0x36, 0x30}
  MacKey string = "0000000000000000"
)
type Up8583 struct {
  Ea *easy8583.Easy8583
}
func memcpy(dst, src []byte, size int) {
  for i := 0; i < size; i++ {
    dst[i] = src[i]
  }
  return
}
func equals(src1 []byte, src2 []byte) bool {
  if src1 == nil || src2 == nil {
    return false
  }
  le1 := len(src1)
  le2 := len(src2)
  if le1 != le2 {
    return false
  }
  for i := 0; i < le1; i++ {
    if src1[i] != src2[i] {
      return false
    }
  }
  return true
}
/*
银联8583签到组包
*/
func (up *Up8583) Frame8583QD() {
  s := up.Ea
  field := up.Ea.Field_S
  s.Init8583Fields(field)
  //消息类型
  s.Msgtype[0] = 0x08
  s.Msgtype[1] = 0x00
  //11域,受卡方系统跟踪号BCD 通讯流水
  field[10].Ihave = true
  field[10].Len = 3
  sn := fmt.Sprintf("%06d", CommSn)
  field[10].Data = byteutil.HexStringToBytes(sn)
  //41域,终端号
  field[40].Ihave = true
  field[40].Len = 8
  field[40].Data = []byte(PosNum)
  //42域,商户号
  field[41].Ihave = true
  field[41].Len = 15
  field[41].Data = []byte(ManNum)
  //60域
  field[59].Ihave = true
  field[59].Len = 0x11
  field[59].Data = make([]byte, 6)
  field[59].Data[0] = 0x00
  memcpy(field[59].Data[1:], PiciNum, 3)
  field[59].Data[4] = 0x00
  field[59].Data[5] = 0x30
  //62域
  field[61].Ihave = true
  field[61].Len = 0x25
  field[61].Data = make([]byte, 25)
  str := "Sequence No12"
  memcpy(field[61].Data, []byte(str), 13)
  memcpy(field[61].Data[13:], LicenceNum, 4)
  memcpy(field[61].Data[17:], []byte(PosNum), 8)
  //63域
  field[62].Ihave = true
  field[62].Len = 0x03
  field[62].Data = make([]byte, 3)
  field[62].Data[0] = 0x30
  field[62].Data[1] = 0x30
  field[62].Data[2] = 0x31
  /*报文组帧,自动组织这些域到Pack的TxBuffer中*/
  s.Pack8583Fields()
  CommSn++ //通讯流水每次加一
  //s.PrintFields(up.Ea.Field_S)
}
func (up *Up8583) Ans8583QD(rxbuf []byte, rxlen int) error {
  r := up.Ea
  fields := up.Ea.Field_S
  fieldr := up.Ea.Field_R
  ret := r.Ans8583Fields(rxbuf, rxlen)
  if ret == 0 {
    fmt.Println("解析成功")
    r.PrintFields(fieldr)
  } else {
    fmt.Println("解析失败")
    return errors.New("error,failed to ans..")
  }
  //消息类型判断
  if (r.Msgtype[0] != 0x08) || (r.Msgtype[1] != 0x10) {
    //Log.d(TAG,"消息类型错!");
    return errors.New("error,wrong Msgtype ")
  }
  //应答码判断
  if (fieldr[38].Data[0] != 0x30) || (fieldr[38].Data[1] != 0x30) {
    //Log.d(TAG,"应答码不正确!");
    return errors.New("error,wrong resp code:" + fmt.Sprintf("%02x%02x", fieldr[38].Data[0], fieldr[38].Data[1]))
  }
  //跟踪号比较
  //memcmp
  if !equals(fields[10].Data, fieldr[10].Data) {
    return errors.New("error,wrong comm no ")
  }
  //终端号比较
  if !equals(fields[40].Data, fieldr[40].Data) {
    return errors.New("error,posnum not equal ")
  }
  //商户号比较
  if !equals(fields[41].Data, fieldr[41].Data) {
    return errors.New("error,mannum not equal ")
  }
  //3DES解密PIN KEY
  data := make([]byte, 16)
  memcpy(data, fieldr[61].Data, 16)
  pinkey, err := desutil.Des3Decrypt(data, byteutil.HexStringToBytes(MainKey))
  if err != nil {
    return errors.New("1" + err.Error())
  }
  //解密后的结果对8Byte全0做3DES加密运算
  tmp := make([]byte, 8)
  out, err := desutil.Des3Encrypt(tmp, pinkey)
  if err != nil {
    return errors.New("2" + err.Error())
  }
  check := make([]byte, 4)
  pincheck := make([]byte, 4)
  memcpy(check, out, 4)
  memcpy(pincheck, fieldr[61].Data[16:], 4)
  if !equals(check, pincheck) {
    return errors.New("error,Er PIK")
  }
  //3DES解密MAC KEY
  memcpy(data, fieldr[61].Data[20:], 16)
  mackey, err := desutil.Des3Decrypt(data, byteutil.HexStringToBytes(MainKey))
  if err != nil {
    return errors.New("3" + err.Error())
  }
  out, err = desutil.DesEncrypt(tmp, mackey[0:8])
  if err != nil {
    return errors.New("4" + err.Error())
  }
  maccheck := make([]byte, 4)
  memcpy(check, out, 4)
  memcpy(maccheck, fieldr[61].Data[36:], 4)
  if !equals(check, maccheck) {
    return errors.New("error,Er MAC")
  }
  memcpy(PiciNum, fieldr[59].Data[1:], 3)
  MacKey = byteutil.BytesToHexString(mackey[0:8])
  fmt.Printf("mackey:%s\n", MacKey)
  up.Ea.SetMacKey(MacKey)
  return nil
}
/*
银联8583 二维码交易组包
*/
func (up *Up8583) Frame8583Qrcode(qrcode string, money int) {
  s := up.Ea
  field := up.Ea.Field_S
  s.Init8583Fields(field)
  //消息类型
  s.Msgtype[0] = 0x02
  s.Msgtype[1] = 0x00
  //3域 交易处理码
  field[2].Ihave = true
  field[2].Len = 3
  field[2].Data = make([]byte, 3)
  //4域 交易金额
  field[3].Ihave = true
  field[3].Len = 6
  field[3].Data = byteutil.HexStringToBytes(fmt.Sprintf("%012d", money))
  //11域,受卡方系统跟踪号BCD 通讯流水
  field[10].Ihave = true
  field[10].Len = 3
  sn := fmt.Sprintf("%06d", RecSn)
  field[10].Data = byteutil.HexStringToBytes(sn)
  //22域
  field[21].Ihave = true
  field[21].Len = 2
  field[21].Data = []byte{0x03, 0x20}
  //25域
  field[24].Ihave = true
  field[24].Len = 1
  field[24].Data = make([]byte, 1)
  //41域,终端号
  field[40].Ihave = true
  field[40].Len = 8
  field[40].Data = []byte(PosNum)
  //42域,商户号
  field[41].Ihave = true
  field[41].Len = 15
  field[41].Data = []byte(ManNum)
  //49域 交易货币代码
  field[48].Ihave = true
  field[48].Len = 3
  field[48].Data = []byte{0x31, 0x35, 0x36}
  //59域,扫码的数据
  field[58].Ihave = true
  field[58].Len = 0x24
  field[58].Data = make([]byte, 24)
  field[58].Data[0] = 'A' //TAG+Len(019)
  field[58].Data[1] = '3'
  field[58].Data[2] = '0'
  field[58].Data[3] = '1'
  field[58].Data[4] = '9'
  memcpy(field[58].Data[5:], []byte(qrcode), 19)
  //60域
  field[59].Ihave = true
  field[59].Len = 0x13
  field[59].Data = make([]byte, 7)
  field[59].Data[0] = 0x22
  memcpy(field[59].Data[1:], PiciNum, 3)
  field[59].Data[4] = 0x00
  field[59].Data[5] = 0x06
  field[59].Data[6] = 0x00
  //MAC,64域
  field[63].Ihave = true
  field[63].Len = 0x08
  field[63].Data = make([]byte, 8)
  //这个域要求填MAC,只需按这样填,MAC的计算在pack8583Fields自动完成了
  /*报文组帧,自动组织这些域到Pack的TxBuffer中*/
  s.Pack8583Fields()
  //CommSn++ //通讯流水每次加一
  //s.PrintFields(up.Ea.Field_S)
}
func NewUp8583() *Up8583 {
  var up = new(Up8583)
  up.Ea = easy8583.New8583()
  up.Ea.Tpdu = byteutil.HexStringToBytes(TPDU)
  return up
}
/*
银联8583 电子现金交易组包
*/
//获取55域 IC卡数据域
/*
9F26 08
9F27 01
9F10
9F37 04
9F36 02
95 05
9A 03
9C 01
9F02 06
5F2A 02
82 02
9F1A 02
9F03 06
9F33 03
9F1E 08
84
9F09 02
9F41 04
9F34 03
9F35 01
9F63 10
9F74 06
8A 02
*/
func getfield55() {
}
func (up *Up8583) Frame8583UpCash(cardbin string, money int, cardvailddata string, cardholdsn string, field55 []byte) {
  s := up.Ea
  field := up.Ea.Field_S
  s.Init8583Fields(field)
  //消息类型
  s.Msgtype[0] = 0x02
  s.Msgtype[1] = 0x00
  //2域 卡号
  field[1].Ihave = true
  tmp := fmt.Sprintf("%02d", len(cardbin))
  t, _ := strconv.ParseInt(tmp, 16, 16)
  if len(cardbin)%2 != 0 {
    cardbin += "0"
  }
  field[1].Len = int(t)
  field[1].Data = byteutil.HexStringToBytes(cardbin)
  //3域 交易处理码
  field[2].Ihave = true
  field[2].Len = 3
  field[2].Data = make([]byte, 3)
  //4域 交易金额
  field[3].Ihave = true
  field[3].Len = 6
  field[3].Data = byteutil.HexStringToBytes(fmt.Sprintf("%012d", money))
  //11域,受卡方系统跟踪号BCD 通讯流水
  field[10].Ihave = true
  field[10].Len = 3
  sn := fmt.Sprintf("%06d", RecSn)
  field[10].Data = byteutil.HexStringToBytes(sn)
  //14域 卡有效期,能获取到时存在
  if len(cardvailddata) > 0 {
    field[13].Ihave = true
    field[13].Len = 2
    field[13].Data = byteutil.HexStringToBytes(cardvailddata)
  }
  //22域
  field[21].Ihave = true
  field[21].Len = 2
  field[21].Data = []byte{0x07, 0x20}
  //23域,卡序列号 能获取时存在
  if len(cardholdsn) > 0 {
    field[22].Ihave = true
    field[22].Len = 2
    field[22].Data = byteutil.HexStringToBytes(cardholdsn)
  }
  //25域
  field[24].Ihave = true
  field[24].Len = 1
  field[24].Data = make([]byte, 1)
  //41域,终端号
  field[40].Ihave = true
  field[40].Len = 8
  field[40].Data = []byte(PosNum)
  //42域,商户号
  field[41].Ihave = true
  field[41].Len = 15
  field[41].Data = []byte(ManNum)
  //49域 交易货币代码
  field[48].Ihave = true
  field[48].Len = 3
  field[48].Data = []byte{0x31, 0x35, 0x36}
  //55域 IC卡数据域
  field[54].Ihave = true
  tmp = fmt.Sprintf("%04d", len(field55))
  b := byteutil.HexStringToBytes(tmp)
  field[54].Len = int(b[0])<<8 | int(b[1])
  field[54].Data = field55
  //60域
  field[59].Ihave = true
  field[59].Len = 0x13
  field[59].Data = make([]byte, 7)
  field[59].Data[0] = 0x36
  memcpy(field[59].Data[1:], PiciNum, 3)
  field[59].Data[4] = 0x00
  field[59].Data[5] = 0x06
  field[59].Data[6] = 0x00
  //63域
  field[62].Ihave = true
  field[62].Len = 0x03
  field[62].Data = make([]byte, 3)
  memcpy(field[62].Data, []byte("CUP"), 3)
  //MAC,64域
  field[63].Ihave = true
  field[63].Len = 0x08
  field[63].Data = make([]byte, 8)
  //这个域要求填MAC,只需按这样填,MAC的计算在pack8583Fields自动完成了
  /*报文组帧,自动组织这些域到Pack的TxBuffer中*/
  s.Pack8583Fields()
}
func (up *Up8583) Ans8583UpCash(rxbuf []byte, rxlen int) error {
  r := up.Ea
  fields := up.Ea.Field_S
  fieldr := up.Ea.Field_R
  ret := r.Ans8583Fields(rxbuf, rxlen)
  if ret == 0 {
    fmt.Println("解析成功")
    r.PrintFields(fieldr)
  } else {
    fmt.Println("解析失败")
    r.PrintFields(fieldr)
    return errors.New("error,failed to ans..")
  }
  //消息类型判断
  if (r.Msgtype[0] != 0x02) || (r.Msgtype[1] != 0x10) {
    //Log.d(TAG,"消息类型错!");
    return errors.New("error,wrong Msgtype ")
  }
  //应答码判断
  if (fieldr[38].Data[0] != 0x30) || (fieldr[38].Data[1] != 0x30) {
    //Log.d(TAG,"应答码不正确!");
    return errors.New("error,wrong resp code:" + fmt.Sprintf("%02x%02x", fieldr[38].Data[0], fieldr[38].Data[1]))
  }
  //跟踪号比较
  //memcmp
  if !equals(fields[10].Data, fieldr[10].Data) {
    return errors.New("error,wrong comm no ")
  }
  //终端号比较
  if !equals(fields[40].Data, fieldr[40].Data) {
    return errors.New("error,posnum not equal ")
  }
  //商户号比较
  if !equals(fields[41].Data, fieldr[41].Data) {
    return errors.New("error,mannum not equal ")
  }
  //MAC验证
  mac, err := easy8583.UpGetMac(rxbuf[13:], rxlen-13-8, easy8583.MacKey)
  if err != nil {
    fmt.Println(err)
    panic("calc mac error!")
  }
  if !equals(fieldr[63].Data, mac) {
    return errors.New("error,mac check err")
  }
  return nil
}
func main() {
  fmt.Println("test...")
  up := NewUp8583()
  //up.Frame8583QD()
  //recvstr := "007960000001386131003111080810003800010AC0001450021122130107200800085500323231333031343931333239303039393939393930363030313433303137303131393939390011000005190030004046F161A743497B32EAC760DF5EA57DF5900ECCE3977731A7EA402DDF0000000000000000CFF1592A"
  //recv := byteutil.HexStringToBytes(recvstr)
  //ret := up.Ea.Ans8583Fields(recv, len(recv))
  //if ret == 0 {
  //  fmt.Println("解析成功")
  //  up.Ea.PrintFields(up.Ea.Field_R)
  // } else {
  //  fmt.Println("解析失败")
  // }
  up.Frame8583QD()
  up.Ea.PrintFields(up.Ea.Field_S)
  //fmt.Println(byteutil.BytesToHexString(up.Ea.Txbuf))
  up.Frame8583Qrcode("6220485073630469936", 1)
  up.Ea.PrintFields(up.Ea.Field_S)
}


/**
 * Created by yangyongzhen on 2019/01/11
 * simple 8583 Protocol Analysis
 */
package easy8583
import (
  "bytes"
  "fmt"
  "strconv"
)
type Field struct {
  Ihave bool   //是否存在该域
  Ltype int    //长度类型 (NOVAR,LLVAR,LLLVAR)
  Dtype int    //数据类型 (BCD,ASCII)
  Len   int    //域的数据内容的长度
  Data  []byte //域的有效数据
}
type Easy8583 struct {
  Len     []byte
  Tpdu    []byte
  Head    []byte
  Msgtype []byte
  Bitmap  []byte
  Txbuf   []byte
  Field_S []Field //发送的域
  Field_R []Field //接收的域
}
//定义枚举类型 长度类型定义
const (
  NOVAR  = iota //value = 0,定长,
  LLVAR         //value = 1,长度为1字节
  LLLVAR        //value = 2,长度为2字节
)
//定义枚举类型 数据类型定义
const (
  UN  = iota //value = 0, 未定义,定长的域无需关注类型
  BIN        //value = 1,BIN
  BCD        //value = 2,BCD
)
//各个域的初始配置
func (ea *Easy8583) Init8583Fields(fds []Field) {
   for i := 0; i < 64;i++ {
    fds[i].Ihave = false
   }
  fds[0].Ltype = 0
  fds[1].Ltype = LLVAR //LLVAR
  fds[1].Dtype = BCD
  fds[2].Ltype = 0
  fds[2].Len = 3
  fds[3].Ltype = 0
  fds[3].Len = 6
  fds[10].Ltype = 0
  fds[10].Len = 3
  fds[11].Ltype = 0
  fds[11].Len = 3
  fds[12].Ltype = 0
  fds[12].Len = 2
  fds[13].Ltype = 0
  fds[13].Len = 2
  fds[14].Ltype = 0
  fds[14].Len = 2
  fds[21].Ltype = 0
  fds[21].Len = 2
  fds[22].Ltype = 0
  fds[22].Len = 2
  fds[24].Ltype = 0
  fds[24].Len = 1
  fds[25].Ltype = 0
  fds[25].Len = 1
  fds[31].Ltype = LLVAR //LLVAR
  fds[31].Dtype = BCD
  fds[34].Ltype = LLVAR //LLVAR
  fds[34].Dtype = BCD
  fds[36].Ltype = 0
  fds[36].Len = 12
  fds[37].Ltype = 0
  fds[37].Len = 6
  fds[38].Ltype = 0
  fds[38].Len = 2
  fds[39].Ltype = LLVAR
  fds[40].Ltype = 0
  fds[40].Len = 8
  fds[41].Ltype = 0
  fds[41].Len = 15
  fds[43].Ltype = LLVAR
  fds[47].Ltype = LLLVAR
  fds[47].Dtype = BCD
  fds[48].Ltype = 0
  fds[48].Len = 3
  fds[51].Ltype = 0
  fds[51].Len = 8
  fds[52].Ltype = 0
  fds[52].Len = 8
  fds[54].Ltype = LLLVAR //LLLVAR
  fds[58].Ltype = LLLVAR
  fds[59].Ltype = LLLVAR
  fds[59].Dtype = BCD
  fds[60].Ltype = LLLVAR
  fds[60].Dtype = BCD
  fds[61].Ltype = LLLVAR
  fds[62].Ltype = LLLVAR
  fds[63].Ltype = 0
  fds[63].Len = 8
}
/*
构造函数,初始化
*/
func New8583() *Easy8583 {
  var ea = new(Easy8583)
  ea.Txbuf = make([]byte, 0, 1024)
  ea.Txbuf = ea.Txbuf[0:23]
  ea.Len  = []byte{0x00, 0x00}
  ea.Tpdu = []byte{0x60, 0x05, 0x01, 0x00, 0x00}
  ea.Head = []byte{0x61, 0x31, 0x00, 0x31, 0x11, 0x08}
  ea.Msgtype = []byte{0x08, 0x00}
  ea.Bitmap = make([]byte, 8)
  ea.Field_S = make([]Field,64)
  ea.Field_R = make([]Field,64)
  ea.Init8583Fields(ea.Field_S)
  ea.Init8583Fields(ea.Field_R)
  return ea
}
func memcpy(dst, src []byte, size int) {
  for i := 0; i < size; i++ {
    dst[i] = src[i]
  }
  return
}
func bytesToHexStr(data []byte, lenth int) string {
  buf := data[0:lenth]
  hexStr := fmt.Sprintf("%x", buf)
  //fmt.Println(hexStr)
  return hexStr
}
// bytes to hex string
func bytesToHexString(b []byte) string {
  var buf bytes.Buffer
  for _, v := range b {
    t := strconv.FormatInt(int64(v), 16)
    if len(t) > 1 {
      buf.WriteString(t)
    } else {
      buf.WriteString("0" + t)
    }
  }
  return buf.String()
}
// hex string to bytes
func hexStringToBytes(s string) []byte {
  bs := make([]byte, 0)
  for i := 0; i < len(s); i = i + 2 {
    b, _ := strconv.ParseInt(s[i:i+2], 16, 16)
    bs = append(bs, byte(b))
  }
  return bs
}
//例:0x19 --> 19, 0x0119 -> 119
func bcdToInt(data []byte, lenth int) int {
  buf := data[0:lenth]
  hexStr := fmt.Sprintf("%x", buf)
  out, _ := strconv.ParseInt(hexStr, 10, 32)
  return int(out)
}
func toZero(p []byte) {
  for i := range p {
    p[i] = 0
  }
}
/*
8583报文打包
*/
func (ea *Easy8583) Pack8583Fields() int {
  fmt.Printf("pack 8583 fields\n")
  //ea.Txbuf[]
  ea.Txbuf = ea.Txbuf[0:23]
  toZero(ea.Txbuf)
  memcpy(ea.Txbuf[2:], ea.Tpdu, 5)
  memcpy(ea.Txbuf[7:], ea.Head, 6)
  memcpy(ea.Txbuf[13:], ea.Msgtype, 2)
  memcpy(ea.Txbuf[15:], ea.Bitmap, 8)
  j := 0
  len := 23
  tmplen := 0
  seat := 0x80
  for i := 0; i < 64; i++ {
    seat = (seat >> 1)
    if (i % 8) == 0 {
      j++
      seat = 0x80
    }
    if ea.Field_S[i].Ihave {
      ea.Bitmap[j-1] |= byte(seat)
      if ea.Field_S[i].Ltype == NOVAR {
        ea.Txbuf = ea.Txbuf[0 : len+ea.Field_S[i].Len]
        memcpy(ea.Txbuf[len:], ea.Field_S[i].Data, ea.Field_S[i].Len)
        len += ea.Field_S[i].Len
      } else if ea.Field_S[i].Ltype == LLVAR {
        ea.Txbuf = ea.Txbuf[0 : len+1]
        ea.Txbuf[len] = byte(ea.Field_S[i].Len)
        tmplen = bcdToInt(ea.Txbuf[len:],1)
        if ea.Field_S[i].Dtype == BCD {
          tmplen = ((tmplen/2) + (tmplen%2))
        }
        len += 1
        ea.Txbuf = ea.Txbuf[0 : len+tmplen]
        memcpy(ea.Txbuf[len:], ea.Field_S[i].Data, tmplen)
        len += tmplen
      } else if ea.Field_S[i].Ltype == LLLVAR {
        ea.Txbuf = ea.Txbuf[0 : len+2]
        ea.Txbuf[len] =   byte(ea.Field_S[i].Len>>8)
        ea.Txbuf[len+1] = byte(ea.Field_S[i].Len)
        tmplen = bcdToInt(ea.Txbuf[len:],2)
        if ea.Field_S[i].Dtype == BCD {
          tmplen = ((tmplen/2) + (tmplen%2))
        }
        len += 2
        ea.Txbuf = ea.Txbuf[0 : len+tmplen]
        memcpy(ea.Txbuf[len:], ea.Field_S[i].Data, tmplen)
        len += tmplen
      }
    }
    //报文总长度
    ea.Txbuf[0] = byte((len-2)>>8)
    ea.Txbuf[1] = byte((len-2))
    memcpy(ea.Len,ea.Txbuf,2)
  }
  return 0
}
/*
8583报文解包
*/
func (ea *Easy8583) Ans8583Fields( rxbuf []byte,rxlen int) int {
  fmt.Printf("ans 8583 fields\n")
  ea.Init8583Fields(ea.Field_R)
  len := 0
  tmplen := 0
  bitMap := make([]byte,8)
  var seat,buf uint64 = 1,0
  memcpy(bitMap,rxbuf[15:],8)
  memcpy(ea.Len,rxbuf[0:],2)
  //memcpy(ea.Tpdu,rxbuf[2:],5)
  memcpy(ea.Head,rxbuf[7:],6)
  memcpy(ea.Msgtype,rxbuf[13:],2)
  memcpy(ea.Bitmap,rxbuf[15:],8)
  len += 23
  for i := 0;i < 8;i++ {
        buf = ((buf<<8) | uint64(bitMap[i]))
  }
  for i := 0; i < 64; i++ {
    if  (buf & (seat << uint(63 - i))) > 0 {
      ea.Field_R[i].Ihave = true
      if ea.Field_R[i].Ltype == NOVAR {
        ea.Field_R[i].Data = make([]byte,ea.Field_R[i].Len)
        memcpy(ea.Field_R[i].Data, rxbuf[len:], ea.Field_R[i].Len)
        len += ea.Field_R[i].Len
      } else if ea.Field_R[i].Ltype == LLVAR {
        ea.Field_R[i].Len = int(rxbuf[len])
        tmplen = bcdToInt(rxbuf[len:],1)
        if ea.Field_R[i].Dtype == BCD {
          tmplen = ((tmplen/2) + (tmplen%2))
        }
        len += 1
        ea.Field_R[i].Data = make([]byte,tmplen)
        memcpy(ea.Field_R[i].Data, rxbuf[len:], tmplen)
        len += tmplen
      } else if ea.Field_R[i].Ltype == LLLVAR {
        ea.Field_R[i].Len = ( ( int(rxbuf[len])<<8 ) | int(rxbuf[len+1] ) )
        tmplen = bcdToInt(rxbuf[len:],2)
        if ea.Field_R[i].Dtype == BCD {
          tmplen = ((tmplen/2) + (tmplen%2))
        }
        len += 2
        ea.Field_R[i].Data = make([]byte,tmplen)
        memcpy(ea.Field_R[i].Data, rxbuf[len:], tmplen)
        len += tmplen
      }
    }
  }
  if(len > rxlen){
        return 1;
  }
  return 0
}
/*
打印信息,调试用
*/
func (ea *Easy8583) PrintFields(fds []Field){
  fmt.Println("Print fields...")
  fmt.Printf("\n==========================================\n")
  fmt.Printf("Len:\t%s\n", bytesToHexString(ea.Len))
  fmt.Printf("Tpdu:\t%s\n", bytesToHexString(ea.Tpdu))
  fmt.Printf("Head:\t%s\n", bytesToHexString(ea.Head))
  fmt.Printf("Msge:\t%s\n", bytesToHexString(ea.Msgtype))
  fmt.Printf("Bitmap:\t%s\n", bytesToHexString(ea.Bitmap))
  fmt.Printf("\n==========================================\n")
  for i:=0; i < 64; i++{
    if fds[i].Ihave {
      fmt.Printf("[field:%d] ",i+1)
      if fds[i].Ltype == LLVAR{
        fmt.Printf("[len:%02x] ",fds[i].Len)
      }else if fds[i].Ltype == LLLVAR{
        fmt.Printf("[len:%04x] ",fds[i].Len)
      }
      fmt.Printf("[%s]\n",bytesToHexString(fds[i].Data))
      fmt.Printf("\n------------------------------\n")
    }
  }
}
func main() {
  fmt.Println("test...")
}
相关文章
|
29天前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
81 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
10天前
|
安全 测试技术 Go
Go语言中的并发编程模型解析####
在当今的软件开发领域,高效的并发处理能力是提升系统性能的关键。本文深入探讨了Go语言独特的并发编程模型——goroutines和channels,通过实例解析其工作原理、优势及最佳实践,旨在为开发者提供实用的Go语言并发编程指南。 ####
|
15天前
|
Go
|
2月前
|
存储 Shell Go
Go语言结构体和元组全面解析
Go语言结构体和元组全面解析
|
消息中间件 缓存 Unix
[面试必备]嵌入式Linux内核开发必须了解的三十道题
[面试必备]嵌入式Linux内核开发必须了解的三十道题
|
Linux
嵌入式Linux QT开发之如何实现获取磁盘空间大小的应用逻辑
嵌入式Linux QT开发之如何实现获取磁盘空间大小的应用逻辑
241 0
|
Linux Go 人机交互
嵌入式linux之go语言开发(十三)LittlevGL,漂亮的嵌入式GUI的go语言绑定
嵌入式linux之go语言开发(十三)LittlevGL,漂亮的嵌入式GUI的go语言绑定
|
存储 XML JSON
嵌入式linux之go语言开发(十二)参数配置文件存储模块开发
嵌入式linux之go语言开发(十二)参数配置文件存储模块开发
|
Linux Go C语言
嵌入式linux之go语言开发(十一)让web服务器跑在终端上,通过网页配置终端参数
嵌入式linux之go语言开发(十一)让web服务器跑在终端上,通过网页配置终端参数
|
存储 监控 物联网
嵌入式linux之go语言开发(十)
嵌入式linux之go语言开发(十)