Example #1
0
static void hci_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
    if (packet_type != HCI_EVENT_PACKET) return;
    
    uint8_t event = hci_event_packet_get_type(packet);
    switch (event) {
        case BTSTACK_EVENT_STATE:
            // BTstack activated, get started
            if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break;
            if (cmdline_addr_found){
                printf("Connect to %s\n", bd_addr_to_str(cmdline_addr));
                state = TC_W4_CONNECT;
                gap_connect(cmdline_addr, 0);
                break;
            }
            printf("Start scanning!\n");
            state = TC_W4_SCAN_RESULT;
            gap_set_scan_parameters(0,0x0030, 0x0030);
            gap_start_scan();
            break;
        case GAP_EVENT_ADVERTISING_REPORT:
            if (state != TC_W4_SCAN_RESULT) return;
            fill_advertising_report_from_packet(&report, packet);
                
            if (blacklist_contains(report.address)) {
                break;
            }
            dump_advertising_report(&report);
            // stop scanning, and connect to the device
            state = TC_W4_CONNECT;
            gap_stop_scan();
            printf("Stop scan. Connect to device with addr %s.\n", bd_addr_to_str(report.address));
            gap_connect(report.address,report.address_type);
            
            break;
        case HCI_EVENT_LE_META:
            // wait for connection complete
            if (hci_event_le_meta_get_subevent_code(packet) !=  HCI_SUBEVENT_LE_CONNECTION_COMPLETE) break;
            if (state != TC_W4_CONNECT) return;
            connection_handle = hci_subevent_le_connection_complete_get_connection_handle(packet);
            // initialize gatt client context with handle, and add it to the list of active clients
            // query primary services
            printf("\nSearch for battery service.\n");
            state = TC_W4_SERVICE_RESULT;
            gatt_client_discover_primary_services_by_uuid16(handle_gatt_client_event, connection_handle, battery_service_uuid);
            break;
        case HCI_EVENT_DISCONNECTION_COMPLETE:
            
            if (cmdline_addr_found){
                printf("\nDisconnected %s\n", bd_addr_to_str(cmdline_addr));
                exit(0);
            }

            printf("\nDisconnected %s\n", bd_addr_to_str(report.address));
            printf("Restart scan.\n");
            state = TC_W4_SCAN_RESULT;
            gap_start_scan();
            break;
        default:
            break;
    }
}
Example #2
0
void
tcpip_ipv6_output(void)
{
  uip_ds6_nbr_t *nbr = NULL;
  uip_ipaddr_t *nexthop = NULL;
  rimeaddr_t *anycast_addr = NULL;

  if(uip_len == 0) {
    return;
  }

//  printf("Tcpip: tcpip_ipv6_output\n");

  if(uip_len > UIP_LINK_MTU) {
    UIP_LOG("tcpip_ipv6_output: Packet to big");
    uip_len = 0;
    return;
  }

  if(uip_is_addr_unspecified(&UIP_IP_BUF->destipaddr)){
    UIP_LOG("tcpip_ipv6_output: Destination address unspecified");
    uip_len = 0;
    return;
  }

  if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
    /* Next hop determination */
    nbr = NULL;
    if(uip_ds6_is_addr_onlink(&UIP_IP_BUF->destipaddr)){
      nexthop = &UIP_IP_BUF->destipaddr;
    } else {
//      uip_ds6_route_t* locrt;
//      locrt = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr);
//      if(locrt == NULL) {
//        if((nexthop = uip_ds6_defrt_choose()) == NULL) {
//#ifdef UIP_FALLBACK_INTERFACE
//          PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n",
//              uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40));
//          if(uip_ext_len > 0) {
//            uint8_t proto = *((uint8_t *)UIP_IP_BUF + 40);
//            remove_ext_hdr();
//            /* This should be copied from the ext header... */
//            UIP_IP_BUF->proto = proto;
//          }
//          UIP_FALLBACK_INTERFACE.output();
//#else
//          PRINTF("tcpip_ipv6_output: Destination off-link but no route\n");
//#endif /* !UIP_FALLBACK_INTERFACE */
//          uip_len = 0;
//          return;
//        }
//      } else {
//        nexthop = &locrt->nexthop;
//      }

      /* Set anycast MAC address instead of routing */
      struct app_data *dataptr = rpl_dataptr_from_uip();
      struct app_data data;
      app_data_init(&data, dataptr);
      if(is_reachable_neighbor(&UIP_IP_BUF->destipaddr)) {
        printf("Tcpip: fw to nbr");
        rpl_trace(dataptr);
        anycast_addr = &anycast_addr_nbr;
      } else if(is_in_subdodag(&UIP_IP_BUF->destipaddr) && !blacklist_contains(data.seqno)) {
        printf("Tcpip: fw down");
        rpl_trace(dataptr);
        anycast_addr = &anycast_addr_down;
      } else {
        printf("Tcpip: fw up");
        rpl_trace(dataptr);
        anycast_addr = &anycast_addr_up;
      }
#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
      if(nexthop != NULL) {
	printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
      }
#endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */
    }
    if(anycast_addr == &anycast_addr_up || anycast_addr == &anycast_addr_down || anycast_addr == &anycast_addr_nbr) {
      tcpip_output((uip_lladdr_t *)anycast_addr);
      uip_len = 0;
      return;
    }
    /* End of next hop determination */
#if UIP_CONF_IPV6_RPL
    if(rpl_update_header_final(nexthop)) {
      uip_len = 0;
      return;
    }
#endif /* UIP_CONF_IPV6_RPL */
    if((nbr = uip_ds6_nbr_lookup(nexthop)) == NULL) {
      if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) {
        uip_len = 0;
        return;
      } else {
#if UIP_CONF_IPV6_QUEUE_PKT
        /* Copy outgoing pkt in the queuing buffer for later transmit. */
        if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) {
          memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF, uip_len);
          uip_packetqueue_set_buflen(&nbr->packethandle, uip_len);
        }
#endif
      /* RFC4861, 7.2.2:
       * "If the source address of the packet prompting the solicitation is the
       * same as one of the addresses assigned to the outgoing interface, that
       * address SHOULD be placed in the IP Source Address of the outgoing
       * solicitation.  Otherwise, any one of the addresses assigned to the
       * interface should be used."*/
       if(uip_ds6_is_my_addr(&UIP_IP_BUF->srcipaddr)){
          uip_nd6_ns_output(&UIP_IP_BUF->srcipaddr, NULL, &nbr->ipaddr);
        } else {
          uip_nd6_ns_output(NULL, NULL, &nbr->ipaddr);
        }

//        stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
        nbr->nscount = 1;
      }
    } else {
//      if(nbr->state == NBR_INCOMPLETE) {
//        PRINTF("tcpip_ipv6_output: nbr cache entry incomplete\n");
//#if UIP_CONF_IPV6_QUEUE_PKT
//        /* Copy outgoing pkt in the queuing buffer for later transmit and set
//           the destination nbr to nbr. */
//        if(uip_packetqueue_alloc(&nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) {
//          memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF, uip_len);
//          uip_packetqueue_set_buflen(&nbr->packethandle, uip_len);
//        }
//#endif /*UIP_CONF_IPV6_QUEUE_PKT*/
//        uip_len = 0;
//        return;
//      }
      /* Send in parallel if we are running NUD (nbc state is either STALE,
         DELAY, or PROBE). See RFC 4861, section 7.7.3 on node behavior. */
      if(nbr->state == NBR_STALE) {
        nbr->state = NBR_DELAY;
//        stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME);
        nbr->nscount = 0;
        PRINTF("tcpip_ipv6_output: nbr cache entry stale moving to delay\n");
      }

//      stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
      tcpip_output(&nbr->lladdr);

#if UIP_CONF_IPV6_QUEUE_PKT
      /*
       * Send the queued packets from here, may not be 100% perfect though.
       * This happens in a few cases, for example when instead of receiving a
       * NA after sendiong a NS, you receive a NS with SLLAO: the entry moves
       * to STALE, and you must both send a NA and the queued packet.
       */
      if(uip_packetqueue_buflen(&nbr->packethandle) != 0) {
        uip_len = uip_packetqueue_buflen(&nbr->packethandle);
        memcpy(UIP_IP_BUF, uip_packetqueue_buf(&nbr->packethandle), uip_len);
        uip_packetqueue_free(&nbr->packethandle);
        tcpip_output(&nbr->lladdr);
      }
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/

      uip_len = 0;
      return;
    }
  }

  /* Multicast IP destination address. */
  tcpip_output(NULL);
  uip_len = 0;
  uip_ext_len = 0;
}