/* Usually called once every second, this function updates the * uptime.yaku TXT CHAOS RR in the local table. */ int uptime_refresh(void) { struct RRentry *uptimerr = NULL; char buffer[1024]; byte *encoded_uptime; int encoded_uptime_size; time_t uptime; uptimerr = local_search(YAKU_UPTIME_RR_NAME".", T_TXT, C_CHAOS, 0); if (uptimerr == NULL) { uptimerr = alloc_rr(YAKU_UPTIME_RR_NAME, T_TXT, C_CHAOS, 1); if (uptimerr == NULL) return -1; uptimerr->data[0] = 0; uptimerr->ttl = 0; local_add_entry(uptimerr); } uptime = get_sec() - ens_start; snprintf(buffer, 1024, "%ld days,%ld hours,%ld minutes,%ld seconds", uptime/86400, (uptime%86400)/3600, ((uptime%86400)%3600)/60, ((uptime%86400)%3600)%60); encoded_uptime = name_encode(buffer, &encoded_uptime_size, ','); if (encoded_uptime == NULL) return encoded_uptime_size; encoded_uptime_size--; free(uptimerr->data); uptimerr->data = encoded_uptime; uptimerr->size = encoded_uptime_size; return 0; }
static uint32_t adv_data_encode(const ble_advdata_t * p_advdata, uint8_t * p_encoded_data, uint8_t * p_len) { uint32_t err_code = NRF_SUCCESS; *p_len = 0; // Encode name if (p_advdata->name_type != BLE_ADVDATA_NO_NAME) { err_code = name_encode(p_advdata, p_encoded_data, p_len); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode appearance if (p_advdata->include_appearance) { err_code = appearance_encode(p_encoded_data, p_len); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode flags if (p_advdata->flags.size > 0) { err_code = uint8_array_encode(&p_advdata->flags, BLE_GAP_AD_TYPE_FLAGS, p_encoded_data, p_len); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode TX power level if (p_advdata->p_tx_power_level != NULL) { err_code = tx_power_level_encode(*p_advdata->p_tx_power_level, p_encoded_data, p_len); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode 'more available' uuid list if (p_advdata->uuids_more_available.uuid_cnt > 0) { err_code = uuid_list_encode(&p_advdata->uuids_more_available, BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE, BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE, p_encoded_data, p_len); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode 'complete' uuid list if (p_advdata->uuids_complete.uuid_cnt > 0) { err_code = uuid_list_encode(&p_advdata->uuids_complete, BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE, p_encoded_data, p_len); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode 'solicited service' uuid list if (p_advdata->uuids_solicited.uuid_cnt > 0) { err_code = uuid_list_encode(&p_advdata->uuids_solicited, BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT, BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT, p_encoded_data, p_len); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode Slave Connection Interval Range if (p_advdata->p_slave_conn_int != NULL) { err_code = conn_int_encode(p_advdata->p_slave_conn_int, p_encoded_data, p_len); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode Manufacturer Specific Data if (p_advdata->p_manuf_specific_data != NULL) { err_code = manuf_specific_data_encode(p_advdata->p_manuf_specific_data, p_encoded_data, p_len); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode Service Data if (p_advdata->service_data_count > 0) { err_code = service_data_encode(p_advdata, p_encoded_data, p_len); if (err_code != NRF_SUCCESS) { return err_code; } } return err_code; }
/* Add a Resource Record to the DNS packet: * return codes: * >= 0 success * YK_NOMEM out of memory */ int add_rr(byte **dest, HEADER *hdr, struct RRentry *rr, unsigned int size, int section, int maxsize) { int offset = size, retval, newsize; u_int16_t tmp16; u_int32_t tmp32; byte *encoded_name, *tmp; ARG_UNUSED(hdr) #if 0 printf("Add %s %s %s (%d)\n", rr->name, qclass_to_str(rr->qclass), qtype_to_str(rr->qtype), size); #endif encoded_name = name_encode(rr->name, &retval, '.'); if (retval < 0) { /* Out of memory or invalid name */ switch(retval) { case YK_NOMEM: return YK_NOMEM; break; case YK_INVALID: default: /* just skip it */ return 0; break; } } /* The new size of the packet */ newsize = size + retval + RRFIXEDSZ + rr->size; /* Check if there is enough space */ if (newsize > maxsize) { /* For additional sections just don't add the RR */ switch(section) { case NS_SECTION: case AR_SECTION: return 0; } } /* Allocate the memmory needed */ if ((tmp = realloc(*dest, newsize)) == NULL) return YK_NOMEM; *dest = tmp; /* add the name */ memcpy((*dest)+offset, encoded_name, retval); offset += retval; free(encoded_name); /* add qtype, qclass, ttl, rdlen and the rr */ tmp16 = htons(rr->qtype); memcpy((*dest)+offset, &tmp16, 2); offset += 2; tmp16 = htons(rr->qclass); memcpy((*dest)+offset, &tmp16, 2); offset += 2; tmp32 = htonl(rr->ttl); memcpy((*dest)+offset, &tmp32, 4); offset += 4; tmp16 = htons(rr->size); memcpy((*dest)+offset, &tmp16, 2); offset += 2; memcpy((*dest)+offset, rr->data, rr->size); offset += rr->size; switch(section) { case QD_SECTION: ((HEADER*)*dest)->qdcount = htons(ntohs(((HEADER*)*dest)->qdcount)+1); break; case AN_SECTION: ((HEADER*)*dest)->ancount = htons(ntohs(((HEADER*)*dest)->ancount)+1); break; case NS_SECTION: ((HEADER*)*dest)->nscount = htons(ntohs(((HEADER*)*dest)->nscount)+1); break; case AR_SECTION: ((HEADER*)*dest)->arcount = htons(ntohs(((HEADER*)*dest)->arcount)+1); break; default: yakuns_assert(0 == 1); /* unreached */ break; } return offset - size; }
uint32_t adv_data_encode(ble_advdata_t const * const p_advdata, uint8_t * const p_encoded_data, uint16_t * const p_len) { uint32_t err_code = NRF_SUCCESS; uint16_t max_size = *p_len; *p_len = 0; //Encode Security Manager OOB Flags if (p_advdata->p_sec_mgr_oob_flags != NULL) { err_code = sec_mgr_oob_flags_encode(*p_advdata->p_sec_mgr_oob_flags, p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode Security Manager TK value if (NULL != p_advdata->p_tk_value) { err_code = tk_value_encode(p_advdata->p_tk_value, p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode LE Role if (BLE_ADVDATA_ROLE_NOT_PRESENT != p_advdata->le_role) { err_code = le_role_encode(p_advdata->le_role, p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode LE Bluetooth Device Address if (p_advdata->include_ble_device_addr) { err_code = ble_device_addr_encode(p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode appearance. if (p_advdata->include_appearance) { err_code = appearance_encode(p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } //Encode Flags if(p_advdata->flags != 0 ) { err_code = flags_encode(p_advdata->flags, p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode TX power level. if (p_advdata->p_tx_power_level != NULL) { err_code = tx_power_level_encode(*p_advdata->p_tx_power_level, p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode 'more available' uuid list. if (p_advdata->uuids_more_available.uuid_cnt > 0) { err_code = uuid_list_encode(&p_advdata->uuids_more_available, BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE, BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE, p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode 'complete' uuid list. if (p_advdata->uuids_complete.uuid_cnt > 0) { err_code = uuid_list_encode(&p_advdata->uuids_complete, BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE, p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode 'solicited service' uuid list. if (p_advdata->uuids_solicited.uuid_cnt > 0) { err_code = uuid_list_encode(&p_advdata->uuids_solicited, BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT, BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT, p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode Slave Connection Interval Range. if (p_advdata->p_slave_conn_int != NULL) { err_code = conn_int_encode(p_advdata->p_slave_conn_int, p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode Manufacturer Specific Data. if (p_advdata->p_manuf_specific_data != NULL) { err_code = manuf_specific_data_encode(p_advdata->p_manuf_specific_data, p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode Service Data. if (p_advdata->service_data_count > 0) { err_code = service_data_encode(p_advdata, p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } // Encode name. WARNING: it is encoded last on purpose since too long device name is truncated. if (p_advdata->name_type != BLE_ADVDATA_NO_NAME) { err_code = name_encode(p_advdata, p_encoded_data, p_len, max_size); if (err_code != NRF_SUCCESS) { return err_code; } } return err_code; }