Forked to avoid changing the publioc repo

Dependencies:   BLE_API mbed-dev-bin nRF51822

Fork of microbit-dal by Lancaster University

Committer:
bluetooth_mdw
Date:
Thu Apr 20 13:42:44 2017 +0000
Revision:
74:4c7db2d5ca9a
Parent:
1:8aa5cdb4ab67
Example app showing how to include the Bluetooth accelerometer service in your micro:bit application code.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 1:8aa5cdb4ab67 1 /*
Jonathan Austin 1:8aa5cdb4ab67 2 The MIT License (MIT)
Jonathan Austin 1:8aa5cdb4ab67 3
Jonathan Austin 1:8aa5cdb4ab67 4 Copyright (c) 2016 British Broadcasting Corporation.
Jonathan Austin 1:8aa5cdb4ab67 5 This software is provided by Lancaster University by arrangement with the BBC.
Jonathan Austin 1:8aa5cdb4ab67 6
Jonathan Austin 1:8aa5cdb4ab67 7 Permission is hereby granted, free of charge, to any person obtaining a
Jonathan Austin 1:8aa5cdb4ab67 8 copy of this software and associated documentation files (the "Software"),
Jonathan Austin 1:8aa5cdb4ab67 9 to deal in the Software without restriction, including without limitation
Jonathan Austin 1:8aa5cdb4ab67 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
Jonathan Austin 1:8aa5cdb4ab67 11 and/or sell copies of the Software, and to permit persons to whom the
Jonathan Austin 1:8aa5cdb4ab67 12 Software is furnished to do so, subject to the following conditions:
Jonathan Austin 1:8aa5cdb4ab67 13
Jonathan Austin 1:8aa5cdb4ab67 14 The above copyright notice and this permission notice shall be included in
Jonathan Austin 1:8aa5cdb4ab67 15 all copies or substantial portions of the Software.
Jonathan Austin 1:8aa5cdb4ab67 16
Jonathan Austin 1:8aa5cdb4ab67 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jonathan Austin 1:8aa5cdb4ab67 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jonathan Austin 1:8aa5cdb4ab67 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Jonathan Austin 1:8aa5cdb4ab67 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Jonathan Austin 1:8aa5cdb4ab67 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 23 DEALINGS IN THE SOFTWARE.
Jonathan Austin 1:8aa5cdb4ab67 24 */
Jonathan Austin 1:8aa5cdb4ab67 25
Jonathan Austin 1:8aa5cdb4ab67 26 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 27 #include "MicroBitRadio.h"
Jonathan Austin 1:8aa5cdb4ab67 28
Jonathan Austin 1:8aa5cdb4ab67 29 /**
Jonathan Austin 1:8aa5cdb4ab67 30 * Provides a simple broadcast radio abstraction, built upon the raw nrf51822 RADIO module.
Jonathan Austin 1:8aa5cdb4ab67 31 *
Jonathan Austin 1:8aa5cdb4ab67 32 * This class provides the ability to broadcast simple text or binary messages to other micro:bits in the vicinity
Jonathan Austin 1:8aa5cdb4ab67 33 * It is envisaged that this would provide the basis for children to experiment with building their own, simple,
Jonathan Austin 1:8aa5cdb4ab67 34 * custom protocols.
Jonathan Austin 1:8aa5cdb4ab67 35 *
Jonathan Austin 1:8aa5cdb4ab67 36 * @note This API does not contain any form of encryption, authentication or authorisation. Its purpose is solely for use as a
Jonathan Austin 1:8aa5cdb4ab67 37 * teaching aid to demonstrate how simple communications operates, and to provide a sandpit through which learning can take place.
Jonathan Austin 1:8aa5cdb4ab67 38 * For serious applications, BLE should be considered a substantially more secure alternative.
Jonathan Austin 1:8aa5cdb4ab67 39 */
Jonathan Austin 1:8aa5cdb4ab67 40
Jonathan Austin 1:8aa5cdb4ab67 41 /**
Jonathan Austin 1:8aa5cdb4ab67 42 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 43 *
Jonathan Austin 1:8aa5cdb4ab67 44 * Creates an instance of a MicroBitRadioDatagram which offers the ability
Jonathan Austin 1:8aa5cdb4ab67 45 * to broadcast simple text or binary messages to other micro:bits in the vicinity
Jonathan Austin 1:8aa5cdb4ab67 46 *
Jonathan Austin 1:8aa5cdb4ab67 47 * @param r The underlying radio module used to send and receive data.
Jonathan Austin 1:8aa5cdb4ab67 48 */
Jonathan Austin 1:8aa5cdb4ab67 49 MicroBitRadioDatagram::MicroBitRadioDatagram(MicroBitRadio &r) : radio(r)
Jonathan Austin 1:8aa5cdb4ab67 50 {
Jonathan Austin 1:8aa5cdb4ab67 51 this->rxQueue = NULL;
Jonathan Austin 1:8aa5cdb4ab67 52 }
Jonathan Austin 1:8aa5cdb4ab67 53
Jonathan Austin 1:8aa5cdb4ab67 54 /**
Jonathan Austin 1:8aa5cdb4ab67 55 * Retrieves packet payload data into the given buffer.
Jonathan Austin 1:8aa5cdb4ab67 56 *
Jonathan Austin 1:8aa5cdb4ab67 57 * If a data packet is already available, then it will be returned immediately to the caller.
Jonathan Austin 1:8aa5cdb4ab67 58 * If no data is available then MICROBIT_INVALID_PARAMETER is returned.
Jonathan Austin 1:8aa5cdb4ab67 59 *
Jonathan Austin 1:8aa5cdb4ab67 60 * @param buf A pointer to a valid memory location where the received data is to be stored
Jonathan Austin 1:8aa5cdb4ab67 61 *
Jonathan Austin 1:8aa5cdb4ab67 62 * @param len The maximum amount of data that can safely be stored in 'buf'
Jonathan Austin 1:8aa5cdb4ab67 63 *
Jonathan Austin 1:8aa5cdb4ab67 64 * @return The length of the data stored, or MICROBIT_INVALID_PARAMETER if no data is available, or the memory regions provided are invalid.
Jonathan Austin 1:8aa5cdb4ab67 65 */
Jonathan Austin 1:8aa5cdb4ab67 66 int MicroBitRadioDatagram::recv(uint8_t *buf, int len)
Jonathan Austin 1:8aa5cdb4ab67 67 {
Jonathan Austin 1:8aa5cdb4ab67 68 if (buf == NULL || rxQueue == NULL || len < 0)
Jonathan Austin 1:8aa5cdb4ab67 69 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 70
Jonathan Austin 1:8aa5cdb4ab67 71 // Take the first buffer from the queue.
Jonathan Austin 1:8aa5cdb4ab67 72 FrameBuffer *p = rxQueue;
Jonathan Austin 1:8aa5cdb4ab67 73 rxQueue = rxQueue->next;
Jonathan Austin 1:8aa5cdb4ab67 74
Jonathan Austin 1:8aa5cdb4ab67 75 int l = min(len, p->length - (MICROBIT_RADIO_HEADER_SIZE - 1));
Jonathan Austin 1:8aa5cdb4ab67 76
Jonathan Austin 1:8aa5cdb4ab67 77 // Fill in the buffer provided, if possible.
Jonathan Austin 1:8aa5cdb4ab67 78 memcpy(buf, p->payload, l);
Jonathan Austin 1:8aa5cdb4ab67 79
Jonathan Austin 1:8aa5cdb4ab67 80 delete p;
Jonathan Austin 1:8aa5cdb4ab67 81 return l;
Jonathan Austin 1:8aa5cdb4ab67 82 }
Jonathan Austin 1:8aa5cdb4ab67 83
Jonathan Austin 1:8aa5cdb4ab67 84 /**
Jonathan Austin 1:8aa5cdb4ab67 85 * Retreives packet payload data into the given buffer.
Jonathan Austin 1:8aa5cdb4ab67 86 *
Jonathan Austin 1:8aa5cdb4ab67 87 * If a data packet is already available, then it will be returned immediately to the caller
Jonathan Austin 1:8aa5cdb4ab67 88 * in the form of a PacketBuffer.
Jonathan Austin 1:8aa5cdb4ab67 89 *
Jonathan Austin 1:8aa5cdb4ab67 90 * @return the data received, or an empty PacketBuffer if no data is available.
Jonathan Austin 1:8aa5cdb4ab67 91 */
Jonathan Austin 1:8aa5cdb4ab67 92 PacketBuffer MicroBitRadioDatagram::recv()
Jonathan Austin 1:8aa5cdb4ab67 93 {
Jonathan Austin 1:8aa5cdb4ab67 94 if (rxQueue == NULL)
Jonathan Austin 1:8aa5cdb4ab67 95 return PacketBuffer::EmptyPacket;
Jonathan Austin 1:8aa5cdb4ab67 96
Jonathan Austin 1:8aa5cdb4ab67 97 FrameBuffer *p = rxQueue;
Jonathan Austin 1:8aa5cdb4ab67 98 rxQueue = rxQueue->next;
Jonathan Austin 1:8aa5cdb4ab67 99
Jonathan Austin 1:8aa5cdb4ab67 100 PacketBuffer packet(p->payload, p->length - (MICROBIT_RADIO_HEADER_SIZE - 1), p->rssi);
Jonathan Austin 1:8aa5cdb4ab67 101
Jonathan Austin 1:8aa5cdb4ab67 102 delete p;
Jonathan Austin 1:8aa5cdb4ab67 103 return packet;
Jonathan Austin 1:8aa5cdb4ab67 104 }
Jonathan Austin 1:8aa5cdb4ab67 105
Jonathan Austin 1:8aa5cdb4ab67 106 /**
Jonathan Austin 1:8aa5cdb4ab67 107 * Transmits the given buffer onto the broadcast radio.
Jonathan Austin 1:8aa5cdb4ab67 108 *
Jonathan Austin 1:8aa5cdb4ab67 109 * This is a synchronous call that will wait until the transmission of the packet
Jonathan Austin 1:8aa5cdb4ab67 110 * has completed before returning.
Jonathan Austin 1:8aa5cdb4ab67 111 *
Jonathan Austin 1:8aa5cdb4ab67 112 * @param buffer The packet contents to transmit.
Jonathan Austin 1:8aa5cdb4ab67 113 *
Jonathan Austin 1:8aa5cdb4ab67 114 * @param len The number of bytes to transmit.
Jonathan Austin 1:8aa5cdb4ab67 115 *
Jonathan Austin 1:8aa5cdb4ab67 116 * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the buffer is invalid,
Jonathan Austin 1:8aa5cdb4ab67 117 * or the number of bytes to transmit is greater than `MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE`.
Jonathan Austin 1:8aa5cdb4ab67 118 */
Jonathan Austin 1:8aa5cdb4ab67 119 int MicroBitRadioDatagram::send(uint8_t *buffer, int len)
Jonathan Austin 1:8aa5cdb4ab67 120 {
Jonathan Austin 1:8aa5cdb4ab67 121 if (buffer == NULL || len < 0 || len > MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE - 1)
Jonathan Austin 1:8aa5cdb4ab67 122 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 123
Jonathan Austin 1:8aa5cdb4ab67 124 FrameBuffer buf;
Jonathan Austin 1:8aa5cdb4ab67 125
Jonathan Austin 1:8aa5cdb4ab67 126 buf.length = len + MICROBIT_RADIO_HEADER_SIZE - 1;
Jonathan Austin 1:8aa5cdb4ab67 127 buf.version = 1;
Jonathan Austin 1:8aa5cdb4ab67 128 buf.group = 0;
Jonathan Austin 1:8aa5cdb4ab67 129 buf.protocol = MICROBIT_RADIO_PROTOCOL_DATAGRAM;
Jonathan Austin 1:8aa5cdb4ab67 130 memcpy(buf.payload, buffer, len);
Jonathan Austin 1:8aa5cdb4ab67 131
Jonathan Austin 1:8aa5cdb4ab67 132 return radio.send(&buf);
Jonathan Austin 1:8aa5cdb4ab67 133 }
Jonathan Austin 1:8aa5cdb4ab67 134
Jonathan Austin 1:8aa5cdb4ab67 135 /**
Jonathan Austin 1:8aa5cdb4ab67 136 * Transmits the given string onto the broadcast radio.
Jonathan Austin 1:8aa5cdb4ab67 137 *
Jonathan Austin 1:8aa5cdb4ab67 138 * This is a synchronous call that will wait until the transmission of the packet
Jonathan Austin 1:8aa5cdb4ab67 139 * has completed before returning.
Jonathan Austin 1:8aa5cdb4ab67 140 *
Jonathan Austin 1:8aa5cdb4ab67 141 * @param data The packet contents to transmit.
Jonathan Austin 1:8aa5cdb4ab67 142 *
Jonathan Austin 1:8aa5cdb4ab67 143 * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the buffer is invalid,
Jonathan Austin 1:8aa5cdb4ab67 144 * or the number of bytes to transmit is greater than `MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE`.
Jonathan Austin 1:8aa5cdb4ab67 145 */
Jonathan Austin 1:8aa5cdb4ab67 146 int MicroBitRadioDatagram::send(PacketBuffer data)
Jonathan Austin 1:8aa5cdb4ab67 147 {
Jonathan Austin 1:8aa5cdb4ab67 148 return send((uint8_t *)data.getBytes(), data.length());
Jonathan Austin 1:8aa5cdb4ab67 149 }
Jonathan Austin 1:8aa5cdb4ab67 150
Jonathan Austin 1:8aa5cdb4ab67 151 /**
Jonathan Austin 1:8aa5cdb4ab67 152 * Transmits the given string onto the broadcast radio.
Jonathan Austin 1:8aa5cdb4ab67 153 *
Jonathan Austin 1:8aa5cdb4ab67 154 * This is a synchronous call that will wait until the transmission of the packet
Jonathan Austin 1:8aa5cdb4ab67 155 * has completed before returning.
Jonathan Austin 1:8aa5cdb4ab67 156 *
Jonathan Austin 1:8aa5cdb4ab67 157 * @param data The packet contents to transmit.
Jonathan Austin 1:8aa5cdb4ab67 158 *
Jonathan Austin 1:8aa5cdb4ab67 159 * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the buffer is invalid,
Jonathan Austin 1:8aa5cdb4ab67 160 * or the number of bytes to transmit is greater than `MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE`.
Jonathan Austin 1:8aa5cdb4ab67 161 */
Jonathan Austin 1:8aa5cdb4ab67 162 int MicroBitRadioDatagram::send(ManagedString data)
Jonathan Austin 1:8aa5cdb4ab67 163 {
Jonathan Austin 1:8aa5cdb4ab67 164 return send((uint8_t *)data.toCharArray(), data.length());
Jonathan Austin 1:8aa5cdb4ab67 165 }
Jonathan Austin 1:8aa5cdb4ab67 166
Jonathan Austin 1:8aa5cdb4ab67 167 /**
Jonathan Austin 1:8aa5cdb4ab67 168 * Protocol handler callback. This is called when the radio receives a packet marked as a datagram.
Jonathan Austin 1:8aa5cdb4ab67 169 *
Jonathan Austin 1:8aa5cdb4ab67 170 * This function process this packet, and queues it for user reception.
Jonathan Austin 1:8aa5cdb4ab67 171 */
Jonathan Austin 1:8aa5cdb4ab67 172 void MicroBitRadioDatagram::packetReceived()
Jonathan Austin 1:8aa5cdb4ab67 173 {
Jonathan Austin 1:8aa5cdb4ab67 174 FrameBuffer *packet = radio.recv();
Jonathan Austin 1:8aa5cdb4ab67 175 int queueDepth = 0;
Jonathan Austin 1:8aa5cdb4ab67 176
Jonathan Austin 1:8aa5cdb4ab67 177 // We add to the tail of the queue to preserve causal ordering.
Jonathan Austin 1:8aa5cdb4ab67 178 packet->next = NULL;
Jonathan Austin 1:8aa5cdb4ab67 179
Jonathan Austin 1:8aa5cdb4ab67 180 if (rxQueue == NULL)
Jonathan Austin 1:8aa5cdb4ab67 181 {
Jonathan Austin 1:8aa5cdb4ab67 182 rxQueue = packet;
Jonathan Austin 1:8aa5cdb4ab67 183 }
Jonathan Austin 1:8aa5cdb4ab67 184 else
Jonathan Austin 1:8aa5cdb4ab67 185 {
Jonathan Austin 1:8aa5cdb4ab67 186 FrameBuffer *p = rxQueue;
Jonathan Austin 1:8aa5cdb4ab67 187 while (p->next != NULL)
Jonathan Austin 1:8aa5cdb4ab67 188 {
Jonathan Austin 1:8aa5cdb4ab67 189 p = p->next;
Jonathan Austin 1:8aa5cdb4ab67 190 queueDepth++;
Jonathan Austin 1:8aa5cdb4ab67 191 }
Jonathan Austin 1:8aa5cdb4ab67 192
Jonathan Austin 1:8aa5cdb4ab67 193 if (queueDepth >= MICROBIT_RADIO_MAXIMUM_RX_BUFFERS)
Jonathan Austin 1:8aa5cdb4ab67 194 {
Jonathan Austin 1:8aa5cdb4ab67 195 delete packet;
Jonathan Austin 1:8aa5cdb4ab67 196 return;
Jonathan Austin 1:8aa5cdb4ab67 197 }
Jonathan Austin 1:8aa5cdb4ab67 198
Jonathan Austin 1:8aa5cdb4ab67 199 p->next = packet;
Jonathan Austin 1:8aa5cdb4ab67 200 }
Jonathan Austin 1:8aa5cdb4ab67 201
Jonathan Austin 1:8aa5cdb4ab67 202 MicroBitEvent(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM);
Jonathan Austin 1:8aa5cdb4ab67 203 }