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; } }
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; }