示例#1
0
文件: l2cap.c 项目: Simu3/RobotLog
int l2cap_send_prepared_connectionless(uint16_t handle, uint16_t cid, uint16_t len){
    
    if (!hci_can_send_packet_now(HCI_ACL_DATA_PACKET)){
        log_info("l2cap_send_prepared_to_handle cid %u, cannot send\n", cid);
        return BTSTACK_ACL_BUFFERS_FULL;
    }
    
    log_debug("l2cap_send_prepared_to_handle cid %u, handle %u\n", cid, handle);
    
    uint8_t *acl_buffer = hci_get_outgoing_acl_packet_buffer();
    
    // 0 - Connection handle : PB=10 : BC=00 
    bt_store_16(acl_buffer, 0, handle | (2 << 12) | (0 << 14));
    // 2 - ACL length
    bt_store_16(acl_buffer, 2,  len + 4);
    // 4 - L2CAP packet length
    bt_store_16(acl_buffer, 4,  len + 0);
    // 6 - L2CAP channel DEST
    bt_store_16(acl_buffer, 6, cid);    
    // send
    int err = hci_send_acl_packet(acl_buffer, len+8);
    
    l2cap_hand_out_credits();

    return err;
}
示例#2
0
文件: att.c 项目: Mechelix/btstack
//
// MARK: ATT_FIND_BY_TYPE_VALUE
//
// "Only attributes with attribute handles between and including the Starting Handle parameter
// and the Ending Handle parameter that match the requested attri- bute type and the attribute
// value that have sufficient permissions to allow reading will be returned" -> (1)
//
// TODO: handle other types then GATT_PRIMARY_SERVICE_UUID and GATT_SECONDARY_SERVICE_UUID
//
// NOTE: doesn't handle DYNAMIC values
// NOTE: only supports 16 bit UUIDs
// 
static uint16_t handle_find_by_type_value_request2(att_connection_t * att_connection, uint8_t * response_buffer, uint16_t response_buffer_size,
                                           uint16_t start_handle, uint16_t end_handle,
                                           uint16_t attribute_type, uint16_t attribute_len, uint8_t* attribute_value){
    
    log_info("ATT_FIND_BY_TYPE_VALUE_REQUEST: from %04X to %04X, type %04X, value: ", start_handle, end_handle, attribute_type);
    hexdump(attribute_value, attribute_len);
    uint8_t request_type = ATT_FIND_BY_TYPE_VALUE_REQUEST;

    if (start_handle > end_handle || start_handle == 0){
        return setup_error_invalid_handle(response_buffer, request_type, start_handle);
    }

    uint16_t offset      = 1;
    uint16_t in_group    = 0;
    uint16_t prev_handle = 0;
    
    att_iterator_t it;
    att_iterator_init(&it);
    while (att_iterator_has_next(&it)){
        att_iterator_fetch_next(&it);
        
        if (it.handle && it.handle < start_handle) continue;
        if (it.handle > end_handle) break;  // (1)
        
        // close current tag, if within a group and a new service definition starts or we reach end of att db
        if (in_group &&
            (it.handle == 0 || att_iterator_match_uuid16(&it, GATT_PRIMARY_SERVICE_UUID) || att_iterator_match_uuid16(&it, GATT_SECONDARY_SERVICE_UUID))){
            
            log_info("End of group, handle 0x%04x", prev_handle);
            bt_store_16(response_buffer, offset, prev_handle);
            offset += 2;
            in_group = 0;
            
            // check if space for another handle pair available
            if (offset + 4 > response_buffer_size){
                break;
            }
        }
        
        // keep track of previous handle
        prev_handle = it.handle;
        
        // does current attribute match
        if (it.handle && att_iterator_match_uuid16(&it, attribute_type) && attribute_len == it.value_len && memcmp(attribute_value, it.value, it.value_len) == 0){
            log_info("Begin of group, handle 0x%04x", it.handle);
            bt_store_16(response_buffer, offset, it.handle);
            offset += 2;
            in_group = 1;
        }
    }
    
    if (offset == 1){
        return setup_error_atribute_not_found(response_buffer, request_type, start_handle);
    }
    
    response_buffer[0] = ATT_FIND_BY_TYPE_VALUE_RESPONSE;
    return offset;
}
示例#3
0
文件: l2cap.c 项目: Simu3/RobotLog
void l2cap_emit_connection_request(l2cap_channel_t *channel) {
    uint8_t event[16];
    event[0] = L2CAP_EVENT_INCOMING_CONNECTION;
    event[1] = sizeof(event) - 2;
    bt_flip_addr(&event[2], channel->address);
    bt_store_16(event,  8, channel->handle);
    bt_store_16(event, 10, channel->psm);
    bt_store_16(event, 12, channel->local_cid);
    bt_store_16(event, 14, channel->remote_cid);
    hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
    l2cap_dispatch(channel, HCI_EVENT_PACKET, event, sizeof(event));
}
示例#4
0
static void att_emit_mtu_event(uint16_t handle, uint16_t mtu){

    if (!att_client_packet_handler) return;

    uint8_t event[6];
    int pos = 0;
    event[pos++] = ATT_MTU_EXCHANGE_COMPLETE;
    event[pos++] = sizeof(event) - 2;
    bt_store_16(event, pos, handle);
    pos += 2;
    bt_store_16(event, pos, mtu);
    pos += 2;
    (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
}
/**
 * send HCI packet to single connection
 */
void socket_connection_send_packet(connection_t *conn, uint16_t type, uint16_t channel, uint8_t *packet, uint16_t size){
    uint8_t header[sizeof(packet_header_t)];
    bt_store_16(header, 0, type);
    bt_store_16(header, 2, channel);
    bt_store_16(header, 4, size);
#ifdef HAVE_SO_NOSIGPIPE
    // BSD Variants like Darwin and iOS
    write(conn->ds.fd, header, 6);
    write(conn->ds.fd, packet, size);
#else
    // Linux
    send(conn->ds.fd, header,    6, MSG_NOSIGNAL);
    send(conn->ds.fd, packet, size, MSG_NOSIGNAL);
#endif
}
示例#6
0
static void att_handle_value_indication_notify_client(uint8_t status, uint16_t client_handle, uint16_t attribute_handle){
    
    if (!att_client_packet_handler) return;
    
    uint8_t event[7];
    int pos = 0;
    event[pos++] = ATT_HANDLE_VALUE_INDICATION_COMPLETE;
    event[pos++] = sizeof(event) - 2;
    event[pos++] = status;
    bt_store_16(event, pos, client_handle);
    pos += 2;
    bt_store_16(event, pos, attribute_handle);
    pos += 2;
    (*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
}
示例#7
0
文件: att.c 项目: Mechelix/btstack
static uint16_t setup_error(uint8_t * response_buffer, uint16_t request, uint16_t handle, uint8_t error_code){
    response_buffer[0] = ATT_ERROR_RESPONSE;
    response_buffer[1] = request;
    bt_store_16(response_buffer, 2, handle);
    response_buffer[4] = error_code;
    return 5;
}
示例#8
0
文件: att.c 项目: 13hoop/limo
//
// MARK: ATT_READ_BY_TYPE_REQUEST
//
static uint16_t handle_read_by_type_request2(uint8_t * response_buffer, uint16_t response_buffer_size,
                                      uint16_t start_handle, uint16_t end_handle,
                                      uint16_t attribute_type_len, uint8_t * attribute_type){
    
    printf("ATT_READ_BY_TYPE_REQUEST: from %04X to %04X, type: ", start_handle, end_handle); 
    hexdump2(attribute_type, attribute_type_len);
    
    uint16_t offset   = 1;
    uint16_t pair_len = 0;

    att_iterator_t it;
    att_iterator_init(&it);
    while (att_iterator_has_next(&it)){
        att_iterator_fetch_next(&it);
        
        if (!it.handle) break;
        if (it.handle < start_handle) continue;
        if (it.handle > end_handle) break;  // (1)

        // does current attribute match
        if (!att_iterator_match_uuid(&it, attribute_type, attribute_type_len)) continue;
        
        att_update_value_len(&it);
        
        // check if value has same len as last one
        uint16_t this_pair_len = 2 + it.value_len;
        if (offset > 1){
            if (pair_len != this_pair_len) {
                break;
            }
        }
        
        // first
        if (offset == 1) {
            pair_len = this_pair_len;
            response_buffer[offset] = pair_len;
            offset++;
        }
        
        // space?
        if (offset + pair_len > response_buffer_size) {
            if (offset > 2) break;
            it.value_len = response_buffer_size - 4;
        }
        
        // store
        bt_store_16(response_buffer, offset, it.handle);
        offset += 2;
        uint16_t bytes_copied = att_copy_value(&it, 0, response_buffer + offset, it.value_len);
        offset += bytes_copied;
    }
    
    if (offset == 1){
        return setup_error_atribute_not_found(response_buffer, ATT_READ_BY_TYPE_REQUEST, start_handle);
    }
    
    response_buffer[0] = ATT_READ_BY_TYPE_RESPONSE;
    return offset;
}
示例#9
0
文件: att.c 项目: 13hoop/limo
//
// MARK: ATT_FIND_INFORMATION_REQUEST
//
// TODO: handle other types then GATT_PRIMARY_SERVICE_UUID and GATT_SECONDARY_SERVICE_UUID
//
static uint16_t handle_find_information_request2(uint8_t * response_buffer, uint16_t response_buffer_size,
                                           uint16_t start_handle, uint16_t end_handle){
    
    printf("ATT_FIND_INFORMATION_REQUEST: from %04X to %04X\n", start_handle, end_handle);
    
    uint16_t offset   = 1;
    uint16_t pair_len = 0;
    
    att_iterator_t it;
    att_iterator_init(&it);
    while (att_iterator_has_next(&it)){
        att_iterator_fetch_next(&it);
        if (!it.handle) break;
        if (it.handle > end_handle) break;
        if (it.handle < start_handle) continue;
        
        att_update_value_len(&it);
        
        // printf("Handle 0x%04x\n", it.handle);
        
        // check if value has same len as last one
        uint16_t this_pair_len = 2 + it.value_len;
        if (offset > 1){
            if (pair_len != this_pair_len) {
                break;
            }
        }
        
        // first
        if (offset == 1) {
            pair_len = this_pair_len;
            if (it.value_len == 2) {
                response_buffer[offset] = 0x01; // format
            } else {
                response_buffer[offset] = 0x02;
            }
            offset++;
        }
        
        // space?
        if (offset + pair_len > response_buffer_size) {
            if (offset > 2) break;
            it.value_len = response_buffer_size - 4;
        }
        
        // store
        bt_store_16(response_buffer, offset, it.handle);
        offset += 2;
        uint16_t bytes_copied = att_copy_value(&it, 0, response_buffer + offset, it.value_len);
        offset += bytes_copied;
    }
    
    if (offset == 1){
        return setup_error_atribute_not_found(response_buffer, ATT_FIND_INFORMATION_REQUEST, start_handle);
    }
    
    response_buffer[0] = ATT_FIND_INFORMATION_REPLY;
    return offset;
}
示例#10
0
文件: hci.c 项目: ajsb85/ioio
void hci_emit_l2cap_check_timeout(hci_connection_t *conn){
    uint8_t event[4];
    event[0] = L2CAP_EVENT_TIMEOUT_CHECK;
    event[1] = sizeof(event) - 2;
    bt_store_16(event, 2, conn->con_handle);
    hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
    hci_stack.packet_handler(HCI_EVENT_PACKET, event, sizeof(event));
}
示例#11
0
文件: l2cap.c 项目: Simu3/RobotLog
void l2cap_emit_channel_closed(l2cap_channel_t *channel) {
    uint8_t event[4];
    event[0] = L2CAP_EVENT_CHANNEL_CLOSED;
    event[1] = sizeof(event) - 2;
    bt_store_16(event, 2, channel->local_cid);
    hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
    l2cap_dispatch(channel, HCI_EVENT_PACKET, event, sizeof(event));
}
示例#12
0
文件: att.c 项目: Mechelix/btstack
//
// MARK: ATT_FIND_INFORMATION_REQUEST
//
// TODO: handle other types then GATT_PRIMARY_SERVICE_UUID and GATT_SECONDARY_SERVICE_UUID
//
static uint16_t handle_find_information_request2(att_connection_t * att_connection, uint8_t * response_buffer, uint16_t response_buffer_size,
                                           uint16_t start_handle, uint16_t end_handle){
    
    log_info("ATT_FIND_INFORMATION_REQUEST: from %04X to %04X", start_handle, end_handle);
    uint8_t request_type = ATT_FIND_INFORMATION_REQUEST;
    
    if (start_handle > end_handle || start_handle == 0){
        return setup_error_invalid_handle(response_buffer, request_type, start_handle);
    }

    uint16_t offset   = 1;
    uint16_t uuid_len = 0;
    
    att_iterator_t it;
    att_iterator_init(&it);
    while (att_iterator_has_next(&it)){
        att_iterator_fetch_next(&it);
        if (!it.handle) break;
        if (it.handle > end_handle) break;
        if (it.handle < start_handle) continue;
                
        // log_info("Handle 0x%04x", it.handle);
        
        uint16_t this_uuid_len = (it.flags & ATT_PROPERTY_UUID128) ? 16 : 2;

        // check if value has same len as last one if not first result
        if (offset > 1){
            if (this_uuid_len != uuid_len) {
                break;
            }
        }

        // first
        if (offset == 1) {
            uuid_len = this_uuid_len;
            // set format field
            response_buffer[offset] = (it.flags & ATT_PROPERTY_UUID128) ? 0x02 : 0x01;
            offset++;
        } 
        
        // space?
        if (offset + 2 + uuid_len > response_buffer_size) break;
        
        // store
        bt_store_16(response_buffer, offset, it.handle);
        offset += 2;

        memcpy(response_buffer + offset, it.uuid, uuid_len);
        offset += uuid_len;
    }
    
    if (offset == 1){
        return setup_error_atribute_not_found(response_buffer, request_type, start_handle);
    }
    
    response_buffer[0] = ATT_FIND_INFORMATION_REPLY;
    return offset;
}
示例#13
0
uint16_t l2cap_create_signaling_internal(uint8_t * acl_buffer, hci_con_handle_t handle, uint16_t cid, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, va_list argptr){
    
    const char *format = l2cap_signaling_commands_format[cmd-1];
    uint16_t word;
    uint8_t * ptr;
    int pb = hci_non_flushable_packet_boundary_flag_supported() ? 0x00 : 0x02;

    // 0 - Connection handle : PB=pb : BC=00 
    bt_store_16(acl_buffer, 0, handle | (pb << 12) | (0 << 14));
    // 6 - L2CAP channel = 1
    bt_store_16(acl_buffer, 6, cid);
    // 8 - Code
    acl_buffer[8] = cmd;
    // 9 - id (!= 0 sequentially)
    acl_buffer[9] = identifier;
    
    // 12 - L2CAP signaling parameters
    uint16_t pos = 12;
    // skip AMP commands
    if (cmd >= CONNECTION_PARAMETER_UPDATE_REQUEST){
        cmd -= 6;
    }
    
    while (*format) {
        switch(*format) {
            case '1': //  8 bit value
            case '2': // 16 bit value
                word = va_arg(argptr, int);
                // minimal va_arg is int: 2 bytes on 8+16 bit CPUs
                acl_buffer[pos++] = word & 0xff;
                if (*format == '2') {
                    acl_buffer[pos++] = word >> 8;
                }
                break;
            case 'D': // variable data. passed: len, ptr
                word = va_arg(argptr, int);
                ptr  = va_arg(argptr, uint8_t *);
                memcpy(&acl_buffer[pos], ptr, word);
                pos += word;
                break;
            default:
                break;
        }
        format++;
    };
示例#14
0
文件: l2cap.c 项目: Simu3/RobotLog
static void l2cap_emit_service_registered(void *connection, uint8_t status, uint16_t psm){
    uint8_t event[5];
    event[0] = L2CAP_EVENT_SERVICE_REGISTERED;
    event[1] = sizeof(event) - 2;
    event[2] = status;
    bt_store_16(event, 3, psm);
    hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
    (*packet_handler)(connection, HCI_EVENT_PACKET, 0, event, sizeof(event));
}
示例#15
0
文件: hfp.c 项目: yourskp/btstack
static void hfp_emit_audio_connection_established_event(hfp_callback_t callback, uint8_t value, uint16_t sco_handle){
    if (!callback) return;
    uint8_t event[6];
    event[0] = HCI_EVENT_HFP_META;
    event[1] = sizeof(event) - 2;
    event[2] = HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED;
    event[3] = value; // status 0 == OK
    bt_store_16(event, 4, sco_handle);
    (*callback)(event, sizeof(event));
}
示例#16
0
static void emit_event_audio_connected(uint8_t status, uint16_t handle){
    if (!hsp_hs_callback) return;
    uint8_t event[6];
    event[0] = HCI_EVENT_HSP_META;
    event[1] = sizeof(event) - 2;
    event[2] = HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE;
    event[3] = status;
    bt_store_16(event, 4, handle);
    (*hsp_hs_callback)(event, sizeof(event));
}
示例#17
0
文件: hci.c 项目: ajsb85/ioio
void hci_emit_btstack_version() {
    uint8_t event[6];
    event[0] = BTSTACK_EVENT_VERSION;
    event[1] = sizeof(event) - 2;
    event[2] = BTSTACK_MAJOR;
    event[3] = BTSTACK_MINOR;
    bt_store_16(event, 4, BTSTACK_REVISION);
    hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
    hci_stack.packet_handler(HCI_EVENT_PACKET, event, sizeof(event));
}
示例#18
0
文件: hci.c 项目: ajsb85/ioio
void hci_emit_disconnection_complete(uint16_t handle, uint8_t reason){
    uint8_t event[6];
    event[0] = HCI_EVENT_DISCONNECTION_COMPLETE;
    event[1] = sizeof(event) - 2;
    event[2] = 0; // status = OK
    bt_store_16(event, 3, handle);
    event[5] = reason;
    hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
    hci_stack.packet_handler(HCI_EVENT_PACKET, event, sizeof(event));
}
示例#19
0
void send_ucd_packet(void){
    l2cap_reserve_packet_buffer();
    int ucd_size = 50;
    uint8_t * ucd_buffer = l2cap_get_outgoing_buffer();
    bt_store_16(ucd_buffer, 0, 0x2211);
    int i; 
    for (i=2; i< ucd_size ; i++){
        ucd_buffer[i] = i;
    }
    l2cap_send_prepared_connectionless(handle, L2CAP_CID_CONNECTIONLESS_CHANNEL, ucd_size);
}
示例#20
0
文件: hci.c 项目: ajsb85/ioio
void hci_emit_connection_complete(hci_connection_t *conn, uint8_t status){
    uint8_t event[13];
    event[0] = HCI_EVENT_CONNECTION_COMPLETE;
    event[1] = sizeof(event) - 2;
    event[2] = status;
    bt_store_16(event, 3, conn->con_handle);
    bt_flip_addr(&event[5], conn->address);
    event[11] = 1; // ACL connection
    event[12] = 0; // encryption disabled
    hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
    hci_stack.packet_handler(HCI_EVENT_PACKET, event, sizeof(event));
}
示例#21
0
文件: att.c 项目: Mechelix/btstack
// MARK: helper for ATT_HANDLE_VALUE_NOTIFICATION and ATT_HANDLE_VALUE_INDICATION
static uint16_t prepare_handle_value(att_connection_t * att_connection,
                                     uint16_t handle,
                                     uint8_t *value,
                                     uint16_t value_len, 
                                     uint8_t * response_buffer){
    bt_store_16(response_buffer, 1, handle);
    if (value_len > att_connection->mtu - 3){
        value_len = att_connection->mtu - 3;
    }
    memcpy(&response_buffer[3], value, value_len);
    return value_len + 3;
}
示例#22
0
文件: mock.c 项目: ChangeTsai/btstack
void mock_simulate_sm_data_packet(uint8_t * packet, uint16_t len) {

    uint16_t handle = 0x40;
    uint16_t cid = 0x06;

    uint8_t acl_buffer[len + 8];

    // 0 - Connection handle : PB=10 : BC=00
    bt_store_16(acl_buffer, 0, handle | (0 << 12) | (0 << 14));
    // 2 - ACL length
    bt_store_16(acl_buffer, 2,  len + 4);
    // 4 - L2CAP packet length
    bt_store_16(acl_buffer, 4,  len + 0);
    // 6 - L2CAP channel DEST
    bt_store_16(acl_buffer, 6, cid);

    memcpy(&acl_buffer[8], packet, len);
    hci_dump_packet(HCI_ACL_DATA_PACKET, 1, &acl_buffer[0], len + 8);

    le_data_handler(SM_DATA_PACKET, handle, packet, len);
}
示例#23
0
文件: att.c 项目: 13hoop/limo
//
// MARK: ATT_EXCHANGE_MTU_REQUEST
//
static uint16_t handle_exchange_mtu_request(att_connection_t * att_connection, uint8_t * request_buffer,  uint16_t request_len,
                                         uint8_t * response_buffer){

    uint16_t client_rx_mtu = READ_BT_16(request_buffer, 1);
    if (client_rx_mtu < att_connection->mtu){
        att_connection->mtu = client_rx_mtu;
    }
    
    response_buffer[0] = ATT_EXCHANGE_MTU_RESPONSE;
    bt_store_16(response_buffer, 1, att_connection->mtu);
    return 3;
}
示例#24
0
文件: l2cap.c 项目: Simu3/RobotLog
int l2cap_send_prepared(uint16_t local_cid, uint16_t len){
    
    if (!hci_can_send_packet_now(HCI_ACL_DATA_PACKET)){
        log_info("l2cap_send_internal cid %u, cannot send\n", local_cid);
        return BTSTACK_ACL_BUFFERS_FULL;
    }
    
    l2cap_channel_t * channel = l2cap_get_channel_for_local_cid(local_cid);
    if (!channel) {
        log_error("l2cap_send_internal no channel for cid %u\n", local_cid);
        return -1;   // TODO: define error
    }

    if (channel->packets_granted == 0){
        log_error("l2cap_send_internal cid %u, no credits!\n", local_cid);
        return -1;  // TODO: define error
    }
    
    --channel->packets_granted;

    log_debug("l2cap_send_internal cid %u, handle %u, 1 credit used, credits left %u;\n",
                  local_cid, channel->handle, channel->packets_granted);
    
    uint8_t *acl_buffer = hci_get_outgoing_acl_packet_buffer();

    // 0 - Connection handle : PB=10 : BC=00 
    bt_store_16(acl_buffer, 0, channel->handle | (2 << 12) | (0 << 14));
    // 2 - ACL length
    bt_store_16(acl_buffer, 2,  len + 4);
    // 4 - L2CAP packet length
    bt_store_16(acl_buffer, 4,  len + 0);
    // 6 - L2CAP channel DEST
    bt_store_16(acl_buffer, 6, channel->remote_cid);    
    // send
    int err = hci_send_acl_packet(acl_buffer, len+8);
    
    l2cap_hand_out_credits();
    
    return err;
}
示例#25
0
文件: mock.c 项目: ChangeTsai/btstack
int l2cap_send_connectionless(uint16_t handle, uint16_t cid, uint8_t * buffer, uint16_t len) {
    // printf("l2cap_send_connectionless\n");

    int pb = hci_non_flushable_packet_boundary_flag_supported() ? 0x00 : 0x02;

    // 0 - Connection handle : PB=pb : BC=00
    bt_store_16(packet_buffer, 0, handle | (pb << 12) | (0 << 14));
    // 2 - ACL length
    bt_store_16(packet_buffer, 2,  len + 4);
    // 4 - L2CAP packet length
    bt_store_16(packet_buffer, 4,  len + 0);
    // 6 - L2CAP channel DEST
    bt_store_16(packet_buffer, 6, cid);

    memcpy(&packet_buffer[8], buffer, len);
    hci_dump_packet(HCI_ACL_DATA_PACKET, 0, &packet_buffer[0], len + 8);

    dump_packet(HCI_ACL_DATA_PACKET, packet_buffer, len + 8);
    packet_buffer_len = len + 8;

    return 0;
}
示例#26
0
static void try_send_sco(void){
    if (!sco_handle) return;
    if (!hci_can_send_sco_packet_now(sco_handle)) {
        // printf("try_send_sco, cannot send now\n");
        return;
    }
    printf("try send handle %x\n", sco_handle);
    const int frames_per_packet = 24;
    hci_reserve_packet_buffer();
    uint8_t * sco_packet = hci_get_outgoing_packet_buffer();
    // set handle + flags
    bt_store_16(sco_packet, 0, sco_handle);
    // set len
    sco_packet[2] = frames_per_packet * 2;  // 16 bit PCM
    int i;
    for (i=0;i<frames_per_packet;i++){
        bt_store_16(sco_packet, 3 + 2*i, sine[phase]);
        phase++;
        if (phase >= TABLE_SIZE) phase = 0;
    }
    hci_send_sco_packet_buffer(3 + frames_per_packet * 2);
}
示例#27
0
文件: l2cap.c 项目: Simu3/RobotLog
void l2cap_emit_credits(l2cap_channel_t *channel, uint8_t credits) {
    // track credits
    channel->packets_granted += credits;
    // log_info("l2cap_emit_credits for cid %u, credits given: %u (+%u)\n", channel->local_cid, channel->packets_granted, credits);
    
    uint8_t event[5];
    event[0] = L2CAP_EVENT_CREDITS;
    event[1] = sizeof(event) - 2;
    bt_store_16(event, 2, channel->local_cid);
    event[4] = credits;
    hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
    l2cap_dispatch(channel, HCI_EVENT_PACKET, event, sizeof(event));
}
示例#28
0
uint16_t l2cap_create_signaling_internal(uint8_t * acl_buffer, hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, va_list argptr){
    
    // 0 - Connection handle : PB=10 : BC=00 
    bt_store_16(acl_buffer, 0, handle | (2 << 12) | (0 << 14));
    // 6 - L2CAP channel = 1
    bt_store_16(acl_buffer, 6, 1);
    // 8 - Code
    acl_buffer[8] = cmd;
    // 9 - id (!= 0 sequentially)
    acl_buffer[9] = identifier;
    
    // 12 - L2CAP signaling parameters
    uint16_t pos = 12;
    const char *format = l2cap_signaling_commands_format[cmd-1];
    uint16_t word;
    uint8_t * ptr;
    while (*format) {
        switch(*format) {
            case '1': //  8 bit value
            case '2': // 16 bit value
                word = va_arg(argptr, int);
                // minimal va_arg is int: 2 bytes on 8+16 bit CPUs
                acl_buffer[pos++] = word & 0xff;
                if (*format == '2') {
                    acl_buffer[pos++] = word >> 8;
                }
                break;
            case 'D': // variable data. passed: len, ptr
                word = va_arg(argptr, int);
                ptr  = va_arg(argptr, uint8_t *);
                memcpy(&acl_buffer[pos], ptr, word);
                pos += word;
                break;
            default:
                break;
        }
        format++;
    };
示例#29
0
文件: att.c 项目: Mechelix/btstack
//
// MARK: ATT_EXCHANGE_MTU_REQUEST
//
static uint16_t handle_exchange_mtu_request(att_connection_t * att_connection, uint8_t * request_buffer,  uint16_t request_len,
                                         uint8_t * response_buffer){

    uint16_t client_rx_mtu = READ_BT_16(request_buffer, 1);
    
    // find min(local max mtu, remote mtu) and use as mtu for this connection
    if (client_rx_mtu < att_connection->max_mtu){
        att_connection->mtu = client_rx_mtu;
    } else {
        att_connection->mtu = att_connection->max_mtu;
    }

    response_buffer[0] = ATT_EXCHANGE_MTU_RESPONSE;
    bt_store_16(response_buffer, 1, att_connection->mtu);
    return 3;
}
示例#30
0
文件: l2cap.c 项目: Simu3/RobotLog
void l2cap_emit_channel_opened(l2cap_channel_t *channel, uint8_t status) {
    uint8_t event[21];
    event[0] = L2CAP_EVENT_CHANNEL_OPENED;
    event[1] = sizeof(event) - 2;
    event[2] = status;
    bt_flip_addr(&event[3], channel->address);
    bt_store_16(event,  9, channel->handle);
    bt_store_16(event, 11, channel->psm);
    bt_store_16(event, 13, channel->local_cid);
    bt_store_16(event, 15, channel->remote_cid);
    bt_store_16(event, 17, channel->local_mtu);
    bt_store_16(event, 19, channel->remote_mtu); 
    hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
    l2cap_dispatch(channel, HCI_EVENT_PACKET, event, sizeof(event));
}