| 77 | } |
| 78 | |
| 79 | GpsResponse getACKCas(::Device* uart, uint8_t class_id, uint8_t msg_id, uint32_t waitMillis) |
| 80 | { |
| 81 | uint32_t startTime = kernel::getMillis(); |
| 82 | uint8_t buffer[CAS_ACK_NACK_MSG_SIZE] = {0}; |
| 83 | uint8_t bufferPos = 0; |
| 84 | TickType_t waitTicks = pdMS_TO_TICKS(waitMillis); |
| 85 | |
| 86 | // CAS-ACK-(N)ACK structure |
| 87 | // | H1 | H2 | Payload Len | cls | msg | Payload | Checksum (4) | |
| 88 | // | | | | | | Cls | Msg | Reserved | | |
| 89 | // |------|------|-------------|------|------|------|------|-------------|---------------------------| |
| 90 | // ACK-NACK| 0xBA | 0xCE | 0x04 | 0x00 | 0x05 | 0x00 | 0xXX | 0xXX | 0x00 | 0x00 | 0xXX | 0xXX | 0xXX | 0xXX | |
| 91 | // ACK-ACK | 0xBA | 0xCE | 0x04 | 0x00 | 0x05 | 0x01 | 0xXX | 0xXX | 0x00 | 0x00 | 0xXX | 0xXX | 0xXX | 0xXX | |
| 92 | |
| 93 | while (kernel::getTicks() - startTime < waitTicks) { |
| 94 | size_t available = 0; |
| 95 | uart_controller_get_available(uart, &available); |
| 96 | if (available > 0) { |
| 97 | uart_controller_read_byte(uart, &buffer[bufferPos++], 1); |
| 98 | |
| 99 | // keep looking at the first two bytes of buffer until |
| 100 | // we have found the CAS frame header (0xBA, 0xCE), if not |
| 101 | // keep reading bytes until we find a frame header or we run |
| 102 | // out of time. |
| 103 | if ((bufferPos == 2) && !(buffer[0] == 0xBA && buffer[1] == 0xCE)) { |
| 104 | buffer[0] = buffer[1]; |
| 105 | buffer[1] = 0; |
| 106 | bufferPos = 1; |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | // we have read all the bytes required for the Ack/Nack (14-bytes) |
| 111 | // and we must have found a frame to get this far |
| 112 | if (bufferPos == sizeof(buffer) - 1) { |
| 113 | uint8_t msg_cls = buffer[4]; // message class should be 0x05 |
| 114 | uint8_t msg_msg_id = buffer[5]; // message id should be 0x00 or 0x01 |
| 115 | uint8_t payload_cls = buffer[6]; // payload class id |
| 116 | uint8_t payload_msg = buffer[7]; // payload message id |
| 117 | |
| 118 | // Check for an ACK-ACK for the specified class and message id |
| 119 | if ((msg_cls == 0x05) && (msg_msg_id == 0x01) && payload_cls == class_id && payload_msg == msg_id) { |
| 120 | #ifdef GPS_DEBUG |
| 121 | LOGGER.info("Got ACK for class {:02X} message {:02X} in {} ms", class_id, msg_id, kernel::getMillis() - startTime); |
| 122 | #endif |
| 123 | return GpsResponse::Ok; |
| 124 | } |
| 125 | |
| 126 | // Check for an ACK-NACK for the specified class and message id |
| 127 | if ((msg_cls == 0x05) && (msg_msg_id == 0x00) && payload_cls == class_id && payload_msg == msg_id) { |
| 128 | #ifdef GPS_DEBUG |
| 129 | LOGGER.warn("Got NACK for class {:02X} message {:02X} in {} ms", class_id, msg_id, millis() - startTime); |
| 130 | #endif |
| 131 | return GpsResponse::NotAck; |
| 132 | } |
| 133 | |
| 134 | // This isn't the frame we are looking for, clear the buffer |
| 135 | // and try again until we run out of time. |
| 136 | memset(buffer, 0x0, sizeof(buffer)); |
no test coverage detected