Junichi Katsu / Mbed 2 deprecated WallbotR4_BTLE

Dependencies:   FatFileSystem HighSpeedAnalogIn TB6612FNG2 mbed

Committer:
jksoft
Date:
Fri May 10 11:48:07 2013 +0000
Revision:
0:373bcb197dc8
?????????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jksoft 0:373bcb197dc8 1 /*
jksoft 0:373bcb197dc8 2 * Copyright (C) 2011-2012 by Matthias Ringwald
jksoft 0:373bcb197dc8 3 *
jksoft 0:373bcb197dc8 4 * Redistribution and use in source and binary forms, with or without
jksoft 0:373bcb197dc8 5 * modification, are permitted provided that the following conditions
jksoft 0:373bcb197dc8 6 * are met:
jksoft 0:373bcb197dc8 7 *
jksoft 0:373bcb197dc8 8 * 1. Redistributions of source code must retain the above copyright
jksoft 0:373bcb197dc8 9 * notice, this list of conditions and the following disclaimer.
jksoft 0:373bcb197dc8 10 * 2. Redistributions in binary form must reproduce the above copyright
jksoft 0:373bcb197dc8 11 * notice, this list of conditions and the following disclaimer in the
jksoft 0:373bcb197dc8 12 * documentation and/or other materials provided with the distribution.
jksoft 0:373bcb197dc8 13 * 3. Neither the name of the copyright holders nor the names of
jksoft 0:373bcb197dc8 14 * contributors may be used to endorse or promote products derived
jksoft 0:373bcb197dc8 15 * from this software without specific prior written permission.
jksoft 0:373bcb197dc8 16 * 4. Any redistribution, use, or modification is done solely for
jksoft 0:373bcb197dc8 17 * personal benefit and not for any commercial purpose or for
jksoft 0:373bcb197dc8 18 * monetary gain.
jksoft 0:373bcb197dc8 19 *
jksoft 0:373bcb197dc8 20 * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
jksoft 0:373bcb197dc8 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
jksoft 0:373bcb197dc8 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
jksoft 0:373bcb197dc8 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
jksoft 0:373bcb197dc8 24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
jksoft 0:373bcb197dc8 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
jksoft 0:373bcb197dc8 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
jksoft 0:373bcb197dc8 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
jksoft 0:373bcb197dc8 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
jksoft 0:373bcb197dc8 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
jksoft 0:373bcb197dc8 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
jksoft 0:373bcb197dc8 31 * SUCH DAMAGE.
jksoft 0:373bcb197dc8 32 *
jksoft 0:373bcb197dc8 33 * Please inquire about commercial licensing options at btstack@ringwald.ch
jksoft 0:373bcb197dc8 34 *
jksoft 0:373bcb197dc8 35 */
jksoft 0:373bcb197dc8 36
jksoft 0:373bcb197dc8 37 /*
jksoft 0:373bcb197dc8 38 * l2cap_le.c
jksoft 0:373bcb197dc8 39 *
jksoft 0:373bcb197dc8 40 * Logical Link Control and Adaption Protocol (L2CAP) for Bluetooth Low Energy
jksoft 0:373bcb197dc8 41 *
jksoft 0:373bcb197dc8 42 * Created by Matthias Ringwald on 5/16/09.
jksoft 0:373bcb197dc8 43 */
jksoft 0:373bcb197dc8 44
jksoft 0:373bcb197dc8 45 #include "l2cap.h"
jksoft 0:373bcb197dc8 46 #include "hci.h"
jksoft 0:373bcb197dc8 47 #include "hci_dump.h"
jksoft 0:373bcb197dc8 48 #include "debug.h"
jksoft 0:373bcb197dc8 49 #include "btstack_memory.h"
jksoft 0:373bcb197dc8 50
jksoft 0:373bcb197dc8 51 #include <stdarg.h>
jksoft 0:373bcb197dc8 52 #include <string.h>
jksoft 0:373bcb197dc8 53
jksoft 0:373bcb197dc8 54 #include <stdio.h>
jksoft 0:373bcb197dc8 55
jksoft 0:373bcb197dc8 56 static void l2cap_packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size);
jksoft 0:373bcb197dc8 57
jksoft 0:373bcb197dc8 58 static void (*packet_handler) (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
jksoft 0:373bcb197dc8 59 static btstack_packet_handler_t attribute_protocol_packet_handler;
jksoft 0:373bcb197dc8 60 static btstack_packet_handler_t security_protocol_packet_handler;
jksoft 0:373bcb197dc8 61
jksoft 0:373bcb197dc8 62 void l2cap_init(){
jksoft 0:373bcb197dc8 63
jksoft 0:373bcb197dc8 64 packet_handler = NULL;
jksoft 0:373bcb197dc8 65 attribute_protocol_packet_handler = NULL;
jksoft 0:373bcb197dc8 66 security_protocol_packet_handler = NULL;
jksoft 0:373bcb197dc8 67
jksoft 0:373bcb197dc8 68 //
jksoft 0:373bcb197dc8 69 // register callback with HCI
jksoft 0:373bcb197dc8 70 //
jksoft 0:373bcb197dc8 71 hci_register_packet_handler(&l2cap_packet_handler);
jksoft 0:373bcb197dc8 72 hci_connectable_control(0); // no services yet
jksoft 0:373bcb197dc8 73 }
jksoft 0:373bcb197dc8 74
jksoft 0:373bcb197dc8 75
jksoft 0:373bcb197dc8 76 /** Register L2CAP packet handlers */
jksoft 0:373bcb197dc8 77 void l2cap_register_packet_handler(void (*handler)(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)){
jksoft 0:373bcb197dc8 78 packet_handler = handler;
jksoft 0:373bcb197dc8 79 }
jksoft 0:373bcb197dc8 80
jksoft 0:373bcb197dc8 81 uint8_t *l2cap_get_outgoing_buffer(void){
jksoft 0:373bcb197dc8 82 return hci_get_outgoing_acl_packet_buffer() + COMPLETE_L2CAP_HEADER; // 8 bytes
jksoft 0:373bcb197dc8 83 }
jksoft 0:373bcb197dc8 84
jksoft 0:373bcb197dc8 85 int l2cap_send_prepared_connectionless(uint16_t handle, uint16_t cid, uint16_t len){
jksoft 0:373bcb197dc8 86
jksoft 0:373bcb197dc8 87 if (!hci_can_send_packet_now(HCI_ACL_DATA_PACKET)){
jksoft 0:373bcb197dc8 88 log_info("l2cap_send_prepared_to_handle cid %u, cannot send\n", cid);
jksoft 0:373bcb197dc8 89 return BTSTACK_ACL_BUFFERS_FULL;
jksoft 0:373bcb197dc8 90 }
jksoft 0:373bcb197dc8 91
jksoft 0:373bcb197dc8 92 log_debug("l2cap_send_prepared_to_handle cid %u, handle %u\n", cid, handle);
jksoft 0:373bcb197dc8 93
jksoft 0:373bcb197dc8 94 uint8_t *acl_buffer = hci_get_outgoing_acl_packet_buffer();
jksoft 0:373bcb197dc8 95
jksoft 0:373bcb197dc8 96 // 0 - Connection handle : PB=10 : BC=00
jksoft 0:373bcb197dc8 97 bt_store_16(acl_buffer, 0, handle | (2 << 12) | (0 << 14));
jksoft 0:373bcb197dc8 98 // 2 - ACL length
jksoft 0:373bcb197dc8 99 bt_store_16(acl_buffer, 2, len + 4);
jksoft 0:373bcb197dc8 100 // 4 - L2CAP packet length
jksoft 0:373bcb197dc8 101 bt_store_16(acl_buffer, 4, len + 0);
jksoft 0:373bcb197dc8 102 // 6 - L2CAP channel DEST
jksoft 0:373bcb197dc8 103 bt_store_16(acl_buffer, 6, cid);
jksoft 0:373bcb197dc8 104 // send
jksoft 0:373bcb197dc8 105 int err = hci_send_acl_packet(acl_buffer, len+8);
jksoft 0:373bcb197dc8 106
jksoft 0:373bcb197dc8 107 return err;
jksoft 0:373bcb197dc8 108 }
jksoft 0:373bcb197dc8 109
jksoft 0:373bcb197dc8 110 int l2cap_send_connectionless(uint16_t handle, uint16_t cid, uint8_t *data, uint16_t len){
jksoft 0:373bcb197dc8 111
jksoft 0:373bcb197dc8 112 if (!hci_can_send_packet_now(HCI_ACL_DATA_PACKET)){
jksoft 0:373bcb197dc8 113 log_info("l2cap_send_internal cid %u, cannot send\n", cid);
jksoft 0:373bcb197dc8 114 return BTSTACK_ACL_BUFFERS_FULL;
jksoft 0:373bcb197dc8 115 }
jksoft 0:373bcb197dc8 116
jksoft 0:373bcb197dc8 117 uint8_t *acl_buffer = hci_get_outgoing_acl_packet_buffer();
jksoft 0:373bcb197dc8 118
jksoft 0:373bcb197dc8 119 memcpy(&acl_buffer[8], data, len);
jksoft 0:373bcb197dc8 120
jksoft 0:373bcb197dc8 121 return l2cap_send_prepared_connectionless(handle, cid, len);
jksoft 0:373bcb197dc8 122 }
jksoft 0:373bcb197dc8 123
jksoft 0:373bcb197dc8 124 void l2cap_event_handler( uint8_t *packet, uint16_t size ){
jksoft 0:373bcb197dc8 125
jksoft 0:373bcb197dc8 126 switch(packet[0]){
jksoft 0:373bcb197dc8 127
jksoft 0:373bcb197dc8 128 case DAEMON_EVENT_HCI_PACKET_SENT:
jksoft 0:373bcb197dc8 129 if (attribute_protocol_packet_handler) {
jksoft 0:373bcb197dc8 130 (*attribute_protocol_packet_handler)(HCI_EVENT_PACKET, 0, packet, size);
jksoft 0:373bcb197dc8 131 }
jksoft 0:373bcb197dc8 132 if (security_protocol_packet_handler) {
jksoft 0:373bcb197dc8 133 (*security_protocol_packet_handler)(HCI_EVENT_PACKET, 0, packet, size);
jksoft 0:373bcb197dc8 134 }
jksoft 0:373bcb197dc8 135 break;
jksoft 0:373bcb197dc8 136
jksoft 0:373bcb197dc8 137 default:
jksoft 0:373bcb197dc8 138 break;
jksoft 0:373bcb197dc8 139 }
jksoft 0:373bcb197dc8 140
jksoft 0:373bcb197dc8 141 // pass on
jksoft 0:373bcb197dc8 142 if (packet_handler) {
jksoft 0:373bcb197dc8 143 (*packet_handler)(NULL, HCI_EVENT_PACKET, 0, packet, size);
jksoft 0:373bcb197dc8 144 }
jksoft 0:373bcb197dc8 145 }
jksoft 0:373bcb197dc8 146
jksoft 0:373bcb197dc8 147 void l2cap_acl_handler( uint8_t *packet, uint16_t size ){
jksoft 0:373bcb197dc8 148
jksoft 0:373bcb197dc8 149 // Get Channel ID
jksoft 0:373bcb197dc8 150 uint16_t channel_id = READ_L2CAP_CHANNEL_ID(packet);
jksoft 0:373bcb197dc8 151 hci_con_handle_t handle = READ_ACL_CONNECTION_HANDLE(packet);
jksoft 0:373bcb197dc8 152
jksoft 0:373bcb197dc8 153 switch (channel_id) {
jksoft 0:373bcb197dc8 154
jksoft 0:373bcb197dc8 155 case L2CAP_CID_ATTRIBUTE_PROTOCOL:
jksoft 0:373bcb197dc8 156 if (attribute_protocol_packet_handler) {
jksoft 0:373bcb197dc8 157 (*attribute_protocol_packet_handler)(ATT_DATA_PACKET, handle, &packet[COMPLETE_L2CAP_HEADER], size-COMPLETE_L2CAP_HEADER);
jksoft 0:373bcb197dc8 158 }
jksoft 0:373bcb197dc8 159 break;
jksoft 0:373bcb197dc8 160
jksoft 0:373bcb197dc8 161 case L2CAP_CID_SECURITY_MANAGER_PROTOCOL:
jksoft 0:373bcb197dc8 162 if (security_protocol_packet_handler) {
jksoft 0:373bcb197dc8 163 (*security_protocol_packet_handler)(SM_DATA_PACKET, handle, &packet[COMPLETE_L2CAP_HEADER], size-COMPLETE_L2CAP_HEADER);
jksoft 0:373bcb197dc8 164 }
jksoft 0:373bcb197dc8 165 break;
jksoft 0:373bcb197dc8 166
jksoft 0:373bcb197dc8 167 default: {
jksoft 0:373bcb197dc8 168 break;
jksoft 0:373bcb197dc8 169 }
jksoft 0:373bcb197dc8 170 }
jksoft 0:373bcb197dc8 171 }
jksoft 0:373bcb197dc8 172
jksoft 0:373bcb197dc8 173 static void l2cap_packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){
jksoft 0:373bcb197dc8 174 switch (packet_type) {
jksoft 0:373bcb197dc8 175 case HCI_EVENT_PACKET:
jksoft 0:373bcb197dc8 176 l2cap_event_handler(packet, size);
jksoft 0:373bcb197dc8 177 break;
jksoft 0:373bcb197dc8 178 case HCI_ACL_DATA_PACKET:
jksoft 0:373bcb197dc8 179 l2cap_acl_handler(packet, size);
jksoft 0:373bcb197dc8 180 break;
jksoft 0:373bcb197dc8 181 default:
jksoft 0:373bcb197dc8 182 break;
jksoft 0:373bcb197dc8 183 }
jksoft 0:373bcb197dc8 184 }
jksoft 0:373bcb197dc8 185
jksoft 0:373bcb197dc8 186
jksoft 0:373bcb197dc8 187 // Bluetooth 4.0 - allow to register handler for Attribute Protocol and Security Manager Protocol
jksoft 0:373bcb197dc8 188 void l2cap_register_fixed_channel(btstack_packet_handler_t packet_handler, uint16_t channel_id) {
jksoft 0:373bcb197dc8 189 switch(channel_id){
jksoft 0:373bcb197dc8 190 case L2CAP_CID_ATTRIBUTE_PROTOCOL:
jksoft 0:373bcb197dc8 191 attribute_protocol_packet_handler = packet_handler;
jksoft 0:373bcb197dc8 192 break;
jksoft 0:373bcb197dc8 193 case L2CAP_CID_SECURITY_MANAGER_PROTOCOL:
jksoft 0:373bcb197dc8 194 security_protocol_packet_handler = packet_handler;
jksoft 0:373bcb197dc8 195 break;
jksoft 0:373bcb197dc8 196 }
jksoft 0:373bcb197dc8 197
jksoft 0:373bcb197dc8 198 if (attribute_protocol_packet_handler || security_protocol_packet_handler){
jksoft 0:373bcb197dc8 199 hci_connectable_control(1); // new service
jksoft 0:373bcb197dc8 200 } else {
jksoft 0:373bcb197dc8 201 hci_connectable_control(0); // no services anymore
jksoft 0:373bcb197dc8 202 }
jksoft 0:373bcb197dc8 203 }