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@19:afcbb425b3cf, 2015-12-01 (annotated)
- Committer:
- AntonLS
- Date:
- Tue Dec 01 16:03:15 2015 +0000
- Revision:
- 19:afcbb425b3cf
- Parent:
- 11:d3aa5fca2330
- Child:
- 75:1b357bee1839
Updated for new hardware. PhoneIO and protocol fixes.
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 | 11:d3aa5fca2330 | 50 | 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 | 11:d3aa5fca2330 | 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 | 5:1b9734e68327 | 127 | } |
| AntonLS | 5:1b9734e68327 | 128 | |
| AntonLS | 11:d3aa5fca2330 | 129 | /** This method used to transfer data from the internal write buffer |
| AntonLS | 11:d3aa5fca2330 | 130 | * (txBuffer) to the physical interface, but we have an intermediate |
| AntonLS | 11:d3aa5fca2330 | 131 | * buffer (rx_buf) in case of failure, so it can be retried. |
| AntonLS | 11:d3aa5fca2330 | 132 | */ |
| AntonLS | 5:1b9734e68327 | 133 | void PhoneAppIO::handleWrite() |
| AntonLS | 5:1b9734e68327 | 134 | { |
| AntonLS | 11:d3aa5fca2330 | 135 | bleWasntReady = updateCharacteristic( toPhoneHandle, rx_buf, rx_len ); // Notifies. |
| AntonLS | 11:d3aa5fca2330 | 136 | busy = bleWasntReady; |
| AntonLS | 5:1b9734e68327 | 137 | } |
| AntonLS | 5:1b9734e68327 | 138 | |
| AntonLS | 11:d3aa5fca2330 | 139 | // I think we don't need to use these because I'm guessing |
| AntonLS | 11:d3aa5fca2330 | 140 | // all reads happen during main loop ble.waitForEvent()? |
| AntonLS | 11:d3aa5fca2330 | 141 | |
| AntonLS | 11:d3aa5fca2330 | 142 | // For locking out read() during write() to prevent buffer state corruption. |
| AntonLS | 11:d3aa5fca2330 | 143 | void PhoneAppIO::disableTxIrq(){ writing = true; } |
| AntonLS | 11:d3aa5fca2330 | 144 | void PhoneAppIO::enableTxIrq() { writing = false; } |
| AntonLS | 11:d3aa5fca2330 | 145 | |
| AntonLS | 11:d3aa5fca2330 | 146 | // For locking out write() during read() to prevent buffer state corruption. |
| AntonLS | 11:d3aa5fca2330 | 147 | void PhoneAppIO::disableRxIrq(){ reading = true; } |
| AntonLS | 11:d3aa5fca2330 | 148 | void PhoneAppIO::enableRxIrq() { reading = false; } |
| AntonLS | 11:d3aa5fca2330 | 149 | |
| AntonLS | 5:1b9734e68327 | 150 | /* EOF */ |
