Exemple #1
0
static void uart_event_handle(app_uart_evt_t * p_event)
{
  static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
  static uint8_t index = 0;
  uint32_t       err_code;

  //uint8_t   dbg_idx = 0;
  //uint8_t   nDataLen = 0;

  switch (p_event->evt_type)
  {
      case APP_UART_DATA_READY:
          UNUSED_VARIABLE(app_uart_get(&data_array[index]));

          //log_print("0x%02x ", data_array[index]);

          index++;

          if ((data_array[index - 1] == 0x03/*'\n'*/) || (index >= (BLE_NUS_MAX_DATA_LEN)))
          {

              //err_code = ble_nus_string_send(&m_nus, data_array, index);
              err_code = ble_uart_send_data(data_array, index);
              if (err_code != NRF_ERROR_INVALID_STATE)
              {
                  APP_ERROR_CHECK(err_code);
              }

              index = 0;
              //nrf_delay_ms(10);
          }

          //nDataLen = sizeof(json);
#if 0
          do
            {
              if (nDataLen < BLE_NUS_MAX_DATA_LEN)
              {
                ble_uart_send_data((uint8_t *)json+dbg_idx, nDataLen);
                dbg_idx += nDataLen;
                nDataLen = 0;
              }
              else
                {
                ble_uart_send_data((uint8_t *)json+dbg_idx, BLE_NUS_MAX_DATA_LEN);
                dbg_idx += BLE_NUS_MAX_DATA_LEN;
                nDataLen -= BLE_NUS_MAX_DATA_LEN;
                }


               nrf_delay_ms(10);


            } while(nDataLen > 0);
#endif
          break;

      case APP_UART_COMMUNICATION_ERROR:
          APP_ERROR_HANDLER(p_event->data.error_communication);
          break;

      case APP_UART_FIFO_ERROR:
          APP_ERROR_HANDLER(p_event->data.error_code);
          break;

      default:
          break;
  }
}
Exemple #2
0
/** @brief Function for main application entry.
 */
int main(void)
{
	  TaskHandle_t  compress_task_handle;
	  TimerHandle_t spi_timer_handle;
	  uint32_t err_code;
	  static int intan_convert_channel = 0;
	
	  err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);
	
    // Setup bsp module.
    //bsp_configuration();

    //uart initialization
    const app_uart_comm_params_t comm_params =
      {
          RX_PIN_NUMBER,
          TX_PIN_NUMBER,
          RTS_PIN_NUMBER,
          CTS_PIN_NUMBER,
          APP_UART_FLOW_CONTROL_ENABLED,
          false,
          UART_BAUDRATE_BAUDRATE_Baud38400
      };

    APP_UART_FIFO_INIT(&comm_params,
                         UART_RX_BUF_SIZE,
                         UART_TX_BUF_SIZE,
                         uart_error_handle,
                         APP_IRQ_PRIORITY_LOW,
                         err_code);

    APP_ERROR_CHECK(err_code);

		//while(app_uart_put(65) != NRF_SUCCESS);
		//printf("1 ms = %d\n", pdMS_TO_TICKS(1));
		intan_setup();
		while(app_uart_put(65) != NRF_SUCCESS);
			
		compression_init();
		while(app_uart_put(66) != NRF_SUCCESS);
			
	  //printf("yo\n");
		UNUSED_VARIABLE(xTaskCreate(compress_task, "c_task", configMINIMAL_STACK_SIZE + 200, NULL, 2, &compress_task_handle));
			
		if(compress_task_handle == NULL)
		{
			printf("compression task init messed up\r\n");
		}
		while(app_uart_put(67) != NRF_SUCCESS);
		
    spi_timer_handle = xTimerCreate("s_timer", 1000, pdTRUE, NULL, spi_data_collection_evt_handler);                                 // LED1 timer creation
    
		if(spi_timer_handle == NULL)
		{
			printf("SPI timer init messed up\r\n");
		}
		while(app_uart_put(68) != NRF_SUCCESS);
		
		if(xTimerStart(spi_timer_handle, 0) != pdPASS)
		{
			printf("Timer could not be started\r\n");
		}
		while(app_uart_put(69) != NRF_SUCCESS);
			
		/* Activate deep sleep mode */
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

    // Start FreeRTOS scheduler.
    vTaskStartScheduler();
			
		//timers_init();
		//while(app_uart_put(67) != NRF_SUCCESS);
			
		//data_collection_timers_start();
		//while(app_uart_put(68) != NRF_SUCCESS);

    for (;;)
    {
			  printf("Messed up\r\n");
			  //power_manage();
        /*if (m_transfer_completed)
        {
					  //while(app_uart_put(72) != NRF_SUCCESS);
            m_transfer_completed = false;

            intan_convert(m_tx_data_spi, m_rx_data_spi,intan_convert_channel);
					  //while(app_uart_put(73) != NRF_SUCCESS);
            intan_convert_channel ++;
            intan_convert_channel = intan_convert_channel % 32;
            //print m_rx_data_spi results
            switch_state();
					  //while(app_uart_put(74) != NRF_SUCCESS);
					  //for (int i; i< RX_MSG_LENGTH; i++){
						//	while(app_uart_put(m_rx_data_spi[i]) != NRF_SUCCESS);
						//}
            nrf_delay_ms(DELAY_MS);
						//while(app_uart_put(75) != NRF_SUCCESS);
        }*/
				//while(app_uart_put(76) != NRF_SUCCESS);
    }
}
Exemple #3
0
/**@brief Function for TX state machine event processing in a state centric manner.
 *
 * @param[in] event Type of event occurred.
 */
static void tx_sm_event_handle(tx_event_t event)
{
    uint32_t err_code;
    
    switch (m_tx_state)
    {
        case TX_STATE_IDLE:
            if (event == TX_EVENT_STATE_ENTRY)
            {                 
                err_code = app_timer_stop(m_app_timer_id);
                APP_ERROR_CHECK(err_code);
                
                // Send TX-done event if registered handler exists.
                if (m_transport_tx_done_handle != NULL)                
                {
                    m_transport_tx_done_handle(m_tx_done_result_code);
                }                
            }
            break;
            
        case TX_STATE_PENDING:
            if (event == TX_EVENT_SLIP_TX_DONE)
            {     
                // @note: this call should always succeed as called from HCI_SLIP_TX_DONE context 
                // and error cases are managed by dedicated error event from the slip layer.
                err_code = hci_slip_write(mp_tx_buffer, 
                                         (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE));  
                APP_ERROR_CHECK(err_code);                                                  
                tx_sm_state_change(TX_STATE_ACTIVE);                                              
            }        
            break;
            
        case TX_STATE_ACTIVE:
            switch (event)
            {
                case TX_EVENT_VALID_RX_ACK:                    
                    // Tx sequence number counter incremented as packet transmission 
                    // acknowledged by peer transport entity.
                    packet_number_tx_inc();                                  
                    tx_sm_state_change(TX_STATE_IDLE);
                    break;
                    
                case TX_EVENT_STATE_ENTRY:
                    m_tx_retry_counter = 0;
                    err_code = app_timer_start(m_app_timer_id, 
                                               RETRANSMISSION_TIMEOUT_IN_TICKS, 
                                               NULL);
                    APP_ERROR_CHECK(err_code);
                    break;
                    
                case TX_EVENT_TIMEOUT:
                    if (m_tx_retry_counter != MAX_RETRY_COUNT)
                    {
                        ++m_tx_retry_counter;
                        // @note: no return value check done for hci_slip_write(...) call as current 
                        // system design allows use case where retransmission is not accepted by the 
                        // slip layer due to existing acknowledgement packet transmission in the 
                        // slip layer. 
                        UNUSED_VARIABLE(hci_slip_write(mp_tx_buffer, 
                                                      (m_tx_buffer_length + 
                                                      PKT_HDR_SIZE        + 
                                                      PKT_CRC_SIZE)));                
                    }    
                    else
                    {
                        // Application packet retransmission count reached: 
                        // - set correct TX done event callback function result code
                        // - execute state change    
                        // @note: m_tx_retry_counter is reset in TX_STATE_ACTIVE state entry.
                        m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE;         
                        tx_sm_state_change(TX_STATE_IDLE);
                    }                
                    break;
                    
                default:
                    break;
            }
            break;
            
        default:        
            break;
    }
}
Exemple #4
0
/**@brief Function for processing ANTFS upload request data event.
 * 
 * @param[in] p_event The event extracted from the queue to be processed.
 */
static void event_upload_request_handle(const antfs_event_return_t * p_event)
{
    uint8_t response = RESPONSE_MESSAGE_OK;   

    if ((p_event->offset == MAX_ULONG))  
    {
        // Requesting to resume an upload.
        
        if (m_file_index != p_event->file_index)
        {
            // We do not have a save point for this file.
            m_file_offset = 0;
            m_current_crc = 0;
        }
    }
    else    
    {
        // This is a new upload.
        
        // Use requested offset and reset CRC.
        m_file_offset = p_event->offset;    
        m_current_crc = 0;                  
    }

    m_file_index = p_event->file_index;   

    // Read file information from directory.            
    if (mem_file_info_get(m_file_index, &m_temp_dir_structure))  
    {             
        // Check permissions.
        if (!(m_temp_dir_structure.general_flags & ANTFS_DIR_WRITE_MASK))    
        {
            response = RESPONSE_MESSAGE_NOT_AVAILABLE;
            printf("Upload request denied: file n/a for writing\n");
        }

        // Set response parameters.
        m_response_info.file_index.data           = m_file_index;   
        // Current valid file size is the last offset written to the file.
        m_response_info.file_size.data            = m_file_offset;   
        // Space available for writing is the file size, as specified on directory.
        m_response_info.max_file_size             = m_temp_dir_structure.file_size_in_bytes;          
        // Get the entire file in a single burst if possible.
        m_response_info.max_burst_block_size.data = m_temp_dir_structure.file_size_in_bytes;  
        // Last valid CRC.
        m_response_info.file_crc                  = m_current_crc;      
    }
    else    
    {
        // Index not found.
        
        response                                  = RESPONSE_MESSAGE_NOT_EXIST;  
        m_response_info.file_index.data           = m_file_index;
        m_response_info.file_size.data            = 0;   
        m_response_info.max_file_size             = 0;
        m_response_info.max_burst_block_size.data = 0;
        m_response_info.file_crc                  = 0;
        printf("Upload request denied: file does not exist\n");
    }

    m_upload_success = true;
    
    // @note: Suppress return value as no use case for handling it exists.
    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(response, &m_response_info));
}
Exemple #5
0
/**@brief Function for processing a single ANTFS event.
 *
 * @param[in] p_event The event extracted from the queue to be processed.
 */
static void antfs_event_process(const antfs_event_return_t * p_event)
{
    switch (p_event->event)
    {
        case ANTFS_EVENT_OPEN_COMPLETE:
            printf("ANTFS_EVENT_OPEN_COMPLETE\n");
            break;
            
        case ANTFS_EVENT_CLOSE_COMPLETE:
            printf("ANTFS_EVENT_CLOSE_COMPLETE\n");
            break;
            
        case ANTFS_EVENT_LINK:
            printf("ANTFS_EVENT_LINK\n");
            break;
            
        case ANTFS_EVENT_AUTH:
            printf("ANTFS_EVENT_AUTH\n");
            break;
            
        case ANTFS_EVENT_TRANS:
            printf("ANTFS_EVENT_TRANS\n");
            break;
            
        case ANTFS_EVENT_PAIRING_REQUEST:
            printf("ANTFS_EVENT_PAIRING_REQUEST\n");       
            event_pairing_request_handle();
            break;
            
        case ANTFS_EVENT_PAIRING_TIMEOUT:
            printf("ANTFS_EVENT_PAIRING_TIMEOUT\n");
            break;
            
        case ANTFS_EVENT_DOWNLOAD_REQUEST:
            printf("ANTFS_EVENT_DOWNLOAD_REQUEST\n");
            event_download_request_handle(p_event);
            break;        
            
        case ANTFS_EVENT_DOWNLOAD_START:
            printf("ANTFS_EVENT_DOWNLOAD_START\n");
            break;
            
        case ANTFS_EVENT_DOWNLOAD_REQUEST_DATA:
            event_download_data_handle(p_event);
            break;
            
        case ANTFS_EVENT_DOWNLOAD_COMPLETE:
            printf("ANTFS_EVENT_DOWNLOAD_COMPLETE\n");
            break;
            
        case ANTFS_EVENT_DOWNLOAD_FAIL:
            printf("ANTFS_EVENT_DOWNLOAD_FAIL\n");
            break;
            
        case ANTFS_EVENT_UPLOAD_REQUEST:
            printf("ANTFS_EVENT_UPLOAD_REQUEST\n");
            event_upload_request_handle(p_event);
            break;
            
        case ANTFS_EVENT_UPLOAD_START:
            printf("ANTFS_EVENT_UPLOAD_START\n");
            break;
            
        case ANTFS_EVENT_UPLOAD_DATA:
            event_upload_data_handle(p_event);
            break;
            
        case ANTFS_EVENT_UPLOAD_FAIL:
            printf("ANTFS_EVENT_UPLOAD_FAIL\n");
            // @note: Suppress return value as no use case for handling it exists.
            UNUSED_VARIABLE(antfs_upload_data_resp_transmit(false));
            break;
            
        case ANTFS_EVENT_UPLOAD_COMPLETE:
            printf("ANTFS_EVENT_UPLOAD_COMPLETE\n");
            event_upload_complete_handle();
            break;
            
        case ANTFS_EVENT_ERASE_REQUEST:
            printf("ANTFS_EVENT_ERASE_REQUEST\n"); 
            event_erase_request_handle(p_event);
            break;
            
        default:
            break;
    }
}
/**@brief Function for decoding a command packet with RPC_SD_BLE_GATTS_HVX opcode.
 *
 * This function will decode the command, call the BLE Stack API, and also send command response
 * to the peer through the the transport layer.
 *
 * @param[in] p_command         The encoded structure that needs to be decoded and passed on
 *                              to the BLE Stack API.
 * @param[in] command_len       The length of the encoded command read from transport layer.
 *
 * @retval NRF_SUCCESS               If the decoding of the command was successful, the SoftDevice
 *                                   API was called, and the command response was sent to peer,
 *                                   otherwise an error code.
 * @retval NRF_ERROR_INVALID_LENGTH  If the content length of the packet is not conforming to the
 *                                   codec specification.
 */
static uint32_t gatts_hvx_handle(uint8_t * const p_command, uint32_t command_len)
{
    uint32_t               err_code;
    uint16_t               conn_handle;
    ble_gatts_hvx_params_t hvx_params;
    uint8_t                resp_data[sizeof(uint16_t)];

    uint16_t                 hvx_params_data_length = 0;
    uint32_t                 index                  = 0;
    ble_gatts_hvx_params_t * p_hvx_params           = NULL;

    conn_handle  = uint16_decode(&p_command[index]);
    index       += sizeof(uint16_t);
    RPC_DECODER_LENGTH_CHECK(command_len, index, SD_BLE_GATTS_HVX);

    if (p_command[index++] == RPC_BLE_FIELD_PRESENT)
    {
        hvx_params.handle  = uint16_decode(&p_command[index]);
        index             += sizeof(uint16_t);
        hvx_params.type    = p_command[index++];
        hvx_params.offset  = uint16_decode(&p_command[index]);
        index             += sizeof(uint16_t);
        RPC_DECODER_LENGTH_CHECK(command_len, index, SD_BLE_GATTS_HVX);
        if (p_command[index++] == RPC_BLE_FIELD_PRESENT)
        {
            hvx_params_data_length  = uint16_decode(&p_command[index]);
            index                  += sizeof(uint16_t);
            hvx_params.p_len        = &hvx_params_data_length;
        }
        else
        {
            hvx_params.p_len = NULL;
        }
        RPC_DECODER_LENGTH_CHECK(command_len,
                                 (index + hvx_params_data_length),
                                 SD_BLE_GATTS_HVX);

        if (p_command[index++] == RPC_BLE_FIELD_PRESENT)
        {
            hvx_params.p_data = &(p_command[index]);
        }
        else
        {
            hvx_params.p_data = NULL;
        }
        p_hvx_params = &hvx_params;
    }

    RPC_DECODER_LENGTH_CHECK(command_len, index, SD_BLE_GATTS_HVX);

    err_code = sd_ble_gatts_hvx(conn_handle, p_hvx_params);

    if (err_code == NRF_SUCCESS)
    {
        if (p_hvx_params != NULL && p_hvx_params->p_len != NULL)
        {
            UNUSED_VARIABLE(uint16_encode(*(p_hvx_params->p_len), resp_data));
            return ble_rpc_cmd_resp_data_send(SD_BLE_GATTS_HVX,
                                              err_code,
                                              resp_data,
                                              sizeof(resp_data));
        }
    }

    return ble_rpc_cmd_resp_send(SD_BLE_GATTS_HVX, err_code);
}
Exemple #7
0
void BLEonAdvReport(ble_gap_evt_adv_report_t* advReport)
{
    //debug_log("BLECH\r\n");
    signed char rssi = advReport->rssi;
    
    if (rssi < MINIMUM_RSSI)  {
        return;  // ignore signals that are too weak.
    }
    
    unsigned char dataLength = advReport->dlen;
    unsigned char* data = (unsigned char*)advReport->data;
    unsigned char index = 0;
    
    unsigned char* namePtr = NULL;
    //unsigned char  nameLen = 0;
    unsigned char* manufDataPtr = NULL;
    unsigned char  manufDataLen = 0;
    
    unsigned char group = BAD_GROUP;
    unsigned short ID = BAD_ID;
    
    while ((namePtr == NULL || manufDataPtr == NULL) && index < dataLength)  {
        unsigned char fieldLen = data[index];
        index++;
        unsigned char fieldType = data[index];
        if (fieldType == BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME || fieldType == BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME)  {
            namePtr = &data[index + 1];  // skip field type byte
            //nameLen = fieldLen - 1;
        }
        else if (fieldType == BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA)  {
            manufDataPtr = &data[index + 1];  // skip field type byte
            manufDataLen = fieldLen - 1;
        }
        index += fieldLen;
    }
    
    if (manufDataLen == BADGE_MANUF_DATA_LEN)  {
        if (namePtr != NULL && memcmp(namePtr,(const uint8_t *)DEVICE_NAME,strlen(DEVICE_NAME)) == 0)  {
            custom_adv_data_t badgeAdvData;
            memcpy(&badgeAdvData,&manufDataPtr[2],CUSTOM_ADV_DATA_LEN);  // skip past company ID; ensure data is properly aligned
            ID = badgeAdvData.ID;
            group = badgeAdvData.group;
            debug_log("---Badge seen: group %d, ID %.4X, rssi %d.\r\n",(int)group,(int)ID,(int)rssi);
        }
    }
    else if (manufDataLen == IBEACON_MANUF_DATA_LEN)  {
        iBeacon_data_t iBeaconData;
        memcpy(&iBeaconData,manufDataPtr,IBEACON_MANUF_DATA_LEN);  // ensure data is properly aligned
        if (iBeaconData.companyID == COMPANY_ID_APPLE && iBeaconData.type == IBEACON_TYPE_PROXIMITY)  {
            // major/minor values are big-endian
            unsigned short major = ((unsigned short)iBeaconData.major[0] * 256) + iBeaconData.major[1];
            UNUSED_VARIABLE(major);
            unsigned short minor = ((unsigned short)iBeaconData.minor[0] * 256) + iBeaconData.minor[1];
            debug_log("---iBeacon seen: major %d, minor %d, rssi %d.\r\n",(int)major,minor,(int)rssi);
            group = iBeaconData.major[1];  // take only lower byte of major value
            ID = minor;
        }
    }
    
    if (ID != BAD_ID && group == badgeAssignment.group && scan.num < MAX_SCAN_RESULTS)  {
        bool prevSeen = false;
        for(int i=0; i<scan.num; i++)  {      // check through list of already seen badges
            if(ID == scan.IDs[i])  {
                scan.rssiSums[i] += rssi;
                scan.counts[i]++;
                prevSeen = true;
                break;
            }
        }
        if(!prevSeen)  {                             // is it a new badge
            scan.IDs[scan.num] = ID;
            scan.rssiSums[scan.num] = rssi;
            scan.counts[scan.num] = 1;
            scan.num++;
        }
    }
    
    /*
    
    // Parse the broadcast packet.  (find+check name, find custom data if present)
    while ((name == NULL || gotPayload == false) && index < dataLength)  {
        unsigned char fieldLen = data[index];
        index++;
        unsigned char fieldType = data[index];
        if (fieldType == BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME || fieldType == BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME)  {
            name = &data[index + 1];
            if (memcmp(name,(const uint8_t *)DEVICE_NAME,strlen(DEVICE_NAME)) == 0)  {
                // name checks out
            }
            else if (name != NULL && memcmp(name,(const uint8_t *)BEACON_NAME,strlen(BEACON_NAME)) == 0)  {
                payload.group = BEACON_GROUP;
                // our beacons are named "[BEACON_NAME]XXXX", where XXXX is a hex ID number.
                payload.ID = hexStringToShort(&name[strlen(BEACON_NAME)]);
                if (payload.ID != 0xffff)  {  // was there a valid ID in name?
                    gotPayload = true;
                }
            }
            else  {
                gotPayload = false;
                break;  // if name doesn't match, stop parsing broadcast packet
            }
        }
        else if(fieldType == BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA)  {
            int payloadLen = fieldLen - 3;  // length of field minus field type byte and manuf ID word
            if(payloadLen == CUSTOM_DATA_LEN)  {
                // Need to copy payload data so it is properly aligned.
                memcpy(&payload,&data[index+3],CUSTOM_DATA_LEN);  // skip past field type byte, manuf ID word
                gotPayload = true;
            }
        }
        index += fieldLen;
    }
    
    if(gotPayload)  {   // did we see a valid device, and retrieve relevant data?
        debug_log("---Badge seen: group %d, ID %hX, rssi %d.\r\n",(int)payload.group,payload.ID,(int)rssi);
        if(payload.group == badgeAssignment.group || payload.group == BEACON_GROUP)  {
            bool prevSeen = false;
            for(int i=0; i<scan.num; i++)  {      // check through list of already seen badges
                if(payload.ID == scan.IDs[i])  {
                    scan.rssiSums[i] += rssi;
                    scan.counts[i]++;
                    prevSeen = true;
                    break;
                }
            }
            if(!prevSeen)  {                             // is it a new badge
                scan.IDs[scan.num] = payload.ID;
                scan.rssiSums[scan.num] = rssi;
                scan.counts[scan.num] = 1;
                scan.num++;
            }
        }
    }
    */
    
    /*
    // step through data until we find both the name and custom data, or have reached the end of the data
    while ((gotPayload == false || name == NULL) && index < dataLength)  {
        unsigned char fieldLen = data[index];
        index++;
        unsigned char fieldType = data[index];
        if(fieldType == BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME
            || fieldType == BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME)
        {
            name = &data[index+1];
        }
        else if(fieldType == BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA)
        {
            payloadLen = fieldLen - 3;  // length of field minus field type byte and manuf ID word
            if(payloadLen == CUSTOM_DATA_LEN)
            {
                // Need to copy payload data so it is properly aligned.
                memcpy(&payload,&data[index+3],CUSTOM_DATA_LEN);  // skip past field type byte, manuf ID word
                gotPayload = true;
            }
        }
        index += fieldLen;
    }
    
    if(name != NULL && memcmp(name,(const uint8_t *)DEVICE_NAME,strlen(DEVICE_NAME)) == 0)  {  // is it a badge?
        if(gotPayload)  {   // is there custom data, and the correct amount?
            //debug_log("Badge seen: group %d, ID %hX, rssi %d.\r\n",(int)payload.group,payload.ID,(int)rssi);
            if(payload.group == badgeAssignment.group)  {
                bool prevSeen = false;
                for(int i=0; i<scan.num; i++)  {      // check through list of already seen badges
                    if(payload.ID == scan.IDs[i])  {
                        scan.rssiSums[i] += rssi;
                        scan.counts[i]++;
                        prevSeen = true;
                        break;
                    }
                }
                if(!prevSeen)  {                             // is it a new badge
                    scan.IDs[scan.num] = payload.ID;
                    scan.rssiSums[scan.num] = rssi;
                    scan.counts[scan.num] = 1;
                    scan.num++;
                }
            }
        }
        else  {
            //debug_log("Badge seen, rssi %d, but wrong/missing adv data, len %d?\r\n",(int)rssi,payloadLen);
        }
    }
    else if (name != NULL && memcmp(name,(const uint8_t *)BEACON_NAME,strlen(BEACON_NAME)) == 0)  {
        // beacons are named [BEACON_NAME]XXXX, where XXXX is a hex ID number.
        unsigned short beaconID = hexStringToShort(&name[strlen(BEACON_NAME)]);  
    }
    else  {
        //debug_log("Unknown device seen, name %.5s, rssi %d.\r\n",name,(int)rssi);
    }
    */
        
}
/*
 * NOTE: This callback is only called by the following
 *  - Storing done operation by dfu_data_pkt_handle
 *  - And all clearing done operation.
 */
static void dfu_cb_handler(uint32_t result, uint8_t * p_data)
{
    uint32_t err_code;
    uint16_t rxd_buffer_len = 0;
    uint16_t ram_crc        = 0;
    uint16_t flash_crc      = 0;

#if defined (DBG_DFU_UART_OUT_PIN)
    DEBUG_UART_OUT(0xFF);
    DEBUG_UART_OUT(m_antfs_dfu_state);
#endif

    switch (m_antfs_dfu_state)
    {
        case ANTFS_DFU_STATE_INIT_DELAYED:
            // This is when upon initialization, a pre-erase operation have occured i.e. bank1 pre clearing.
            services_init();
            break;

        case ANTFS_DFU_STATE_FLASH_ERASE:
            // Handles upload and download request response delay when there is ongoing flash activities
            // Generally we need to avoid flash activities and burst activities to happen at the same time.
            // ANTFS request response are delayed and when flash is done response are handled here.
            if (m_upload_request_in_progress)
            {
                m_upload_request_in_progress    = false;
                // Make sure we got all the latest values.
                m_response_info.file_size.data  = m_current_offset;
                m_response_info.file_crc        = m_current_crc;
                if (result == NRF_SUCCESS)
                {
                    m_upload_swap_space_prepared = true;
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));
                }
                else
                {
                    /* Not ready */
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_UPLOAD_NOT_READY, &m_response_info));
                }
            }

            if (m_download_request_in_progress)
            {
                m_download_request_in_progress = false;

                UNUSED_VARIABLE(antfs_download_req_resp_prepare(RESPONSE_MESSAGE_OK, &m_response_info));
            }

            m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
            break;


        case ANTFS_DFU_STATE_FLASH_PENDING:
        case ANTFS_DFU_STATE_READY:
            // Handles Flash write call back queued by Upload Data.
            if (result != NRF_SUCCESS)
            {
                upload_data_response_fail_reset();
                return;
            }

            if ((m_mem_pool_1.a_mem_pool <= p_data) && (p_data <= (m_mem_pool_1.a_mem_pool + ANTFS_UPLOAD_DATA_BUFFER_MAX_SIZE)))
            {
                rxd_buffer_len = m_mem_pool_1.size;
                ram_crc = m_mem_pool_1.crc;
                m_mem_pool_1.size = 0;
            }
            else if ((m_mem_pool_2.a_mem_pool <= p_data) && (p_data <= (m_mem_pool_2.a_mem_pool + ANTFS_UPLOAD_DATA_BUFFER_MAX_SIZE)))
            {
                rxd_buffer_len = m_mem_pool_2.size;
                ram_crc = m_mem_pool_2.crc;
                m_mem_pool_2.size = 0;
            }
            else
            {
                upload_data_response_fail_reset();
                return;
            }

            // Verify the data written to flash.
            flash_crc = crc_crc16_update(0, (uint8_t*)(dfu_storage_start_address_get() + m_image_data_offset), rxd_buffer_len);
            if (flash_crc != ram_crc)
            {
                upload_data_response_fail_reset();
                return;
            }

            //update current offsets and crc
            m_current_offset    += rxd_buffer_len;
            m_current_crc       = crc_crc16_update(m_current_crc, (uint8_t*)(dfu_storage_start_address_get() + m_image_data_offset), rxd_buffer_len);

            m_image_data_offset += rxd_buffer_len;

            if (m_antfs_dfu_state == ANTFS_DFU_STATE_FLASH_PENDING)
            {
                m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
                // Update it with the latest values;
                m_response_info.file_size.data            = m_current_offset;
                m_response_info.file_crc                  = m_current_crc;
                if (m_upload_request_in_progress)
                {
                    m_upload_request_in_progress = false;
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));
                }
                else    // data response
                {
                    if (m_image_data_complete == true)
                    {
                        if (m_image_data_max == m_image_data_offset)
                        {
                            err_code = dfu_image_validate(m_header_crc_seed);
                            if (err_code == NRF_SUCCESS)
                            {
                                UNUSED_VARIABLE(antfs_upload_data_resp_transmit(true));
                                m_antfs_dfu_state = ANTFS_DFU_STATE_VALIDATED;
                                return;
                            }
                            else
                            {
                                upload_data_response_fail_reset();
                            }
                        }

                        if ((m_mem_pool_1.size != 0) || (m_mem_pool_2.size != 0))
                        {
                            m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_PENDING;
                        }
                    }
                    else //m_image_data_complete == false
                    {
                        if ((m_mem_pool_1.size == 0) && (m_mem_pool_2.size == 0))
                        {
                            UNUSED_VARIABLE(antfs_upload_data_resp_transmit(true));                 // Handles block transfers
                        }
                        else
                        {
                            m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_PENDING;
                        }
                    }
                }
            }

            break;

        default:
            break;
    }
}
/**@brief Function for processing ANTFS upload request data event.
 *
 * @param[in] p_event The event extracted from the queue to be processed.
 */
static void antfs_event_upload_request_handle(const antfs_event_return_t * p_event)
{
    uint32_t    err_code = RESPONSE_MESSAGE_OK;
    uint8_t     new_request = false;

    if ((m_antfs_dfu_state == ANTFS_DFU_STATE_FLASH_ERASE) || (m_antfs_dfu_state == ANTFS_DFU_STATE_FLASH_PENDING))
    {
        return;
    }

    /*reset*/
    m_response_info.file_index.data           = p_event->file_index;
    m_response_info.max_burst_block_size.data = 0;
    m_response_info.max_file_size             = 0;
    m_response_info.file_size.data            = 0;
    m_response_info.file_crc                  = 0;

    // Evaluate File Index first
    if (m_current_file_index != p_event->file_index )
    {
        m_current_file_index = p_event->file_index;
        m_current_offset                        = 0;
        m_current_crc                           = 0;
    }

    if (p_event->offset == MAX_ULONG)
    {
        // This is a request to continue upload.
    }
    else if (p_event->offset == 0x00)
    {
        new_request = true;
    }
    else if(p_event->offset != m_current_offset)
    {
        // Something is wrong.
        UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_INVALID_OPERATION, &m_response_info));
        m_antfs_dfu_state = ANTFS_DFU_STATE_STALL;
    }
    else
    {
        // no implementation.
    }

    switch (m_current_file_index)
    {
#if !defined (S210_V3_STACK)
        case ANTFS_FILE_INDEX_UPDATE_STACK:
        case ANTFS_FILE_INDEX_UPDATE_BOOTLOADER:
        case ANTFS_FILE_INDEX_UPDATE_STACK_BOOTLOADER:
#endif // S210_V3_STACK
        case ANTFS_FILE_INDEX_UPDATE_APPLICATION:
        {
            // Current valid file size is the last offset written to the file.
            m_response_info.file_size.data            = m_current_offset;
            // Intentionally report maximum allowed upload file size as max writeable file size + header and crc.
            // Writeable size check will be performed by dfu_start_pkt_handle() after parsing uploaded header
            m_response_info.max_file_size             = ANTFS_FILE_SIZE_MAX_DFU_IMAGE + OTA_IMAGE_HEADER_SIZE_MAX;
            // Maximum burst block should be maximum allowable downloadable file size.
            m_response_info.max_burst_block_size.data = ANTFS_FILE_SIZE_MAX_DFU_IMAGE + OTA_IMAGE_HEADER_SIZE_MAX;
            // Last valid CRC.
            m_response_info.file_crc                  = m_current_crc;

            // Will only handle upload request while at ANTFS_DFU_STATE_READY
            if (m_antfs_dfu_state == ANTFS_DFU_STATE_VALIDATED)
            {
                if (new_request)
                {
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_AVAILABLE, &m_response_info));
                }
                else
                {
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));                 // To handle resume at end of data.
                }
                return;
            }
            else if (m_antfs_dfu_state != ANTFS_DFU_STATE_READY)
            {
                UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_AVAILABLE, &m_response_info));
                return;
            }

            // Check File Size if it can still fit. Uploaded file size may be larger than the total writeable space because it includes header
            // and CRC that do not get written to flash. Writeable size check will be performed by dfu_start_pk_handle() after
            // parsing uploaded header
            if ((p_event->offset + p_event->bytes) > (ANTFS_FILE_SIZE_MAX_DFU_IMAGE + OTA_IMAGE_HEADER_SIZE_MAX + OTA_IMAGE_CRC_SIZE_MAX))
            {
                UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_ENOUGH_SPACE, &m_response_info));
                return;
            }

            m_data_buffered         = 0;

            if (new_request)
            {
                m_current_offset    = 0;
                m_current_crc       = 0;
                m_pending_offset    = 0;

                antfs_ota_init();

                // Only supports offset starting at 0;
                if (p_event->offset != 0)
                {
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_FAIL, &m_response_info));
                    return;
                }

//                boot_return_set(PARAM_RETURN_BOOT_STATUS_Entered);

                // Store file size,
                m_current_file_size     = p_event->bytes;

                if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_STACK)
                {
                    m_update_mode = DFU_UPDATE_SD;
                }
                else if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_BOOTLOADER)
                {
                    m_update_mode = DFU_UPDATE_BL;
                }
                else if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_APPLICATION)
                {
                    m_update_mode = DFU_UPDATE_APP;
                }
                else if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_STACK_BOOTLOADER)
                {
                    m_update_mode = DFU_UPDATE_SD;
                    m_update_mode |= DFU_UPDATE_BL;//lint !e655 suppress Lint Warning 655: Bit-wise operations
                }

                m_dfu_pkt.packet_type = INIT_PACKET;

                if ((*ANT_BOOT_APP_SIZE > DFU_IMAGE_MAX_SIZE_BANKED)    ||
                    (*ANT_BOOT_APP_SIZE == 0xFFFFFFFF)                  ||
                    (*ANT_BOOT_APP_SIZE == 0x00000000)                  ||
                    (m_update_mode & DFU_UPDATE_SD))/*lint !e655 suppress Lint Warning 655: Bit-wise operations*/
                {
                    m_dfu_pkt.params.init_packet.total_image_size = DFU_IMAGE_MAX_SIZE_FULL;
                }
                else
                {
                    m_dfu_pkt.params.init_packet.total_image_size = m_current_file_size;
                }

                if (m_upload_swap_space_prepared == true)
                {
                    // Prepare no flash, except the states
                    m_dfu_pkt.params.init_packet.total_image_size = 0;
                }

                err_code = dfu_init_pkt_handle(&m_dfu_pkt);
                if (err_code)
                {
                    if (err_code == NRF_ERROR_INVALID_STATE)
                    {
                        UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_INVALID_OPERATION, &m_response_info));
                    }
                    else
                    {
                        UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_FAIL, &m_response_info));
                    }
                    return;
                }

                m_ota_image_header_parsed   = false;
                m_image_data_complete       = false;
                m_image_data_offset         = 0;

                m_data_buffered             = 0;

                // A flash erase is expected at this time. postpone response if there is.
                if (flash_busy())
                {
                    m_upload_request_in_progress = true;
                    m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_ERASE;
                    return;
                }
            }
            else
            {
                // Check if there are still pending writes scheduled in Flash.
                if (flash_busy())
                {
                    m_upload_request_in_progress = true;
                    m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_PENDING;
                    return;
                }
            }

            m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
            UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));
        }
            break;
        default:
            m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
            UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_EXIST, &m_response_info));
    }
}
static void upload_data_response_fail_reset(void)
{
    UNUSED_VARIABLE(antfs_upload_data_resp_transmit(false));
    m_antfs_dfu_state = ANTFS_DFU_STATE_STALL;
}
Exemple #11
0
/**@brief Function for updating the wall clock of the IoT Timer module.
 */
static void iot_timer_tick_callback(void * p_context)
{
    UNUSED_VARIABLE(p_context);
    uint32_t err_code = iot_timer_update();
    APP_ERROR_CHECK(err_code);
}
Exemple #12
0
void storer_init()
{
    
    storerMode = STORER_INIT;
    store.from = 0;
    store.to = 0;
    
    debug_log("-storer initialization-\r\n");
    
    unsigned long lastStoredTime = MODERN_TIME;
    
    for (int c = 0; c <= LAST_FLASH_CHUNK; c++)  {
        mic_chunk_t* chunkPtr = (mic_chunk_t*)ADDRESS_OF_CHUNK(c);

        unsigned long timestamp = chunkPtr->timestamp;
        unsigned long check = chunkPtr->check;
        
        //is the timestamp possibly valid?
        if (timestamp < FUTURE_TIME && timestamp > MODERN_TIME)  { 
            //is it a completely stored chunk?
            if (timestamp == check || check == CHECK_TRUNC)  { 
                //is it later than the latest stored one found so far?
                if (timestamp > lastStoredTime)  { 
                    store.to = c; //keep track of latest stored chunk
                    lastStoredTime = timestamp;
                }
            }
        }
        
    }
    
    if (lastStoredTime == MODERN_TIME)  {  // no valid chunk found
        debug_log("  No stored chunks found. Will start from chunk 0.\r\n");
        store.to = LAST_FLASH_CHUNK;    // will advance to chunk 0 below.
    }
    else  {
        debug_log("  Last stored chunk: %d at time: 0x%lX\r\n", store.to, lastStoredTime);
        //printStorerChunk(store.to);
    }
    
    
    debug_log("  Initializing FLASH for storage...\r\n");
    
    int newChunk = (store.to < LAST_FLASH_CHUNK) ? store.to+1 : 0;  // next chunk in FLASH (first unused chunk)
    
    unsigned char oldPage = PAGE_OF_CHUNK(store.to);
    unsigned char newPage = PAGE_OF_CHUNK(newChunk);
    
    // If new chunk is on a new page, we can just erase the whole page.
    if (oldPage != newPage)  {
        debug_log("    erase pg%d.\r\n",(int)newPage);
        nrf_delay_ms(20);
        erasePageOfFlash(newPage);
        while(flashWorking);
    }
    // If new chunk is on same page as old data, we need to erase while preserving the old data
    else  {
        uint32_t* oldChunkAddr = ADDRESS_OF_CHUNK(store.to);   // address of latest stored data
        uint32_t* pageAddr = ADDRESS_OF_PAGE(newPage); // address of beginning of current page
        
        int bytesToErase = (int)(oldChunkAddr) - (int)(pageAddr); // how many bytes of current page we need to erase
        int chunksToSave = (BYTES_PER_PAGE - bytesToErase)/CHUNK_SIZE;  // how many old chunks are in this page
        UNUSED_VARIABLE(chunksToSave);
        
        debug_log("    pg%d (%d chunks)-->RAM...", newPage, chunksToSave);
        uint32_t temp[WORDS_PER_PAGE];                            // temporary buffer for page
        memcpy(temp, pageAddr, BYTES_PER_PAGE);                   // copy old data to buffer
        debug_log("clear %dbytes...", bytesToErase);
        memset(temp, 0xff, bytesToErase);                         // clear unused portion of page in buffer
        
        debug_log("erase pg%d...",(int)newPage);
        nrf_delay_ms(20);
        erasePageOfFlash(newPage);                              // erase page
        while(flashWorking);
        
        debug_log("restore data...\r\n");
        nrf_delay_ms(10);
        writeBlockToFlash(pageAddr, temp, WORDS_PER_PAGE);      // replace data from buffer
        while(flashWorking);
    }
    
    store.to = newChunk;
    debug_log("  Ready to store to chunk %d.\r\n",newChunk); 
    
    store.extFrom = 0;
    
    // We need to find the most recent stored chunk, to start storing after it
    
    scan_header_t header;
    scan_tail_t tail;
    
    ext_eeprom_wait();

    store.extTo = EXT_FIRST_DATA_CHUNK;
    unsigned long lastStoredTimestamp = 0;
    for (int i = EXT_FIRST_DATA_CHUNK; i <= EXT_LAST_CHUNK; i++)  {
        unsigned int addr = EXT_ADDRESS_OF_CHUNK(i);
        ext_eeprom_read(addr,header.buf,sizeof(header.buf));               // Beginning of the chunk
        ext_eeprom_wait();
        ext_eeprom_read(addr+EXT_CHUNK_SIZE-4,tail.buf,sizeof(tail.buf));  // End of the chunk
        ext_eeprom_wait();
        
        // Print all written chunks
        /*if(header.timestamp != 0xFFFFFFFFUL)
        {
            debug_log("CH: %d,TS: %X\r\n",i,(int)header.timestamp);
            nrf_delay_ms(2);
        } */
        
        // is it a completely stored scan result chunk?
        if (header.timestamp > MODERN_TIME && header.timestamp < FUTURE_TIME)  {
            if (tail.check == header.timestamp || tail.check == CHECK_TRUNC || tail.check == CHECK_CONTINUE)  {
                // is it the most recent one found yet?
                if (header.timestamp >= lastStoredTimestamp)  {
                    lastStoredTimestamp = header.timestamp;
                    store.extTo = i;
                }
            }
        }
    }
    
    if (lastStoredTimestamp == 0)  {
        debug_log("  No stored scans found.\r\n");
    }
    else  {
        debug_log("  Last stored scan in chunk %d, timestamp %X.\r\n",(int)store.extTo,(int)lastStoredTimestamp);
    }
    
    store.extTo = (store.extTo < EXT_LAST_CHUNK) ? store.extTo+1 : EXT_FIRST_DATA_CHUNK;
    
    
    //store.extFrom = 0;
    //store.extTo = EXT_FIRST_DATA_CHUNK;
    ext_eeprom_global_unprotect();
    ext_eeprom_wait();
    
    
    
    storerMode = STORER_IDLE;
    
}
Exemple #13
0
double StairSpiked::GetHumanStep(int nHumanDirection)
{
	UNUSED_VARIABLE(nHumanDirection);

	return 1;
}
Exemple #14
0
/**@brief Timer callback used for periodic servicing of LwIP protocol timers.
 *        This trigger is also used in the example to trigger sending UDP packets on the port.
 *
 * @details Timer callback used for periodic servicing of LwIP protocol timers.
 *
 * @param[in]   p_context   Pointer used for passing context. No context used in this application.
 */
static void system_timer_callback(iot_timer_time_in_ms_t wall_clock_value)
{
    UNUSED_VARIABLE(wall_clock_value);

    sys_check_timeouts();
}