Exemple #1
0
static int daemon_client_handler(connection_t *connection, uint16_t packet_type, uint16_t channel, uint8_t *data, uint16_t length){
    
    int err = 0;
    client_state_t * client;
    
    switch (packet_type){
        case HCI_COMMAND_DATA_PACKET:
            if (READ_CMD_OGF(data) != OGF_BTSTACK) { 
                // HCI Command
                hci_send_cmd_packet(data, length);
            } else {
                // BTstack command
                btstack_command_handler(connection, data, length);
            }
            break;
        case HCI_ACL_DATA_PACKET:
            err = hci_send_acl_packet(data, length);
            break;
        case L2CAP_DATA_PACKET:
            // process l2cap packet...
            err = l2cap_send_internal(channel, data, length);
            if (err == BTSTACK_ACL_BUFFERS_FULL) {
                l2cap_block_new_credits(1);
            }
            break;
        case RFCOMM_DATA_PACKET:
            // process l2cap packet...
            err = rfcomm_send_internal(channel, data, length);
            break;
        case DAEMON_EVENT_PACKET:
            switch (data[0]) {
                case DAEMON_EVENT_CONNECTION_OPENED:
                    log_info("DAEMON_EVENT_CONNECTION_OPENED %p\n",connection);

                    client = malloc(sizeof(client_state_t));
                    if (!client) break; // fail
                    client->connection   = connection;
                    client->power_mode   = HCI_POWER_OFF;
                    client->discoverable = 0;
                    linked_list_add(&clients, (linked_item_t *) client);
                    break;
                case DAEMON_EVENT_CONNECTION_CLOSED:
                    log_info("DAEMON_EVENT_CONNECTION_CLOSED %p\n",connection);
                    sdp_unregister_services_for_connection(connection);
                    rfcomm_close_connection(connection);
                    l2cap_close_connection(connection);
                    client = client_for_connection(connection);
                    if (!client) break;
                    linked_list_remove(&clients, (linked_item_t *) client);
                    free(client);
                    // update discoverable mode
                    hci_discoverable_control(clients_require_discoverable());
                    // start power off, if last active client
                    if (!clients_require_power_on()){
                        start_power_off_timer();
                    }
                    break;
                case DAEMON_NR_CONNECTIONS_CHANGED:
                    log_info("Nr Connections changed, new %u\n",data[1]);
                    break;
                default:
                    break;
            }
            break;
    }
    if (err) {
        log_info("Daemon Handler: err %d\n", err);
    }
    return err;
}
/*
parse the sdp record:
type   DES (6), element len 26
    type   DES (6), element len 24
        type  UINT (1), element len  3 , value: 0x00000004
        type   DES (6), element len 19
            type   DES (6), element len  5
                type  UUID (3), element len  3 , value: 0x00000100
            type   DES (6), element len  7
                type  UUID (3), element len  3 , value: 0x00000003
                type  UINT (1), element len  2 , value: 0x00000002
            type   DES (6), element len  5
                type  UUID (3), element len  3 , value: 0x00000008
*/
static void sdpc_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
{
  if (packet_type == HCI_EVENT_PACKET)
  {
    switch(packet[0]){
    case L2CAP_EVENT_CHANNEL_OPENED:
      {
        if (packet[2]) {
          log_info("Connection failed\n");
          return;
        }
        log_info("Connected\n");
        state = SENDING;
        current_server = 0;
        l2cap_cid = READ_BT_16(packet, 13);
        sdpc_trysend();
        break;
      }
    case DAEMON_EVENT_HCI_PACKET_SENT:
    case L2CAP_EVENT_CREDITS:
      {
        sdpc_trysend();
        break;
      }
    case L2CAP_EVENT_CHANNEL_CLOSED:
      if (channel == l2cap_cid){
        // reset
        l2cap_cid = 0;
      }
      break;
    }
  }

  if (packet_type == L2CAP_DATA_PACKET){
    log_info("SDP Respone %d \n", READ_NET_16(packet, 5));
    //de_dump_data_element(&packet[7]);

    //check if valid answer returns
    if (READ_NET_16(packet, 5) > 2)
    {
      switch(current_server)
      {
      case 0:
        {
        hfp_port = sdp_get_parameters_for_uuid(&packet[7], 0x0003);;
        log_info("hfp port: %d\n", hfp_port);
        break;
        }
      case 1:
        break;
      case 2:
        {
        mas_port = sdp_get_parameters_for_uuid(&packet[7], 0x0003);;
        log_info("MAP port: %d\n", mas_port );
        break;
        }
      }
    }

    current_server++;
    if (current_server == 3)
    {
      state = DONE;
      l2cap_close_connection(&current_server);
      if (hfp_port != 0)
        hfp_open(&addr, hfp_port);
//      if (mas_port != 0)
//        mas_open(&addr, mas_port);
    }
    else
    {
      state = SENDING;
      sdpc_trysend();
    }
  }
}