Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FatFileSystem mbed myBlueUSB neigbourhood rfcomm sdp
ftlib/ftlibclasstxcbt.cpp@0:7da612835693, 2011-06-15 (annotated)
- Committer:
 - networker 
 - Date:
 - Wed Jun 15 19:12:25 2011 +0000
 - Revision:
 - 0:7da612835693
 
initial version
; Bluetooth support incomplete
Who changed what in which revision?
| User | Revision | Line number | New contents of line | 
|---|---|---|---|
| networker  | 
0:7da612835693 | 1 | #include "mbed.h" | 
| networker  | 
0:7da612835693 | 2 | #include "USBHost.h" | 
| networker  | 
0:7da612835693 | 3 | #include "ftlibclasstxcbt.h" | 
| networker  | 
0:7da612835693 | 4 | #include "ftErrCode.h" | 
| networker  | 
0:7da612835693 | 5 | #include "Utils.h" | 
| networker  | 
0:7da612835693 | 6 | |
| networker  | 
0:7da612835693 | 7 | ftusbdevtxbt::ftusbdevtxbt(BTDevice *bd): ftusbdevtx() { | 
| networker  | 
0:7da612835693 | 8 | init = idle; | 
| networker  | 
0:7da612835693 | 9 | message_pending = 0; | 
| networker  | 
0:7da612835693 | 10 | parseState = 0; | 
| networker  | 
0:7da612835693 | 11 | if (bd) { | 
| networker  | 
0:7da612835693 | 12 | memcpy((char*)&btaddr, (char*)bd->GetAddress(), sizeof(BD_ADDR)); | 
| networker  | 
0:7da612835693 | 13 | name = bd->_name; | 
| networker  | 
0:7da612835693 | 14 | } | 
| networker  | 
0:7da612835693 | 15 | set_baudrate(38400);//no effect | 
| networker  | 
0:7da612835693 | 16 | //further com not possible because device is not open | 
| networker  | 
0:7da612835693 | 17 | // send_msg(1); //ping | 
| networker  | 
0:7da612835693 | 18 | // GetFtSerialNr(); | 
| networker  | 
0:7da612835693 | 19 | } | 
| networker  | 
0:7da612835693 | 20 | |
| networker  | 
0:7da612835693 | 21 | unsigned ftusbdevtxbt::InitFtUsbDeviceList() { | 
| networker  | 
0:7da612835693 | 22 | ftusbdev::InitFtUsbDeviceList(); | 
| networker  | 
0:7da612835693 | 23 | BTDevice* btdevs[8]; | 
| networker  | 
0:7da612835693 | 24 | int count = Bluetooth.GetDevices(btdevs,8); | 
| networker  | 
0:7da612835693 | 25 | for (int i = 0; i < count; i++) | 
| networker  | 
0:7da612835693 | 26 | //if (memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) | 
| networker  | 
0:7da612835693 | 27 | { | 
| networker  | 
0:7da612835693 | 28 | devs.push_back(new ftusbdevtxbt(btdevs[i])); | 
| networker  | 
0:7da612835693 | 29 | printf("%d: %s\n", i, btdevs[i]->_name); | 
| networker  | 
0:7da612835693 | 30 | } | 
| networker  | 
0:7da612835693 | 31 | return 0; | 
| networker  | 
0:7da612835693 | 32 | } | 
| networker  | 
0:7da612835693 | 33 | |
| networker  | 
0:7da612835693 | 34 | int ftusbdevtxbt::read_data(unsigned char *data, int size, USBCallback callback, void* userData) { | 
| networker  | 
0:7da612835693 | 35 | return 0; | 
| networker  | 
0:7da612835693 | 36 | } | 
| networker  | 
0:7da612835693 | 37 | |
| networker  | 
0:7da612835693 | 38 | int ftusbdevtxbt::write_data(unsigned char *data, int size, USBCallback callback, void* userData) { | 
| networker  | 
0:7da612835693 | 39 | return Socket_Send(device, data, size); | 
| networker  | 
0:7da612835693 | 40 | } | 
| networker  | 
0:7da612835693 | 41 | |
| networker  | 
0:7da612835693 | 42 | unsigned ftusbdevtxbt::GetFtSerialNr() { | 
| networker  | 
0:7da612835693 | 43 | return sn; | 
| networker  | 
0:7da612835693 | 44 | } | 
| networker  | 
0:7da612835693 | 45 | |
| networker  | 
0:7da612835693 | 46 | void ftusbdevtxbt::parse (const unsigned char *buf, unsigned len) { | 
| networker  | 
0:7da612835693 | 47 | unsigned i = 0; | 
| networker  | 
0:7da612835693 | 48 | //printf("start parse, state = %d, len = %d\n", parseState, len); | 
| networker  | 
0:7da612835693 | 49 | while (i < len) { | 
| networker  | 
0:7da612835693 | 50 | char c = buf[i++]; | 
| networker  | 
0:7da612835693 | 51 | switch (parseState) { | 
| networker  | 
0:7da612835693 | 52 | case 0: //ascii state | 
| networker  | 
0:7da612835693 | 53 | if (c==2) | 
| networker  | 
0:7da612835693 | 54 | parseState = 1; | 
| networker  | 
0:7da612835693 | 55 | else { | 
| networker  | 
0:7da612835693 | 56 | putc(c, stdout); | 
| networker  | 
0:7da612835693 | 57 | console.put(c); | 
| networker  | 
0:7da612835693 | 58 | } | 
| networker  | 
0:7da612835693 | 59 | break; | 
| networker  | 
0:7da612835693 | 60 | case 1: | 
| networker  | 
0:7da612835693 | 61 | if (c==0x55) | 
| networker  | 
0:7da612835693 | 62 | parseState = 2; | 
| networker  | 
0:7da612835693 | 63 | else { | 
| networker  | 
0:7da612835693 | 64 | parseState = 0; | 
| networker  | 
0:7da612835693 | 65 | printf("expected 0x55 in X1 header, found %02X\n", c); | 
| networker  | 
0:7da612835693 | 66 | } | 
| networker  | 
0:7da612835693 | 67 | break; | 
| networker  | 
0:7da612835693 | 68 | case 2: | 
| networker  | 
0:7da612835693 | 69 | X1_len = c<<8; | 
| networker  | 
0:7da612835693 | 70 | X1_crc = c; | 
| networker  | 
0:7da612835693 | 71 | parseState= 3; | 
| networker  | 
0:7da612835693 | 72 | break; | 
| networker  | 
0:7da612835693 | 73 | case 3: | 
| networker  | 
0:7da612835693 | 74 | X1_len += c; | 
| networker  | 
0:7da612835693 | 75 | X1_crc += c; | 
| networker  | 
0:7da612835693 | 76 | parseState= 4; | 
| networker  | 
0:7da612835693 | 77 | X1_pkt = new unsigned char[X1_len]; | 
| networker  | 
0:7da612835693 | 78 | //printf("net length = %d\n", X1_len); | 
| networker  | 
0:7da612835693 | 79 | X1_pos = 0; | 
| networker  | 
0:7da612835693 | 80 | break; | 
| networker  | 
0:7da612835693 | 81 | case 4: | 
| networker  | 
0:7da612835693 | 82 | if (X1_pos < X1_len) { | 
| networker  | 
0:7da612835693 | 83 | X1_pkt[X1_pos++] = c; | 
| networker  | 
0:7da612835693 | 84 | X1_crc += c; | 
| networker  | 
0:7da612835693 | 85 | } else { //c is first checksum byte (MSB!) | 
| networker  | 
0:7da612835693 | 86 | parseState = 6; | 
| networker  | 
0:7da612835693 | 87 | X1_crc += c<<8; | 
| networker  | 
0:7da612835693 | 88 | } | 
| networker  | 
0:7da612835693 | 89 | break; | 
| networker  | 
0:7da612835693 | 90 | case 5: | 
| networker  | 
0:7da612835693 | 91 | //X1_crc = c<<8; | 
| networker  | 
0:7da612835693 | 92 | X1_crc += c; | 
| networker  | 
0:7da612835693 | 93 | parseState= 6; | 
| networker  | 
0:7da612835693 | 94 | break; | 
| networker  | 
0:7da612835693 | 95 | case 6: | 
| networker  | 
0:7da612835693 | 96 | X1_crc += c; | 
| networker  | 
0:7da612835693 | 97 | parseState= 7; | 
| networker  | 
0:7da612835693 | 98 | break; | 
| networker  | 
0:7da612835693 | 99 | case 7: | 
| networker  | 
0:7da612835693 | 100 | if (c == 3 && X1_crc == 0) { | 
| networker  | 
0:7da612835693 | 101 | //printHex(X1_pkt, X1_len); | 
| networker  | 
0:7da612835693 | 102 | if (transferAktiv == FTX1SYNC) | 
| networker  | 
0:7da612835693 | 103 | FtThreadEnd(); | 
| networker  | 
0:7da612835693 | 104 | else | 
| networker  | 
0:7da612835693 | 105 | X1_cmd = rec_msg2((headerbody*)X1_pkt, X1_len); | 
| networker  | 
0:7da612835693 | 106 | delete[] X1_pkt; | 
| networker  | 
0:7da612835693 | 107 | } else | 
| networker  | 
0:7da612835693 | 108 | printf("framing or checksum error, end char = %02X, sum=%04X\n", c, X1_crc); | 
| networker  | 
0:7da612835693 | 109 | |
| networker  | 
0:7da612835693 | 110 | parseState = 0; | 
| networker  | 
0:7da612835693 | 111 | break; | 
| networker  | 
0:7da612835693 | 112 | } | 
| networker  | 
0:7da612835693 | 113 | } | 
| networker  | 
0:7da612835693 | 114 | //printf("Leaving parse, state = %d, i = %d (last char = %02X)\n", parseState, i, buf[i-1]); | 
| networker  | 
0:7da612835693 | 115 | } | 
| networker  | 
0:7da612835693 | 116 | |
| networker  | 
0:7da612835693 | 117 | void ftusbdevtxbt::receive(int socket, SocketState state, const u8* data, int len) { | 
| networker  | 
0:7da612835693 | 118 | //printf("ftusbdevtxbt::receive was called: socket %d, state=%d, length=%d\n", socket, state, len); | 
| networker  | 
0:7da612835693 | 119 | static const unsigned char req[] = "\xdget_ser_num\xd"; | 
| networker  | 
0:7da612835693 | 120 | char line[80]; | 
| networker  | 
0:7da612835693 | 121 | if (len==0) { | 
| networker  | 
0:7da612835693 | 122 | switch (state) { | 
| networker  | 
0:7da612835693 | 123 | case SocketState_Opening: | 
| networker  | 
0:7da612835693 | 124 | break; | 
| networker  | 
0:7da612835693 | 125 | case SocketState_Open: | 
| networker  | 
0:7da612835693 | 126 | console.flush(); | 
| networker  | 
0:7da612835693 | 127 | send_msg(1, 0, false); //ping | 
| networker  | 
0:7da612835693 | 128 | init = ping; | 
| networker  | 
0:7da612835693 | 129 | break; | 
| networker  | 
0:7da612835693 | 130 | case SocketState_Closing: | 
| networker  | 
0:7da612835693 | 131 | case SocketState_Closed: | 
| networker  | 
0:7da612835693 | 132 | return; | 
| networker  | 
0:7da612835693 | 133 | } | 
| networker  | 
0:7da612835693 | 134 | } else { | 
| networker  | 
0:7da612835693 | 135 | //printHex(data, len); | 
| networker  | 
0:7da612835693 | 136 | parse(data, len); | 
| networker  | 
0:7da612835693 | 137 | switch (init) { | 
| networker  | 
0:7da612835693 | 138 | case idle: | 
| networker  | 
0:7da612835693 | 139 | break; | 
| networker  | 
0:7da612835693 | 140 | case ping: | 
| networker  | 
0:7da612835693 | 141 | if (X1_cmd == 1) { | 
| networker  | 
0:7da612835693 | 142 | printf("sending sernum request \n%s\n", req); | 
| networker  | 
0:7da612835693 | 143 | Socket_Send(socket, req, strlen((char*)req)); | 
| networker  | 
0:7da612835693 | 144 | init = serial; | 
| networker  | 
0:7da612835693 | 145 | } | 
| networker  | 
0:7da612835693 | 146 | break; | 
| networker  | 
0:7da612835693 | 147 | case serial: | 
| networker  | 
0:7da612835693 | 148 | while (console.gets(line, 80)==0) { | 
| networker  | 
0:7da612835693 | 149 | printf("Line=%s\n", line); | 
| networker  | 
0:7da612835693 | 150 | if (sscanf(line, "%d", &sn) == 1) { | 
| networker  | 
0:7da612835693 | 151 | printf("Got S/N=%d\n", sn); | 
| networker  | 
0:7da612835693 | 152 | send_msg(6, 1, false); //get INFO for master | 
| networker  | 
0:7da612835693 | 153 | init = info; | 
| networker  | 
0:7da612835693 | 154 | } | 
| networker  | 
0:7da612835693 | 155 | } | 
| networker  | 
0:7da612835693 | 156 | break; | 
| networker  | 
0:7da612835693 | 157 | case info: | 
| networker  | 
0:7da612835693 | 158 | if (X1_cmd == 6) { | 
| networker  | 
0:7da612835693 | 159 | printf("Master=%s\n", ta[0]->info.device_name); | 
| networker  | 
0:7da612835693 | 160 | send_msg(7, 1, false); //get state for master | 
| networker  | 
0:7da612835693 | 161 | init = slaves; | 
| networker  | 
0:7da612835693 | 162 | } | 
| networker  | 
0:7da612835693 | 163 | break; | 
| networker  | 
0:7da612835693 | 164 | case slaves: | 
| networker  | 
0:7da612835693 | 165 | if (X1_cmd == 7) {/* | 
| networker  | 
0:7da612835693 | 166 | for (int i = 1; i <= N_EXT_DEV; i++) | 
| networker  | 
0:7da612835693 | 167 | if (ta[0]->state.ext_dev_connect_state[i-1]) { | 
| networker  | 
0:7da612835693 | 168 | if (ta[i] == 0) { //new slave | 
| networker  | 
0:7da612835693 | 169 | ta[i] = new TA; | 
| networker  | 
0:7da612835693 | 170 | memset(ta[i], 0, sizeof(TA)); | 
| networker  | 
0:7da612835693 | 171 | active |= 1<<i; | 
| networker  | 
0:7da612835693 | 172 | printf("New Extension %d = %s\n", i, ta[i]->info.device_name); | 
| networker  | 
0:7da612835693 | 173 | if (cbRoboExtState) cbRoboExtState(i, 1); | 
| networker  | 
0:7da612835693 | 174 | } | 
| networker  | 
0:7da612835693 | 175 | } else { | 
| networker  | 
0:7da612835693 | 176 | if (ta[i]) {//should not happen during initialisation | 
| networker  | 
0:7da612835693 | 177 | delete ta[i]; | 
| networker  | 
0:7da612835693 | 178 | ta[i] = 0; | 
| networker  | 
0:7da612835693 | 179 | active &= ~(1<<i); | 
| networker  | 
0:7da612835693 | 180 | printf("Extension %d went offline\n", i); | 
| networker  | 
0:7da612835693 | 181 | if (cbRoboExtState) cbRoboExtState(i, 0); | 
| networker  | 
0:7da612835693 | 182 | } | 
| networker  | 
0:7da612835693 | 183 | } | 
| networker  | 
0:7da612835693 | 184 | if (active != 1) { | 
| networker  | 
0:7da612835693 | 185 | send_msg(6, active & ~1, false); //get info for slaves; | 
| networker  | 
0:7da612835693 | 186 | init = slaves_info; | 
| networker  | 
0:7da612835693 | 187 | } else*/ | 
| networker  | 
0:7da612835693 | 188 | init = ready; | 
| networker  | 
0:7da612835693 | 189 | } | 
| networker  | 
0:7da612835693 | 190 | break; | 
| networker  | 
0:7da612835693 | 191 | case slaves_info: | 
| networker  | 
0:7da612835693 | 192 | if (X1_cmd == 6) { | 
| networker  | 
0:7da612835693 | 193 | init = ready; | 
| networker  | 
0:7da612835693 | 194 | } | 
| networker  | 
0:7da612835693 | 195 | break; | 
| networker  | 
0:7da612835693 | 196 | case ready://normal message processing | 
| networker  | 
0:7da612835693 | 197 | break; | 
| networker  | 
0:7da612835693 | 198 | } | 
| networker  | 
0:7da612835693 | 199 | } | 
| networker  | 
0:7da612835693 | 200 | } | 
| networker  | 
0:7da612835693 | 201 | |
| networker  | 
0:7da612835693 | 202 | unsigned ftusbdevtxbt::OpenFtUsbDevice() { | 
| networker  | 
0:7da612835693 | 203 | ta[0] = new TA; | 
| networker  | 
0:7da612835693 | 204 | memset(ta[0], 0, sizeof(TA)); | 
| networker  | 
0:7da612835693 | 205 | active = 1; | 
| networker  | 
0:7da612835693 | 206 | L2CAPAddr s; | 
| networker  | 
0:7da612835693 | 207 | s.bdaddr = btaddr; | 
| networker  | 
0:7da612835693 | 208 | s.psm = 1;//abuse the psm for the channelID | 
| networker  | 
0:7da612835693 | 209 | device = Socket_Open(SOCKET_RFCOM, &s.hdr, recv, this);//Open the serial connection via RFCOMM | 
| networker  | 
0:7da612835693 | 210 | if (device<=0) { | 
| networker  | 
0:7da612835693 | 211 | printf("Opening of RFCOMM socket for ftdevice failed (%d)\n", device); | 
| networker  | 
0:7da612835693 | 212 | delete ta[0]; | 
| networker  | 
0:7da612835693 | 213 | ta[0] = 0; | 
| networker  | 
0:7da612835693 | 214 | return FTLIB_ERR_FAILED; | 
| networker  | 
0:7da612835693 | 215 | } | 
| networker  | 
0:7da612835693 | 216 | return 0; | 
| networker  | 
0:7da612835693 | 217 | } | 
| networker  | 
0:7da612835693 | 218 | |
| networker  | 
0:7da612835693 | 219 | unsigned ftusbdevtxbt::CloseFtDevice() { | 
| networker  | 
0:7da612835693 | 220 | if (ta[0]==0) | 
| networker  | 
0:7da612835693 | 221 | return FTLIB_ERR_DEVICE_NOT_OPEN; | 
| networker  | 
0:7da612835693 | 222 | while (transferAktiv != FTX1STOP) { | 
| networker  | 
0:7da612835693 | 223 | fprintf(stderr, "Transfer ta still active\n"); | 
| networker  | 
0:7da612835693 | 224 | wait(1); | 
| networker  | 
0:7da612835693 | 225 | } | 
| networker  | 
0:7da612835693 | 226 | for (int i = 0; i < N_EXT_DEV; i++) | 
| networker  | 
0:7da612835693 | 227 | if (ta[i]!=0) { | 
| networker  | 
0:7da612835693 | 228 | delete ta[i]; | 
| networker  | 
0:7da612835693 | 229 | ta[i] = 0; | 
| networker  | 
0:7da612835693 | 230 | } | 
| networker  | 
0:7da612835693 | 231 | init = idle; | 
| networker  | 
0:7da612835693 | 232 | unsigned retval = Socket_Close(device); | 
| networker  | 
0:7da612835693 | 233 | if (retval) { | 
| networker  | 
0:7da612835693 | 234 | printf("Socket_Close(%d) returned %d\n", device, retval); | 
| networker  | 
0:7da612835693 | 235 | return FTLIB_ERR_FAILED; //or whatever | 
| networker  | 
0:7da612835693 | 236 | } | 
| networker  | 
0:7da612835693 | 237 | return 0; | 
| networker  | 
0:7da612835693 | 238 | } | 
| networker  | 
0:7da612835693 | 239 | |
| networker  | 
0:7da612835693 | 240 | |
| networker  | 
0:7da612835693 | 241 | |
| networker  | 
0:7da612835693 | 242 | void ftusbdevtxbt::FtThreadBegin() { | 
| networker  | 
0:7da612835693 | 243 | if (init != ready) {//still initialising | 
| networker  | 
0:7da612835693 | 244 | busy = false; | 
| networker  | 
0:7da612835693 | 245 | return; | 
| networker  | 
0:7da612835693 | 246 | } | 
| networker  | 
0:7da612835693 | 247 | ftusbdevtx::FtThreadBegin(); | 
| networker  | 
0:7da612835693 | 248 | } | 
| networker  | 
0:7da612835693 | 249 | |
| networker  | 
0:7da612835693 | 250 | void ftusbdevtxbt::FtThreadEnd() { | 
| networker  | 
0:7da612835693 | 251 | if (!test_and_set()) {//skip when busy | 
| networker  | 
0:7da612835693 | 252 | busy = false; | 
| networker  | 
0:7da612835693 | 253 | printf("TA busy: skip end slot\n"); | 
| networker  | 
0:7da612835693 | 254 | return; | 
| networker  | 
0:7da612835693 | 255 | } | 
| networker  | 
0:7da612835693 | 256 | X1_cmd = rec_msg2((headerbody*)X1_pkt, X1_len); //parse the message | 
| networker  | 
0:7da612835693 | 257 | increment(); //release the TA mutex | 
| networker  | 
0:7da612835693 | 258 | if (ne.NotificationCallback) { | 
| networker  | 
0:7da612835693 | 259 | ne.NotificationCallback(ne.Context); | 
| networker  | 
0:7da612835693 | 260 | } | 
| networker  | 
0:7da612835693 | 261 | transferAktiv = FTX1RUN;//TA update complete | 
| networker  | 
0:7da612835693 | 262 | if (tid%100 == 0) { //about every 1 seconds | 
| networker  | 
0:7da612835693 | 263 | // getSlaveInfo(); //synchronous! TODO: change to non-blocking | 
| networker  | 
0:7da612835693 | 264 | } | 
| networker  | 
0:7da612835693 | 265 | busy = false; //ready for the next tick | 
| networker  | 
0:7da612835693 | 266 | // printf("Busy released\n"); | 
| networker  | 
0:7da612835693 | 267 | } | 
| networker  | 
0:7da612835693 | 268 | #if 0 | 
| networker  | 
0:7da612835693 | 269 | |
| networker  | 
0:7da612835693 | 270 | UINT16 ftusbdevtxbt::checksum(unsigned char *p, unsigned n) { | 
| networker  | 
0:7da612835693 | 271 | UINT16 sum = 0; | 
| networker  | 
0:7da612835693 | 272 | do { | 
| networker  | 
0:7da612835693 | 273 | sum -= *p++; | 
| networker  | 
0:7da612835693 | 274 | } while (--n); | 
| networker  | 
0:7da612835693 | 275 | return (sum<<8)|(sum>>8); | 
| networker  | 
0:7da612835693 | 276 | } | 
| networker  | 
0:7da612835693 | 277 | |
| networker  | 
0:7da612835693 | 278 | void ftusbdevtxbt::dump_buffer(int size) { | 
| networker  | 
0:7da612835693 | 279 | if (buffer==0) { | 
| networker  | 
0:7da612835693 | 280 | printf("No buffer\n"); | 
| networker  | 
0:7da612835693 | 281 | return; | 
| networker  | 
0:7da612835693 | 282 | } | 
| networker  | 
0:7da612835693 | 283 | for (int i = 0; i < size; i++) { | 
| networker  | 
0:7da612835693 | 284 | printf("%02X ", buffer[i]); | 
| networker  | 
0:7da612835693 | 285 | if (i%16 == 15) printf("\n"); | 
| networker  | 
0:7da612835693 | 286 | } | 
| networker  | 
0:7da612835693 | 287 | printf("----------------------\n"); | 
| networker  | 
0:7da612835693 | 288 | } | 
| networker  | 
0:7da612835693 | 289 | |
| networker  | 
0:7da612835693 | 290 | unsigned ftusbdevtxbt::send_msg(unsigned cmd, unsigned set, bool sync) { | 
| networker  | 
0:7da612835693 | 291 | const unsigned sizes[] = {0, 0, //cmd 1 | 
| networker  | 
0:7da612835693 | 292 | sizeof(TA_OUTPUT)+sizeof(UINT32), //cmd 2 | 
| networker  | 
0:7da612835693 | 293 | 0, //unknown | 
| networker  | 
0:7da612835693 | 294 | 0, //unknown | 
| networker  | 
0:7da612835693 | 295 | sizeof(TA_CONFIG)+sizeof(UINT32), //cmd 5 | 
| networker  | 
0:7da612835693 | 296 | sizeof(UINT32), //cmd 6 | 
| networker  | 
0:7da612835693 | 297 | sizeof(UINT32), //cmd 7 | 
| networker  | 
0:7da612835693 | 298 | sizeof(DISPLAY_MSG)+sizeof(UINT32), //cmd 8 | 
| networker  | 
0:7da612835693 | 299 | DEV_NAME_LEN + 1+3 + sizeof(UINT32) //cmd 9 | 
| networker  | 
0:7da612835693 | 300 | }; | 
| networker  | 
0:7da612835693 | 301 | int ret = 0; | 
| networker  | 
0:7da612835693 | 302 | int n = 0; | 
| networker  | 
0:7da612835693 | 303 | for (int i = TA_LOCAL; i < TA_N_PARTS; i++) { | 
| networker  | 
0:7da612835693 | 304 | if (set & (1<<i)) { | 
| networker  | 
0:7da612835693 | 305 | n++; | 
| networker  | 
0:7da612835693 | 306 | } | 
| networker  | 
0:7da612835693 | 307 | } | 
| networker  | 
0:7da612835693 | 308 | unsigned size = 0; | 
| networker  | 
0:7da612835693 | 309 | if (cmd < sizeof(sizes)/sizeof(unsigned)) | 
| networker  | 
0:7da612835693 | 310 | size = sizes[cmd]; | 
| networker  | 
0:7da612835693 | 311 | unsigned payload_size = n*size; | 
| networker  | 
0:7da612835693 | 312 | num_read = sizeof(header)+sizeof(trailer); | 
| networker  | 
0:7da612835693 | 313 | unsigned total_size = sizeof(header)+payload_size+sizeof(trailer); | 
| networker  | 
0:7da612835693 | 314 | buffer = new unsigned char[total_size]; //size must be known in advance | 
| networker  | 
0:7da612835693 | 315 | |
| networker  | 
0:7da612835693 | 316 | unsigned net_size = total_size-sizeof(UINT32)-sizeof(trailer);//exclude start,len,crc,etx | 
| networker  | 
0:7da612835693 | 317 | header *hdr = (header*)buffer; | 
| networker  | 
0:7da612835693 | 318 | hdr->start = 0x5502; | 
| networker  | 
0:7da612835693 | 319 | hdr->bytesH = net_size>>8; | 
| networker  | 
0:7da612835693 | 320 | hdr->bytesL = net_size&0xff; | 
| networker  | 
0:7da612835693 | 321 | hdr->snd = 2; | 
| networker  | 
0:7da612835693 | 322 | hdr->rec = 1; | 
| networker  | 
0:7da612835693 | 323 | hdr->trans = ++tid; | 
| networker  | 
0:7da612835693 | 324 | hdr->session = sid; | 
| networker  | 
0:7da612835693 | 325 | hdr->cmd = cmd; | 
| networker  | 
0:7da612835693 | 326 | hdr->structs = n; | 
| networker  | 
0:7da612835693 | 327 | unsigned char* payload = buffer+sizeof(header); | 
| networker  | 
0:7da612835693 | 328 | for (int i = TA_LOCAL; i < TA_N_PARTS; i++) { | 
| networker  | 
0:7da612835693 | 329 | if (ta[i]==0 || !(set & (1<<i))) { | 
| networker  | 
0:7da612835693 | 330 | if (set & (1<<i)) printf("TX %d is not open yet!\n", i); | 
| networker  | 
0:7da612835693 | 331 | continue; | 
| networker  | 
0:7da612835693 | 332 | } | 
| networker  | 
0:7da612835693 | 333 | unsigned *id = (unsigned*)payload; | 
| networker  | 
0:7da612835693 | 334 | *id = i; | 
| networker  | 
0:7da612835693 | 335 | payload = (unsigned char*)(id+1); | 
| networker  | 
0:7da612835693 | 336 | num_read += sizeof(UINT32); | 
| networker  | 
0:7da612835693 | 337 | switch (cmd) { | 
| networker  | 
0:7da612835693 | 338 | case 1: | 
| networker  | 
0:7da612835693 | 339 | break; | 
| networker  | 
0:7da612835693 | 340 | case 2: | 
| networker  | 
0:7da612835693 | 341 | memcpy(payload, &ta[i]->output, sizeof(TA_OUTPUT)); | 
| networker  | 
0:7da612835693 | 342 | payload += sizeof(TA_OUTPUT); | 
| networker  | 
0:7da612835693 | 343 | num_read += sizeof(TA_INPUT); | 
| networker  | 
0:7da612835693 | 344 | break; | 
| networker  | 
0:7da612835693 | 345 | case 5: | 
| networker  | 
0:7da612835693 | 346 | memcpy(payload, &ta[i]->config, sizeof(TA_CONFIG)); | 
| networker  | 
0:7da612835693 | 347 | payload += sizeof(TA_OUTPUT); | 
| networker  | 
0:7da612835693 | 348 | break; | 
| networker  | 
0:7da612835693 | 349 | case 6: | 
| networker  | 
0:7da612835693 | 350 | num_read += sizeof(TA_INFO); | 
| networker  | 
0:7da612835693 | 351 | break; | 
| networker  | 
0:7da612835693 | 352 | case 7: | 
| networker  | 
0:7da612835693 | 353 | num_read += sizeof(TA_STATE); | 
| networker  | 
0:7da612835693 | 354 | break; | 
| networker  | 
0:7da612835693 | 355 | case 8: | 
| networker  | 
0:7da612835693 | 356 | memcpy(payload, &ta[i]->display.display_msg, sizeof(DISPLAY_MSG)); | 
| networker  | 
0:7da612835693 | 357 | payload += sizeof(DISPLAY_MSG); | 
| networker  | 
0:7da612835693 | 358 | break; | 
| networker  | 
0:7da612835693 | 359 | case 9: | 
| networker  | 
0:7da612835693 | 360 | memcpy(payload, ta[i]->info.device_name, DEV_NAME_LEN + 1+3); | 
| networker  | 
0:7da612835693 | 361 | payload += sizeof(DEV_NAME_LEN + 1+3); | 
| networker  | 
0:7da612835693 | 362 | break; | 
| networker  | 
0:7da612835693 | 363 | default: | 
| networker  | 
0:7da612835693 | 364 | printf("Unknown message type %d\n", cmd); | 
| networker  | 
0:7da612835693 | 365 | break; | 
| networker  | 
0:7da612835693 | 366 | } | 
| networker  | 
0:7da612835693 | 367 | } | 
| networker  | 
0:7da612835693 | 368 | trailer *trl = (trailer*)payload; | 
| networker  | 
0:7da612835693 | 369 | trl->chksum = checksum(buffer+2, net_size+2); | 
| networker  | 
0:7da612835693 | 370 | trl->etx = '\x03'; | 
| networker  | 
0:7da612835693 | 371 | num_read--; | 
| networker  | 
0:7da612835693 | 372 | //dump_buffer(total_size); | 
| networker  | 
0:7da612835693 | 373 | //printf("Expecting %d bytes for transaction %d\n", num_read, tid); | 
| networker  | 
0:7da612835693 | 374 | if (sync) { | 
| networker  | 
0:7da612835693 | 375 | ret = USBBulkTransfer(device, 3, buffer, total_size-1);//send 1 less because trailer is 1 too long due to alignment | 
| networker  | 
0:7da612835693 | 376 | delete[] buffer; | 
| networker  | 
0:7da612835693 | 377 | if (ret < 0) | 
| networker  | 
0:7da612835693 | 378 | printf("synchronous send_message failed (%d)\n", ret); | 
| networker  | 
0:7da612835693 | 379 | else { | 
| networker  | 
0:7da612835693 | 380 | buffer = new unsigned char[num_read]; | 
| networker  | 
0:7da612835693 | 381 | ret = USBInterruptTransfer(device, 0x82, buffer, num_read); | 
| networker  | 
0:7da612835693 | 382 | if (ret < 0) { | 
| networker  | 
0:7da612835693 | 383 | printf("synchronous read failed (%d)\n", ret); | 
| networker  | 
0:7da612835693 | 384 | delete[] buffer; | 
| networker  | 
0:7da612835693 | 385 | } else { | 
| networker  | 
0:7da612835693 | 386 | //dump_buffer(num_read); | 
| networker  | 
0:7da612835693 | 387 | rec_msg(); | 
| networker  | 
0:7da612835693 | 388 | } | 
| networker  | 
0:7da612835693 | 389 | } | 
| networker  | 
0:7da612835693 | 390 | } else | 
| networker  | 
0:7da612835693 | 391 | USBBulkTransfer(device, 3, buffer, total_size-1, &ftusbdevtxbt::write_finished_cb, this); | 
| networker  | 
0:7da612835693 | 392 | return ret; | 
| networker  | 
0:7da612835693 | 393 | } | 
| networker  | 
0:7da612835693 | 394 | |
| networker  | 
0:7da612835693 | 395 | unsigned ftusbdevtxbt::rec_msg() { | 
| networker  | 
0:7da612835693 | 396 | header *hdr = (header*)buffer; | 
| networker  | 
0:7da612835693 | 397 | //dump_buffer(num_read); | 
| networker  | 
0:7da612835693 | 398 | if (hdr->start != 0x5502) printf("Invalid packet\n"); | 
| networker  | 
0:7da612835693 | 399 | unsigned net_size = (hdr->bytesH<<8) + hdr->bytesL; | 
| networker  | 
0:7da612835693 | 400 | if (net_size+7 != num_read) printf("message has %d bytes, was expecting %d bytes\n", net_size+7, num_read); | 
| networker  | 
0:7da612835693 | 401 | //printf("message %d from %d\n", hdr->cmd, hdr->snd); | 
| networker  | 
0:7da612835693 | 402 | if (hdr->rec != 2) printf("Wrong destination (%d)\n", hdr->rec); | 
| networker  | 
0:7da612835693 | 403 | if (hdr->trans != tid) printf("Response to request %d, expected %d\n", hdr->trans, tid); | 
| networker  | 
0:7da612835693 | 404 | if (hdr->session != sid) { | 
| networker  | 
0:7da612835693 | 405 | printf("Session number has changed from %d to %d\n", sid, hdr->session); | 
| networker  | 
0:7da612835693 | 406 | sid = hdr->session; | 
| networker  | 
0:7da612835693 | 407 | tid = 1; //restart transaction sequence | 
| networker  | 
0:7da612835693 | 408 | } | 
| networker  | 
0:7da612835693 | 409 | unsigned cmd = hdr->cmd - 100; | 
| networker  | 
0:7da612835693 | 410 | unsigned n = hdr->structs; | 
| networker  | 
0:7da612835693 | 411 | unsigned char* payload = buffer+sizeof(header); | 
| networker  | 
0:7da612835693 | 412 | trailer *trl = (trailer*)(buffer+net_size+4); | 
| networker  | 
0:7da612835693 | 413 | for (int i = 0; i < n && payload < (unsigned char*)trl; i++) { | 
| networker  | 
0:7da612835693 | 414 | unsigned *id = (unsigned*)payload; | 
| networker  | 
0:7da612835693 | 415 | if (*id >= TA_N_PARTS) { | 
| networker  | 
0:7da612835693 | 416 | printf("Illegal extension nr %d\n", *id); | 
| networker  | 
0:7da612835693 | 417 | continue; | 
| networker  | 
0:7da612835693 | 418 | } | 
| networker  | 
0:7da612835693 | 419 | if (ta[*id]==0) { | 
| networker  | 
0:7da612835693 | 420 | printf("Message for new device %d\n", *id); | 
| networker  | 
0:7da612835693 | 421 | continue;//skip the copy to avoid assignment to null ta but the payload pointer is not advanced! stopping further copying | 
| networker  | 
0:7da612835693 | 422 | } | 
| networker  | 
0:7da612835693 | 423 | payload = (unsigned char*)(id+1); | 
| networker  | 
0:7da612835693 | 424 | switch (cmd) { | 
| networker  | 
0:7da612835693 | 425 | case 1: | 
| networker  | 
0:7da612835693 | 426 | break; | 
| networker  | 
0:7da612835693 | 427 | case 2: | 
| networker  | 
0:7da612835693 | 428 | memcpy(&ta[*id]->input, payload, sizeof(TA_INPUT)); | 
| networker  | 
0:7da612835693 | 429 | payload += sizeof(TA_INPUT); | 
| networker  | 
0:7da612835693 | 430 | break; | 
| networker  | 
0:7da612835693 | 431 | case 5: | 
| networker  | 
0:7da612835693 | 432 | break; | 
| networker  | 
0:7da612835693 | 433 | case 6: | 
| networker  | 
0:7da612835693 | 434 | memcpy(&ta[*id]->info, payload, sizeof(TA_INFO)); | 
| networker  | 
0:7da612835693 | 435 | payload += sizeof(TA_INFO); | 
| networker  | 
0:7da612835693 | 436 | break; | 
| networker  | 
0:7da612835693 | 437 | case 7: | 
| networker  | 
0:7da612835693 | 438 | memcpy(&ta[*id]->state, payload, sizeof(TA_STATE)); | 
| networker  | 
0:7da612835693 | 439 | payload += sizeof(TA_STATE); | 
| networker  | 
0:7da612835693 | 440 | break; | 
| networker  | 
0:7da612835693 | 441 | case 8: | 
| networker  | 
0:7da612835693 | 442 | break; | 
| networker  | 
0:7da612835693 | 443 | case 9: | 
| networker  | 
0:7da612835693 | 444 | break; | 
| networker  | 
0:7da612835693 | 445 | default: | 
| networker  | 
0:7da612835693 | 446 | printf("Unknown message type %d\n", cmd); | 
| networker  | 
0:7da612835693 | 447 | break; | 
| networker  | 
0:7da612835693 | 448 | } | 
| networker  | 
0:7da612835693 | 449 | } | 
| networker  | 
0:7da612835693 | 450 | if (payload != (unsigned char*)trl) printf("expected %d sections with in total %d bytes; got %d bytes\n", n, payload-buffer-sizeof(header), net_size-sizeof(header)); | 
| networker  | 
0:7da612835693 | 451 | if (trl->chksum != checksum(buffer+2, net_size+2)) printf("Checksum error\n"); | 
| networker  | 
0:7da612835693 | 452 | if (trl->etx != '\x03') printf("Expected ETX(03), got %02X\n", trl->etx); | 
| networker  | 
0:7da612835693 | 453 | delete[] buffer; | 
| networker  | 
0:7da612835693 | 454 | return 0; | 
| networker  | 
0:7da612835693 | 455 | } | 
| networker  | 
0:7da612835693 | 456 | |
| networker  | 
0:7da612835693 | 457 | void ftusbdevtxbt::read_finished_cb(int device, int endpoint, int status, u8* data, int len, void* userData) { | 
| networker  | 
0:7da612835693 | 458 | //end of reply transfer | 
| networker  | 
0:7da612835693 | 459 | //printf("read_finished_cb: %d bytes\n", len); | 
| networker  | 
0:7da612835693 | 460 | ftusbdevtx *fth = (ftusbdevtx*)userData; | 
| networker  | 
0:7da612835693 | 461 | if (fth->transferAktiv == FTX1SYNC) | 
| networker  | 
0:7da612835693 | 462 | fth->FtThreadEnd(); | 
| networker  | 
0:7da612835693 | 463 | else | 
| networker  | 
0:7da612835693 | 464 | fth->rec_msg(); | 
| networker  | 
0:7da612835693 | 465 | } | 
| networker  | 
0:7da612835693 | 466 | |
| networker  | 
0:7da612835693 | 467 | void ftusbdevtxbt::write_finished_cb(int device, int endpoint, int status, u8* data, int len, void* userData) { //end of request transfer, issue, reply transfer | 
| networker  | 
0:7da612835693 | 468 | ftusbdevtx *fth = (ftusbdevtx*)userData; | 
| networker  | 
0:7da612835693 | 469 | //printf("write_finished_cb: wrote %d bytes, reading %d bytes\n", len, fth->num_read); | 
| networker  | 
0:7da612835693 | 470 | delete[] fth->buffer; | 
| networker  | 
0:7da612835693 | 471 | fth->buffer = new unsigned char[fth->num_read]; | 
| networker  | 
0:7da612835693 | 472 | USBInterruptTransfer(fth->device, 0x82, fth->buffer, fth->num_read, read_finished_cb, fth); | 
| networker  | 
0:7da612835693 | 473 | } | 
| networker  | 
0:7da612835693 | 474 | #endif |