package main import ( "encoding/binary" "encoding/hex" "flag" "log" "strconv" "time" "pm3.dev/cvend" ) var wait = flag.Duration("w", 5*time.Second, "how long to wait for a response") var follow = flag.Bool("f", false, "don't exit after response") func main() { flag.Parse() log.SetFlags(log.Lshortfile | log.Ldate | log.Ltime | log.Lmicroseconds) log.Println("start") wc := make(chan struct{}, 1) cv, err := cvend.Open(cvend.Path, func(msgType byte, msgData []byte) { switch msgType { case 0x07: log.Printf("Heartbeat(%s)", hex.EncodeToString(msgData)) case 0x0f: log.Printf("Startup(%s)", hex.EncodeToString(msgData)) case 0xed: if len(msgData) == 0 { log.Printf("Log()") } else { log.Printf("Log(%d) %q", msgData[0], string(msgData[1:])) } case 0xbe: if len(msgData) < 22 || len(msgData) < 22+int(msgData[21]) { log.Printf("PICCRead(short)\n%s", hex.Dump(msgData)) } else { _ = msgData[:11] // unknown uid := msgData[11:18] atqa := binary.LittleEndian.Uint16(msgData[18:20]) sak := msgData[20] atrLen := msgData[21] atr := msgData[22 : 22+atrLen] _ = msgData[22+atrLen:] // unknown log.Printf("PICCRead(uid %s atqa 0x%04x sak %02x atr %s)\n%s", hex.EncodeToString(uid), atqa, sak, hex.EncodeToString(atr), hex.Dump(msgData)) } case 0xd1: log.Printf("EMVTransactionSuccessUnk\n%s", hex.Dump(msgData)) default: log.Printf("ipp %02x\n%s", msgType, hex.Dump(msgData)) } select { case wc <- struct{}{}: default: } }) if err != nil { panic(err) } defer cv.Close() for i := 0; i < flag.NArg(); i += 2 { var msgType byte var msgData []byte if n, err := strconv.ParseUint(flag.Arg(i), 0, 8); err != nil { panic(err) } else { msgType = byte(n) } if bs, err := hex.DecodeString(flag.Arg(i + 1)); err != nil { panic(err) } else { msgData = bs } if err := cv.SendIPP(msgType, msgData); err != nil { panic(err) } if *wait > 0 { select { case <-wc: case <-time.After(*wait): } } } if *follow || flag.NArg() == 0 { select {} } }