Solution for Bluetooth SIG hands-on training course
Dependencies: BLE_API mbed-dev-bin nRF51822-bluetooth-mdw
Fork of microbit-dal-bluetooth-mdw_starter by
source/drivers/MicroBitRadioEvent.cpp@22:23d7b9a4b082, 2016-07-13 (annotated)
- Committer:
- LancasterUniversity
- Date:
- Wed Jul 13 12:17:54 2016 +0100
- Revision:
- 22:23d7b9a4b082
- Parent:
- 1:8aa5cdb4ab67
Synchronized with git rev 7cf98c22
Author: James Devine
microbit-dal: patch for fiber_wake_on_event
fiber_wake_on_event used to crash after forking a FOB fiber.
It would attempt to obtain a new fiber context, and would place it on the wait queue.
Then when that fiber was paged in, the context of that fiber would not have been
initialised, as the function presumed schedule would be called immediately after
fiber initialisation.
This patch catches that edge case.
Who changed what in which revision?
User | Revision | Line number | New 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 extend the micro:bit's default EventModel to other micro:bits in the vicinity, |
Jonathan Austin |
1:8aa5cdb4ab67 | 33 | * in a very similar way to the MicroBitEventService for BLE interfaces. |
Jonathan Austin |
1:8aa5cdb4ab67 | 34 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 35 | * It is envisaged that this would provide the basis for children to experiment with building their own, simple, |
Jonathan Austin |
1:8aa5cdb4ab67 | 36 | * custom asynchronous events and actions. |
Jonathan Austin |
1:8aa5cdb4ab67 | 37 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 38 | * @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 | 39 | * teaching aid to demonstrate how simple communications operates, and to provide a sandpit through which learning can take place. |
Jonathan Austin |
1:8aa5cdb4ab67 | 40 | * For serious applications, BLE should be considered a substantially more secure alternative. |
Jonathan Austin |
1:8aa5cdb4ab67 | 41 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 42 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 43 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 44 | * Constructor. |
Jonathan Austin |
1:8aa5cdb4ab67 | 45 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 46 | * Creates an instance of MicroBitRadioEvent which offers the ability to extend |
Jonathan Austin |
1:8aa5cdb4ab67 | 47 | * the micro:bit's default EventModel to other micro:bits in the vicinity. |
Jonathan Austin |
1:8aa5cdb4ab67 | 48 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 49 | * @param r The underlying radio module used to send and receive data. |
Jonathan Austin |
1:8aa5cdb4ab67 | 50 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 51 | MicroBitRadioEvent::MicroBitRadioEvent(MicroBitRadio &r) : radio(r) |
Jonathan Austin |
1:8aa5cdb4ab67 | 52 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 53 | this->suppressForwarding = false; |
Jonathan Austin |
1:8aa5cdb4ab67 | 54 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 55 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 56 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 57 | * Associates the given event with the radio channel. |
Jonathan Austin |
1:8aa5cdb4ab67 | 58 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 59 | * Once registered, all events matching the given registration sent to this micro:bit's |
Jonathan Austin |
1:8aa5cdb4ab67 | 60 | * default EventModel will be automatically retransmitted on the radio. |
Jonathan Austin |
1:8aa5cdb4ab67 | 61 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 62 | * @param id The id of the event to register. |
Jonathan Austin |
1:8aa5cdb4ab67 | 63 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 64 | * @param value the value of the event to register. |
Jonathan Austin |
1:8aa5cdb4ab67 | 65 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 66 | * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if no default EventModel is available. |
Jonathan Austin |
1:8aa5cdb4ab67 | 67 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 68 | * @note The wildcards MICROBIT_ID_ANY and MICROBIT_EVT_ANY can also be in place of the |
Jonathan Austin |
1:8aa5cdb4ab67 | 69 | * id and value fields. |
Jonathan Austin |
1:8aa5cdb4ab67 | 70 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 71 | int MicroBitRadioEvent::listen(uint16_t id, uint16_t value) |
Jonathan Austin |
1:8aa5cdb4ab67 | 72 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 73 | if (EventModel::defaultEventBus) |
Jonathan Austin |
1:8aa5cdb4ab67 | 74 | return listen(id, value, *EventModel::defaultEventBus); |
Jonathan Austin |
1:8aa5cdb4ab67 | 75 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 76 | return MICROBIT_NO_RESOURCES; |
Jonathan Austin |
1:8aa5cdb4ab67 | 77 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 78 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 79 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 80 | * Associates the given event with the radio channel. |
Jonathan Austin |
1:8aa5cdb4ab67 | 81 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 82 | * Once registered, all events matching the given registration sent to the given |
Jonathan Austin |
1:8aa5cdb4ab67 | 83 | * EventModel will be automatically retransmitted on the radio. |
Jonathan Austin |
1:8aa5cdb4ab67 | 84 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 85 | * @param id The id of the events to register. |
Jonathan Austin |
1:8aa5cdb4ab67 | 86 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 87 | * @param value the value of the event to register. |
Jonathan Austin |
1:8aa5cdb4ab67 | 88 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 89 | * @param eventBus The EventModel to listen for events on. |
Jonathan Austin |
1:8aa5cdb4ab67 | 90 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 91 | * @return MICROBIT_OK on success. |
Jonathan Austin |
1:8aa5cdb4ab67 | 92 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 93 | * @note The wildcards MICROBIT_ID_ANY and MICROBIT_EVT_ANY can also be in place of the |
Jonathan Austin |
1:8aa5cdb4ab67 | 94 | * id and value fields. |
Jonathan Austin |
1:8aa5cdb4ab67 | 95 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 96 | int MicroBitRadioEvent::listen(uint16_t id, uint16_t value, EventModel &eventBus) |
Jonathan Austin |
1:8aa5cdb4ab67 | 97 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 98 | return eventBus.listen(id, value, this, &MicroBitRadioEvent::eventReceived, MESSAGE_BUS_LISTENER_IMMEDIATE); |
Jonathan Austin |
1:8aa5cdb4ab67 | 99 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 100 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 101 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 102 | * Disassociates the given event with the radio channel. |
Jonathan Austin |
1:8aa5cdb4ab67 | 103 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 104 | * @param id The id of the events to deregister. |
Jonathan Austin |
1:8aa5cdb4ab67 | 105 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 106 | * @param value The value of the event to deregister. |
Jonathan Austin |
1:8aa5cdb4ab67 | 107 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 108 | * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the default message bus does not exist. |
Jonathan Austin |
1:8aa5cdb4ab67 | 109 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 110 | * @note MICROBIT_EVT_ANY can be used to deregister all event values matching the given id. |
Jonathan Austin |
1:8aa5cdb4ab67 | 111 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 112 | int MicroBitRadioEvent::ignore(uint16_t id, uint16_t value) |
Jonathan Austin |
1:8aa5cdb4ab67 | 113 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 114 | if (EventModel::defaultEventBus) |
Jonathan Austin |
1:8aa5cdb4ab67 | 115 | return ignore(id, value, *EventModel::defaultEventBus); |
Jonathan Austin |
1:8aa5cdb4ab67 | 116 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 117 | return MICROBIT_INVALID_PARAMETER; |
Jonathan Austin |
1:8aa5cdb4ab67 | 118 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 119 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 120 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 121 | * Disassociates the given events with the radio channel. |
Jonathan Austin |
1:8aa5cdb4ab67 | 122 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 123 | * @param id The id of the events to deregister. |
Jonathan Austin |
1:8aa5cdb4ab67 | 124 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 125 | * @param value The value of the event to deregister. |
Jonathan Austin |
1:8aa5cdb4ab67 | 126 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 127 | * @param eventBus The EventModel to deregister on. |
Jonathan Austin |
1:8aa5cdb4ab67 | 128 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 129 | * @return MICROBIT_OK on success. |
Jonathan Austin |
1:8aa5cdb4ab67 | 130 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 131 | * @note MICROBIT_EVT_ANY can be used to deregister all event values matching the given id. |
Jonathan Austin |
1:8aa5cdb4ab67 | 132 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 133 | int MicroBitRadioEvent::ignore(uint16_t id, uint16_t value, EventModel &eventBus) |
Jonathan Austin |
1:8aa5cdb4ab67 | 134 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 135 | return eventBus.ignore(id, value, this, &MicroBitRadioEvent::eventReceived); |
Jonathan Austin |
1:8aa5cdb4ab67 | 136 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 137 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 138 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 139 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 140 | * Protocol handler callback. This is called when the radio receives a packet marked as using the event protocol. |
Jonathan Austin |
1:8aa5cdb4ab67 | 141 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 142 | * This function process this packet, and fires the event contained inside onto the default EventModel. |
Jonathan Austin |
1:8aa5cdb4ab67 | 143 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 144 | void MicroBitRadioEvent::packetReceived() |
Jonathan Austin |
1:8aa5cdb4ab67 | 145 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 146 | FrameBuffer *p = radio.recv(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 147 | MicroBitEvent *e = (MicroBitEvent *) p->payload; |
Jonathan Austin |
1:8aa5cdb4ab67 | 148 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 149 | suppressForwarding = true; |
Jonathan Austin |
1:8aa5cdb4ab67 | 150 | e->fire(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 151 | suppressForwarding = false; |
Jonathan Austin |
1:8aa5cdb4ab67 | 152 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 153 | delete p; |
Jonathan Austin |
1:8aa5cdb4ab67 | 154 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 155 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 156 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 157 | * Event handler callback. This is called whenever an event is received matching one of those registered through |
Jonathan Austin |
1:8aa5cdb4ab67 | 158 | * the registerEvent() method described above. Upon receiving such an event, it is wrapped into |
Jonathan Austin |
1:8aa5cdb4ab67 | 159 | * a radio packet and transmitted to any other micro:bits in the same group. |
Jonathan Austin |
1:8aa5cdb4ab67 | 160 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 161 | void MicroBitRadioEvent::eventReceived(MicroBitEvent e) |
Jonathan Austin |
1:8aa5cdb4ab67 | 162 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 163 | if(suppressForwarding) |
Jonathan Austin |
1:8aa5cdb4ab67 | 164 | return; |
Jonathan Austin |
1:8aa5cdb4ab67 | 165 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 166 | FrameBuffer buf; |
Jonathan Austin |
1:8aa5cdb4ab67 | 167 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 168 | buf.length = sizeof(MicroBitEvent) + MICROBIT_RADIO_HEADER_SIZE - 1; |
Jonathan Austin |
1:8aa5cdb4ab67 | 169 | buf.version = 1; |
Jonathan Austin |
1:8aa5cdb4ab67 | 170 | buf.group = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 171 | buf.protocol = MICROBIT_RADIO_PROTOCOL_EVENTBUS; |
Jonathan Austin |
1:8aa5cdb4ab67 | 172 | memcpy(buf.payload, (const uint8_t *)&e, sizeof(MicroBitEvent)); |
Jonathan Austin |
1:8aa5cdb4ab67 | 173 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 174 | radio.send(&buf); |
Jonathan Austin |
1:8aa5cdb4ab67 | 175 | } |