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.
Fork of football_project by
PhoneAppIO.cpp@75:1b357bee1839, 2016-04-03 (annotated)
- Committer:
- AntonLS
- Date:
- Sun Apr 03 08:56:32 2016 +0000
- Revision:
- 75:1b357bee1839
- Parent:
- 19:afcbb425b3cf
Prevent repeated BAD CRC on ACK msg. Response added for u beep cmd to prevent BT buffer problem. New radio-send flush methods.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| AntonLS | 5:1b9734e68327 | 1 | /* |
| AntonLS | 5:1b9734e68327 | 2 | * Buffered IO of pending CharacteristicWrites meant to Nofify |
| AntonLS | 11:d3aa5fca2330 | 3 | * the phone/tablet application and reading of Characteristic |
| AntonLS | 11:d3aa5fca2330 | 4 | * set by the phone/tablet application. Started 20150416 ALS |
| AntonLS | 5:1b9734e68327 | 5 | * |
| AntonLS | 5:1b9734e68327 | 6 | */ |
| AntonLS | 5:1b9734e68327 | 7 | |
| AntonLS | 5:1b9734e68327 | 8 | #include "PhoneAppIO.h" |
| AntonLS | 5:1b9734e68327 | 9 | |
| AntonLS | 11:d3aa5fca2330 | 10 | PhoneAppIO::PhoneAppIO( BLEDevice &ble, GattAttribute::Handle_t toPhoneHandle, |
| AntonLS | 11:d3aa5fca2330 | 11 | GattAttribute::Handle_t toConeHandle, |
| AntonLS | 11:d3aa5fca2330 | 12 | int txBufferSize, int rxBufferSize ) |
| AntonLS | 11:d3aa5fca2330 | 13 | : mts::MTSBufferedIO( txBufferSize, rxBufferSize ), |
| AntonLS | 11:d3aa5fca2330 | 14 | bleP( &ble ), toPhoneHandle( toPhoneHandle ), |
| AntonLS | 11:d3aa5fca2330 | 15 | toConeHandle( toConeHandle ) |
| AntonLS | 5:1b9734e68327 | 16 | { |
| AntonLS | 11:d3aa5fca2330 | 17 | loopbackMode = false; |
| AntonLS | 11:d3aa5fca2330 | 18 | bleWasntReady = false; |
| AntonLS | 11:d3aa5fca2330 | 19 | |
| AntonLS | 11:d3aa5fca2330 | 20 | enableTxIrq(); |
| AntonLS | 11:d3aa5fca2330 | 21 | enableRxIrq(); |
| AntonLS | 11:d3aa5fca2330 | 22 | |
| AntonLS | 11:d3aa5fca2330 | 23 | data = NULL; |
| AntonLS | 11:d3aa5fca2330 | 24 | bytesRead = 0; |
| AntonLS | 11:d3aa5fca2330 | 25 | |
| AntonLS | 11:d3aa5fca2330 | 26 | memset( rx_buf, 0, TXRX_BUF_LEN ); |
| AntonLS | 11:d3aa5fca2330 | 27 | rx_len = 0; |
| AntonLS | 5:1b9734e68327 | 28 | } |
| AntonLS | 5:1b9734e68327 | 29 | |
| AntonLS | 5:1b9734e68327 | 30 | PhoneAppIO::~PhoneAppIO() |
| AntonLS | 5:1b9734e68327 | 31 | { |
| AntonLS | 5:1b9734e68327 | 32 | } |
| AntonLS | 5:1b9734e68327 | 33 | |
| AntonLS | 11:d3aa5fca2330 | 34 | uint16_t PhoneAppIO::maybeHandleRead( const GattCharacteristicWriteCBParams *params ) // Called by onDataWritten() from BLE. |
| AntonLS | 11:d3aa5fca2330 | 35 | { // also writes to txPayload |
| AntonLS | 11:d3aa5fca2330 | 36 | bytesRead = 0; |
| AntonLS | 5:1b9734e68327 | 37 | |
| AntonLS | 11:d3aa5fca2330 | 38 | if( params->charHandle == toConeHandle ) |
| AntonLS | 11:d3aa5fca2330 | 39 | { |
| AntonLS | 11:d3aa5fca2330 | 40 | uint8_t buf[TXRX_BUF_LEN]; |
| AntonLS | 11:d3aa5fca2330 | 41 | bytesRead = MIN( params->len, TXRX_BUF_LEN ); |
| AntonLS | 11:d3aa5fca2330 | 42 | |
| AntonLS | 11:d3aa5fca2330 | 43 | if( loopbackMode ) |
| AntonLS | 11:d3aa5fca2330 | 44 | { |
| AntonLS | 11:d3aa5fca2330 | 45 | // Loopback data from Central. |
| AntonLS | 11:d3aa5fca2330 | 46 | updateCharacteristic( toPhoneHandle, params->data, bytesRead ); // Notifies. // TODO apply retries to this as well, |
| AntonLS | 11:d3aa5fca2330 | 47 | // but they might not be needed here. |
| AntonLS | 11:d3aa5fca2330 | 48 | } |
| AntonLS | 11:d3aa5fca2330 | 49 | |
| AntonLS | 75:1b357bee1839 | 50 | ble_error_t err = bleP->readCharacteristicValue( toConeHandle, buf, &bytesRead ); |
| AntonLS | 11:d3aa5fca2330 | 51 | |
| AntonLS | 11:d3aa5fca2330 | 52 | // Copy data to accessible location for others and handleRead(). |
| AntonLS | 11:d3aa5fca2330 | 53 | memset( txPayload, 0, TXRX_BUF_LEN ); |
| AntonLS | 11:d3aa5fca2330 | 54 | memcpy( txPayload, buf, bytesRead ); |
| AntonLS | 11:d3aa5fca2330 | 55 | |
| AntonLS | 11:d3aa5fca2330 | 56 | // Buffer the data. |
| AntonLS | 11:d3aa5fca2330 | 57 | data = (char *)txPayload; |
| AntonLS | 11:d3aa5fca2330 | 58 | handleRead(); |
| AntonLS | 11:d3aa5fca2330 | 59 | } |
| AntonLS | 11:d3aa5fca2330 | 60 | |
| AntonLS | 11:d3aa5fca2330 | 61 | return bytesRead; |
| AntonLS | 11:d3aa5fca2330 | 62 | } |
| AntonLS | 11:d3aa5fca2330 | 63 | |
| AntonLS | 19:afcbb425b3cf | 64 | uint16_t PhoneAppIO::injectHandleRead( char *buf, int len ) // Inject data from elsewhere simulating BLE-in. |
| AntonLS | 19:afcbb425b3cf | 65 | { // also writes to txPayload |
| AntonLS | 19:afcbb425b3cf | 66 | int bytesRead = 0; |
| AntonLS | 19:afcbb425b3cf | 67 | |
| AntonLS | 19:afcbb425b3cf | 68 | if( (NULL != buf) && (0 < len) ) |
| AntonLS | 19:afcbb425b3cf | 69 | { |
| AntonLS | 19:afcbb425b3cf | 70 | bytesRead = MIN( len, TXRX_BUF_LEN ); |
| AntonLS | 19:afcbb425b3cf | 71 | |
| AntonLS | 19:afcbb425b3cf | 72 | // Copy data to accessible location for others and handleRead(). |
| AntonLS | 19:afcbb425b3cf | 73 | memset( txPayload, 0, TXRX_BUF_LEN ); |
| AntonLS | 19:afcbb425b3cf | 74 | memcpy( txPayload, buf, bytesRead ); |
| AntonLS | 19:afcbb425b3cf | 75 | |
| AntonLS | 19:afcbb425b3cf | 76 | // Buffer the data. |
| AntonLS | 19:afcbb425b3cf | 77 | data = (char *)txPayload; |
| AntonLS | 19:afcbb425b3cf | 78 | handleRead(); |
| AntonLS | 19:afcbb425b3cf | 79 | } |
| AntonLS | 19:afcbb425b3cf | 80 | |
| AntonLS | 19:afcbb425b3cf | 81 | return bytesRead; |
| AntonLS | 19:afcbb425b3cf | 82 | } |
| AntonLS | 19:afcbb425b3cf | 83 | |
| AntonLS | 11:d3aa5fca2330 | 84 | // Maybe write to RX characteristic (From cone to phone.) |
| AntonLS | 11:d3aa5fca2330 | 85 | uint16_t PhoneAppIO::maybeHandleWrite() // Called by toPhoneChk() from main loop. |
| AntonLS | 5:1b9734e68327 | 86 | { |
| AntonLS | 11:d3aa5fca2330 | 87 | uint16_t charsWritten = 0; |
| AntonLS | 11:d3aa5fca2330 | 88 | |
| AntonLS | 11:d3aa5fca2330 | 89 | while( true ) |
| AntonLS | 11:d3aa5fca2330 | 90 | { |
| AntonLS | 11:d3aa5fca2330 | 91 | if( !bleWasntReady ) |
| AntonLS | 11:d3aa5fca2330 | 92 | { |
| AntonLS | 11:d3aa5fca2330 | 93 | char ch; |
| AntonLS | 11:d3aa5fca2330 | 94 | |
| AntonLS | 11:d3aa5fca2330 | 95 | while( writing ); // Block. |
| AntonLS | 11:d3aa5fca2330 | 96 | |
| AntonLS | 11:d3aa5fca2330 | 97 | if( 0 == txBuffer.read( ch ) ) break; |
| AntonLS | 11:d3aa5fca2330 | 98 | |
| AntonLS | 11:d3aa5fca2330 | 99 | if( '\n' == ch ) continue; // Filter linefeeds. |
| AntonLS | 11:d3aa5fca2330 | 100 | rx_buf[rx_len++] = ch; |
| AntonLS | 11:d3aa5fca2330 | 101 | } |
| AntonLS | 11:d3aa5fca2330 | 102 | if( bleWasntReady || rx_len>=TXRX_BUF_LEN || rx_buf[rx_len-1]=='\r' || rx_buf[rx_len-1]=='\0' ) |
| AntonLS | 11:d3aa5fca2330 | 103 | { |
| AntonLS | 11:d3aa5fca2330 | 104 | handleWrite(); |
| AntonLS | 11:d3aa5fca2330 | 105 | |
| AntonLS | 11:d3aa5fca2330 | 106 | if( bleWasntReady ) break; // Don't loop on not ready (Don't starve main loop.) |
| AntonLS | 11:d3aa5fca2330 | 107 | |
| AntonLS | 11:d3aa5fca2330 | 108 | charsWritten = rx_len; |
| AntonLS | 11:d3aa5fca2330 | 109 | |
| AntonLS | 11:d3aa5fca2330 | 110 | rx_len = 0; |
| AntonLS | 11:d3aa5fca2330 | 111 | break; |
| AntonLS | 11:d3aa5fca2330 | 112 | } |
| AntonLS | 11:d3aa5fca2330 | 113 | } |
| AntonLS | 11:d3aa5fca2330 | 114 | |
| AntonLS | 11:d3aa5fca2330 | 115 | return charsWritten; |
| AntonLS | 5:1b9734e68327 | 116 | } |
| AntonLS | 5:1b9734e68327 | 117 | |
| AntonLS | 5:1b9734e68327 | 118 | void PhoneAppIO::handleRead() |
| AntonLS | 5:1b9734e68327 | 119 | { |
| AntonLS | 75:1b357bee1839 | 120 | //// while( reading ); // Block. |
| AntonLS | 11:d3aa5fca2330 | 121 | |
| AntonLS | 11:d3aa5fca2330 | 122 | int charsToBuf = rxBuffer.write( data, bytesRead ); |
| AntonLS | 5:1b9734e68327 | 123 | if( charsToBuf != bytesRead ) |
| AntonLS | 5:1b9734e68327 | 124 | { |
| AntonLS | 11:d3aa5fca2330 | 125 | ::printf( "[ERROR] ToPhoneCharacteristic Data Lost, tried %d, got %d\r\n", bytesRead, charsToBuf ); |
| AntonLS | 5:1b9734e68327 | 126 | } |
| AntonLS | 75:1b357bee1839 | 127 | DEBUG( "Got:%s", data ); |
| AntonLS | 5:1b9734e68327 | 128 | } |
| AntonLS | 5:1b9734e68327 | 129 | |
| AntonLS | 11:d3aa5fca2330 | 130 | /** This method used to transfer data from the internal write buffer |
| AntonLS | 11:d3aa5fca2330 | 131 | * (txBuffer) to the physical interface, but we have an intermediate |
| AntonLS | 11:d3aa5fca2330 | 132 | * buffer (rx_buf) in case of failure, so it can be retried. |
| AntonLS | 11:d3aa5fca2330 | 133 | */ |
| AntonLS | 5:1b9734e68327 | 134 | void PhoneAppIO::handleWrite() |
| AntonLS | 5:1b9734e68327 | 135 | { |
| AntonLS | 11:d3aa5fca2330 | 136 | bleWasntReady = updateCharacteristic( toPhoneHandle, rx_buf, rx_len ); // Notifies. |
| AntonLS | 11:d3aa5fca2330 | 137 | busy = bleWasntReady; |
| AntonLS | 5:1b9734e68327 | 138 | } |
| AntonLS | 5:1b9734e68327 | 139 | |
| AntonLS | 11:d3aa5fca2330 | 140 | // I think we don't need to use these because I'm guessing |
| AntonLS | 75:1b357bee1839 | 141 | // all reads happen during main loop ble.waitForEvent()? -- Not using waitForEvent() now. |
| AntonLS | 11:d3aa5fca2330 | 142 | |
| AntonLS | 11:d3aa5fca2330 | 143 | // For locking out read() during write() to prevent buffer state corruption. |
| AntonLS | 11:d3aa5fca2330 | 144 | void PhoneAppIO::disableTxIrq(){ writing = true; } |
| AntonLS | 11:d3aa5fca2330 | 145 | void PhoneAppIO::enableTxIrq() { writing = false; } |
| AntonLS | 11:d3aa5fca2330 | 146 | |
| AntonLS | 11:d3aa5fca2330 | 147 | // For locking out write() during read() to prevent buffer state corruption. |
| AntonLS | 11:d3aa5fca2330 | 148 | void PhoneAppIO::disableRxIrq(){ reading = true; } |
| AntonLS | 11:d3aa5fca2330 | 149 | void PhoneAppIO::enableRxIrq() { reading = false; } |
| AntonLS | 11:d3aa5fca2330 | 150 | |
| AntonLS | 5:1b9734e68327 | 151 | /* EOF */ |
