1765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/* 2765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * Author: Jon Trulson <jtrulson@ics.com> 3765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * Copyright (c) 2015 Intel Corporation. 4765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * 5765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * Permission is hereby granted, free of charge, to any person obtaining 6765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * a copy of this software and associated documentation files (the 7765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * "Software"), to deal in the Software without restriction, including 8765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * without limitation the rights to use, copy, modify, merge, publish, 9765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * distribute, sublicense, and/or sell copies of the Software, and to 10765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * permit persons to whom the Software is furnished to do so, subject to 11765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * the following conditions: 12765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * 13765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * The above copyright notice and this permission notice shall be 14765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * included in all copies or substantial portions of the Software. 15765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * 16765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */ 24765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 25765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#include <stdexcept> 26765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 27765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#include "sm130.h" 28765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 29765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangusing namespace upm; 30765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangusing namespace std; 31765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 32765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// Uncomment the below to see packaet data sent and received from the SM130 33765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// #define SM130_DEBUG 34765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 35765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangstatic const int defaultDelay = 1000; // ms for read 36765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 37765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangstatic const int maxLen = 64; // max number of bytes to read 38765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 39765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun ZhangSM130::SM130(int uart, int reset) : 40765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_uart(uart), m_gpioReset(reset) 41765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 42765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_tagType = TAG_NONE; 43765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_uidLen = 0; 44765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_uid.clear(); 45765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 46765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang initClock(); 47765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 48765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_gpioReset.dir(mraa::DIR_OUT); 49765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_gpioReset.write(0); 50765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 51765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 52765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun ZhangSM130::~SM130() 53765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 54765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 55765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 56765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangmraa::Result SM130::setBaudRate(int baud) 57765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 58765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_baud = baud; 59765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return m_uart.setBaudRate(baud); 60765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 61765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 62765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangstring SM130::sendCommand(CMD_T cmd, string data) 63765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 64765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang uint8_t cksum = 0; 65765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string command; 66765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 67765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // for uart, we need to add the sync bytes, 0xff, 0x00 68765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang command.push_back(0xff); 69765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang command.push_back(0x00); 70765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 71765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // compute the length - command + data 72765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang uint8_t len = 1; // command 73765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (!data.empty()) 74765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang len += data.size(); 75765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 76765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang command.push_back(len); 77765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 78765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cksum += len; 79765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 80765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // now the command 81765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang command.push_back(cmd); 82765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cksum += cmd; 83765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 84765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // now the data if any 85765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (!data.empty()) 86765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 87765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang for (int i=0; i<data.size(); i++) 88765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 89765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang command.push_back(data[i]); 90765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cksum += (uint8_t)data[i]; 91765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 92765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 93765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 94765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // now add the checksum 95765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang command.push_back(cksum); 96765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 97765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#ifdef SM130_DEBUG 98765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << "CMD: " << string2HexString(command) << endl; 99765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#endif // SM130_DEBUG 100765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 101765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // send it 102765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_uart.writeStr(command); 103765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 104765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // if the command is SET_BAUD, then switch to the new baudrate here 105765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // before attempting to read the response (and hope it worked). 106765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (cmd == CMD_SET_BAUD) 107765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 108765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang usleep(100000); // 100ms 109765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang setBaudRate(m_baud); 110765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 111765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 112765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // now wait for a response 113765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (!m_uart.dataAvailable(defaultDelay)) 114765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 115765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": timeout waiting for response" << endl; 116765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ""; 117765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 118765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 119765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = m_uart.readStr(maxLen); 120765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 121765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#ifdef SM130_DEBUG 122765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << "RSP: " << string2HexString(resp) << endl; 123765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#endif // SM130_DEBUG 124765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 125765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (!((uint8_t)resp[0] == 0xff && (uint8_t)resp[1] == 0x00)) 126765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 127765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": invalid packet header" << endl; 128765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ""; 129765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 130765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 131765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // check size - 2 header bytes + len + cksum. 132765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.size() != ((uint8_t)resp[2] + 2 + 1 + 1)) 133765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 134765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": invalid packet length, expected " 135765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang << int((uint8_t)resp[2] + 2 + 1 + 1) 136765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang << ", got " << resp.size() << endl; 137765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ""; 138765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 139765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 140765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // verify the cksum 141765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cksum = 0; 142765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang for (int i=2; i<(resp.size() - 1); i++) 143765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cksum += (uint8_t)resp[i]; 144765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 145765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (cksum != (uint8_t)resp[resp.size() - 1]) 146765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 147765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": invalid checksum, expected " 148765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang << int(cksum) << ", got " << (uint8_t)resp[resp.size()-1] << endl; 149765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ""; 150765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 151765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 152765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // we could also verify that the command code returned was for the 153765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // command submitted... 154765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 155765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // now, remove the 2 header bytes and the checksum, leave the length 156765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // and command. 157765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang resp.erase(resp.size() - 1, 1); // cksum 158765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang resp.erase(0, 2); // header bytes 159765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 160765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // return the rest 161765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return resp; 162765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 163765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 164765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangstring SM130::getFirmwareVersion() 165765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 166765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 167765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 168765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_VERSION, ""); 169765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 170765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 171765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 172765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 173765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ""; 174765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 175765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 176765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // delete the len and cmd, return the rest 177765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang resp.erase(0, 2); 178765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return resp; 179765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 180765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 181765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool SM130::reset() 182765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 183765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 184765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 185765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_RESET, ""); 186765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 187765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 188765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 189765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 190765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 191765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 192765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 193765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 194765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 195765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangvoid SM130::hardwareReset() 196765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 197765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_gpioReset.write(1); 198765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang usleep(100000); 199765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_gpioReset.write(0); 200765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 201765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 202765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool SM130::select() 203765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 204765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 205765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 206765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_tagType = TAG_NONE; 207765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_uidLen = 0; 208765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_uid.clear(); 209765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 210765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_SELECT_TAG, ""); 211765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 212765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 213765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 214765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 215765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 216765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 217765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 218765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if ((uint8_t)resp[0] == 2) 219765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 220765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // then we got an error of some sort, store the error code, str 221765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // and bail. 222765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_lastErrorCode = resp[2]; 223765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 224765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang switch (m_lastErrorCode) 225765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 226765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'N': m_lastErrorString = "No tag present"; 227765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 228765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'U': m_lastErrorString = "Access failed, RF field is off"; 229765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 230765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang default: m_lastErrorString = "Unknown error code"; 231765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 232765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 233765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 234765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 235765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 236765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // if we are here, then store the uid info and tag type. 237765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_tagType = (TAG_TYPE_T)resp[2]; 238765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 239765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if ((uint8_t)resp[0] == 6) 240765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_uidLen = 4; // 4 byte uid 241765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang else 242765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_uidLen = 7; // 7 byte 243765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 244765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang for (int i=0; i<m_uidLen; i++) 245765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_uid.push_back(resp[i+3]); 246765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 247765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 248765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 249765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 250765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool SM130::authenticate(uint8_t block, KEY_TYPES_T keyType, string key) 251765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 252765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 253765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 254765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // A little sanity checking... 255765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (keyType == KEY_TYPE_A || keyType == KEY_TYPE_B) 256765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 257765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (key.empty()) 258765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang throw std::invalid_argument(string(__FUNCTION__) + 259765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ": You must specify a key for type A or B"); 260765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (key.size() != 6) 261765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang throw std::invalid_argument(string(__FUNCTION__) + 262765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ": Key size must be 6"); 263765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 264765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; // probably not reached :) 265765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 266765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang else 267765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 268765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // make sure the key is empty for any other key type 269765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang key.clear(); 270765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 271765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 272765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string data; 273765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data.push_back(block); 274765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data.push_back(keyType); 275765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data += key; 276765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 277765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_AUTHENTICATE, data); 278765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 279765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 280765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 281765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 282765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 283765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 284765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 285765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // response len is always 2, 'L' means auth was successful 286765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp[2] != 'L') 287765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 288765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // then we got an error of some sort, store the error code, str 289765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // and bail. 290765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_lastErrorCode = resp[2]; 291765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 292765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang switch (m_lastErrorCode) 293765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 294765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'N': m_lastErrorString = "No tag present, or login failed"; 295765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 296765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'U': m_lastErrorString = "Login failed"; 297765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 298765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'E': m_lastErrorString = "Invalid key format in EEPROM"; 299765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 300765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang default: m_lastErrorString = "Unknown error code"; 301765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 302765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 303765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 304765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 305765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 306765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 307765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 308765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 309765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangstring SM130::readBlock16(uint8_t block) 310765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 311765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 312765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 313765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string data; 314765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 315765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data.push_back(block); 316765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 317765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_READ16, data); 318765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 319765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 320765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 321765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 322765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ""; 323765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 324765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 325765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if ((uint8_t)resp[0] == 2) 326765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 327765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // then we got an error of some sort, store the error code, str 328765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // and bail. 329765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_lastErrorCode = resp[2]; 330765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 331765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang switch (m_lastErrorCode) 332765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 333765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'N': m_lastErrorString = "No tag present"; 334765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 335765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'F': m_lastErrorString = "Read failed"; 336765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 337765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang default: m_lastErrorString = "Unknown error code"; 338765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 339765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 340765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 341765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ""; 342765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 343765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 344765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // trim off the len, cmd, and block # bytes and return the rest 345765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang resp.erase(0, 3); 346765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return resp; 347765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 348765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 349765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangint32_t SM130::readValueBlock(uint8_t block) 350765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 351765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 352765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 353765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string data; 354765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 355765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data.push_back(block); 356765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 357765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_READ_VALUE, data); 358765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 359765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 360765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 361765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 362765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return 0; 363765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 364765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 365765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if ((uint8_t)resp[0] == 2) 366765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 367765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // then we got an error of some sort, store the error code, str 368765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // and bail. 369765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_lastErrorCode = resp[2]; 370765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 371765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang switch (m_lastErrorCode) 372765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 373765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'N': m_lastErrorString = "No tag present"; 374765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 375765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'F': m_lastErrorString = "Read failed"; 376765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 377765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'I': m_lastErrorString = "Invalid Value Block"; 378765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 379765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang default: m_lastErrorString = "Unknown error code"; 380765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 381765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 382765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 383765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return 0; 384765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 385765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 386765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang int32_t rv; 387765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang rv = ((uint8_t)resp[3] | 388765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ((uint8_t)resp[4] << 8) | 389765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ((uint8_t)resp[5] << 16) | 390765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ((uint8_t)resp[6] << 24)); 391765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 392765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return rv; 393765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 394765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 395765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool SM130::writeBlock16(uint8_t block, string contents) 396765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 397765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 398765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 399765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // A little sanity checking... 400765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (contents.size() != 16) 401765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 402765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang throw std::invalid_argument(string(__FUNCTION__) + 403765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ": You must supply 16 bytes for block content"); 404765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 405765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 406765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 407765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 408765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string data; 409765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data.push_back(block); 410765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data += contents; 411765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 412765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_WRITE16, data); 413765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 414765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 415765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 416765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 417765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 418765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 419765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 420765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if ((uint8_t)resp[0] == 2) 421765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 422765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // then we got an error of some sort, store the error code, str 423765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // and bail. 424765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_lastErrorCode = resp[2]; 425765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 426765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang switch (m_lastErrorCode) 427765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 428765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'F': m_lastErrorString = "Write failed"; 429765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 430765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'N': m_lastErrorString = "No tag present"; 431765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 432765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'U': m_lastErrorString = "Read after write failed"; 433765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 434765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'X': m_lastErrorString = "Unable to read after write"; 435765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 436765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang default: m_lastErrorString = "Unknown error code"; 437765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 438765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 439765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 440765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 441765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 442765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 443765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 444765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 445765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool SM130::writeValueBlock(uint8_t block, int32_t value) 446765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 447765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 448765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 449765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string data; 450765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data.push_back(block); 451765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // put the value in, LSB first 452765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data += (value & 0xff); 453765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data += ((value >> 8) & 0xff); 454765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data += ((value >> 16) & 0xff); 455765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data += ((value >> 24) & 0xff); 456765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 457765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_WRITE_VALUE, data); 458765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 459765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 460765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 461765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 462765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 463765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 464765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 465765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if ((uint8_t)resp[0] == 2) 466765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 467765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // then we got an error of some sort, store the error code, str 468765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // and bail. 469765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_lastErrorCode = resp[2]; 470765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 471765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang switch (m_lastErrorCode) 472765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 473765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'F': m_lastErrorString = "Read failed during verification"; 474765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 475765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'N': m_lastErrorString = "No tag present"; 476765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 477765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'I': m_lastErrorString = "Invalid value block"; 478765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 479765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang default: m_lastErrorString = "Unknown error code"; 480765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 481765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 482765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 483765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 484765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 485765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 486765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 487765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 488765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool SM130::writeBlock4(uint8_t block, string contents) 489765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 490765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 491765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 492765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // A little sanity checking... 493765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (contents.size() != 4) 494765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 495765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang throw std::invalid_argument(string(__FUNCTION__) + 496765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ": You must supply 4 bytes for block content"); 497765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 498765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 499765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 500765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 501765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string data; 502765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data.push_back(block); 503765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data += contents; 504765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 505765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_WRITE4, data); 506765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 507765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 508765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 509765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 510765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 511765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 512765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 513765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if ((uint8_t)resp[0] == 2) 514765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 515765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // then we got an error of some sort, store the error code, str 516765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // and bail. 517765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_lastErrorCode = resp[2]; 518765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 519765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang switch (m_lastErrorCode) 520765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 521765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'F': m_lastErrorString = "Write failed"; 522765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 523765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'N': m_lastErrorString = "No tag present"; 524765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 525765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'U': m_lastErrorString = "Read after write failed"; 526765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 527765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'X': m_lastErrorString = "Unable to read after write"; 528765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 529765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang default: m_lastErrorString = "Unknown error code"; 530765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 531765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 532765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 533765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 534765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 535765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 536765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 537765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 538765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool SM130::writeKey(uint8_t eepromSector, KEY_TYPES_T keyType, string key) 539765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 540765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 541765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 542765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // A little sanity checking... 543765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang eepromSector &= 0x0f; // Only 0x00-0x0f is valid 544765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 545765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (!(keyType == KEY_TYPE_A || keyType == KEY_TYPE_B)) 546765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 547765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang throw std::invalid_argument(string(__FUNCTION__) + 548765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ": Key type must be A or B"); 549765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 550765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 551765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 552765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 553765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (key.size() != 6) 554765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 555765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang throw std::invalid_argument(string(__FUNCTION__) + 556765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ": Key must be 6 bytes"); 557765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 558765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 559765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 560765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 561765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string data; 562765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data.push_back(eepromSector); 563765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data += keyType; 564765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data += key; 565765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 566765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_WRITE_KEY, data); 567765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 568765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 569765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 570765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 571765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 572765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 573765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 574765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // reponse len is always 2 575765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if ((uint8_t)resp[2] != 'L') 576765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 577765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // then we got an error of some sort, store the error code, str 578765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // and bail. 579765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_lastErrorCode = resp[2]; 580765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 581765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang switch (m_lastErrorCode) 582765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 583765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'N': m_lastErrorString = "Write master key failed"; 584765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 585765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang default: m_lastErrorString = "Unknown error code"; 586765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 587765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 588765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 589765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 590765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 591765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 592765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 593765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 594765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangint32_t SM130::adjustValueBlock(uint8_t block, int32_t value, bool incr) 595765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 596765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 597765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 598765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string data; 599765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data.push_back(block); 600765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // put the value in, LSB first 601765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data += (value & 0xff); 602765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data += ((value >> 8) & 0xff); 603765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data += ((value >> 16) & 0xff); 604765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data += ((value >> 24) & 0xff); 605765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 606765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(((incr) ? CMD_INC_VALUE : CMD_DEC_VALUE), data); 607765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 608765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 609765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 610765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 611765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return 0; 612765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 613765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 614765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if ((uint8_t)resp[0] == 2) 615765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 616765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // then we got an error of some sort, store the error code, str 617765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // and bail. 618765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_lastErrorCode = resp[2]; 619765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 620765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang switch (m_lastErrorCode) 621765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 622765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'F': m_lastErrorString = "Read failed during verification"; 623765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 624765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'N': m_lastErrorString = "No tag present"; 625765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 626765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'I': m_lastErrorString = "Invalid value block"; 627765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 628765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang default: m_lastErrorString = "Unknown error code"; 629765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 630765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 631765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return 0; 632765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 633765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 634765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // now unpack the new value, LSB first 635765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang int32_t rv; 636765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang rv = ((uint8_t)resp[3] | 637765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ((uint8_t)resp[4] << 8) | 638765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ((uint8_t)resp[5] << 16) | 639765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ((uint8_t)resp[6] << 24)); 640765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 641765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return rv; 642765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 643765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 644765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool SM130::setAntennaPower(bool on) 645765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 646765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 647765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 648765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_ANTENNA_POWER, ""); 649765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 650765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 651765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 652765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 653765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 654765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 655765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 656765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 657765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 658765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 659765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhanguint8_t SM130::readPorts() 660765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 661765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 662765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 663765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_READ_PORT, ""); 664765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 665765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 666765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 667765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 668765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return 0; 669765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 670765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 671765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // only the first 2 bits are valid 672765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return (resp[2] & 3); 673765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 674765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 675765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool SM130::writePorts(uint8_t val) 676765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 677765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 678765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 679765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // only the first 2 bits are valid 680765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang val &= 3; 681765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 682765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string data; 683765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data.push_back(val); 684765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 685765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_WRITE_PORT, data); 686765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 687765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 688765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 689765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 690765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 691765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 692765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 693765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 694765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 695765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 696765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool SM130::haltTag() 697765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 698765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 699765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 700765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_HALT_TAG, ""); 701765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 702765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 703765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 704765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 705765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 706765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 707765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 708765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // reponse len is always 2 709765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if ((uint8_t)resp[2] != 'L') 710765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 711765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // then we got an error of some sort, store the error code, str 712765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // and bail. 713765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_lastErrorCode = resp[2]; 714765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 715765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang switch (m_lastErrorCode) 716765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 717765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'U': m_lastErrorString = "Can not halt, RF field is off"; 718765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 719765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang default: m_lastErrorString = "Unknown error code"; 720765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 721765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 722765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 723765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 724765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 725765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 726765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 727765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 728765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool SM130::setSM130BaudRate(int baud) 729765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 730765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 731765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 732765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang uint8_t newBaud; 733765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 734765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang switch (baud) 735765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 736765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 9600: newBaud = 0x00; 737765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 738765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 19200: newBaud = 0x01; 739765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 740765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 38400: newBaud = 0x02; 741765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 742765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 57600: newBaud = 0x03; 743765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 744765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 115200: newBaud = 0x04; 745765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang break; 746765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang default: 747765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang throw std::invalid_argument(string(__FUNCTION__) + 748765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ": Invalid SM130 baud rate specified"); 749765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 750765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 751765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // WARNING: this is a dangerous command 752765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang int oldBaud = m_baud; 753765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang m_baud = baud; 754765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 755765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string data; 756765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data.push_back(newBaud); 757765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 758765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_SET_BAUD, data); 759765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 760765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 761765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 762765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 763765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": restoring old baud rate" << endl; 764765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 765765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang setBaudRate(oldBaud); 766765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 767765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 768765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 769765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // otherwise assume success, possibly incorrectly 770765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 771765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 772765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 773765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool SM130::sleep() 774765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 775765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang clearError(); 776765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 777765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string resp = sendCommand(CMD_SLEEP, ""); 778765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 779765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (resp.empty()) 780765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 781765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang cerr << __FUNCTION__ << ": failed" << endl; 782765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 783765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 784765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 785765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 786765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 787765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 788765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangstring SM130::string2HexString(string input) 789765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 790765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang static const char* const lut = "0123456789abcdef"; 791765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang size_t len = input.size(); 792765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 793765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang string output; 794765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang output.reserve(3 * len); 795765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang for (size_t i = 0; i < len; ++i) 796765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 797765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang const unsigned char c = input[i]; 798765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang output.push_back(lut[c >> 4]); 799765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang output.push_back(lut[c & 15]); 800765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang output.push_back(' '); 801765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 802765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 803765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return output; 804765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 805765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 806765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangvoid SM130::initClock() 807765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 808765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang gettimeofday(&m_startTime, NULL); 809765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 810765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 811765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhanguint32_t SM130::getMillis() 812765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 813765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang struct timeval elapsed, now; 814765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang uint32_t elapse; 815765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 816765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // get current time 817765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang gettimeofday(&now, NULL); 818765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 819765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // compute the delta since m_startTime 820765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if( (elapsed.tv_usec = now.tv_usec - m_startTime.tv_usec) < 0 ) 821765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 822765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang elapsed.tv_usec += 1000000; 823765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang elapsed.tv_sec = now.tv_sec - m_startTime.tv_sec - 1; 824765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 825765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang else 826765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 827765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang elapsed.tv_sec = now.tv_sec - m_startTime.tv_sec; 828765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 829765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 830765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang elapse = (uint32_t)((elapsed.tv_sec * 1000) + (elapsed.tv_usec / 1000)); 831765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 832765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // never return 0 833765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (elapse == 0) 834765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang elapse = 1; 835765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 836765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return elapse; 837765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 838765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 839765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangbool SM130::waitForTag(uint32_t timeout) 840765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 841765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang initClock(); 842765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 843765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang do 844765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 845765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (select()) 846765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 847765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // success 848765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 849765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 850765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang else 851765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 852765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // If there was an error, fail if it's anything other than a 853765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // tag not present 854765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (getLastErrorCode() != 'N') 855765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 856765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 857765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // otherwise, sleep for 100ms and try again 858765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang usleep(100000); 859765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 860765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } while (getMillis() <= timeout); 861765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 862765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 863765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 864765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 865765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangstring SM130::tag2String(TAG_TYPE_T tag) 866765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang{ 867765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang switch (tag) 868765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang { 869765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case TAG_MIFARE_ULTRALIGHT: return "MiFare Ultralight"; 870765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case TAG_MIFARE_1K: return "MiFare 1K"; 871765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case TAG_MIFARE_4K: return "MiFare 4K"; 872765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case TAG_UNKNOWN: return "Unknown Tag Type"; 873765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang default: return "Invalid Tag Type"; 874765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 875765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 876765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 877765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 878765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 879