/**@brief Function for adding/updating IPv6 address in table. * * @param[in] interface_id Index of interface. * @param[in] p_addr Given address. * * @return NRF_SUCCESS if operation successful, NRF_ERROR_NO_MEM otherwise. */ static uint32_t addr_set(const iot_interface_t * p_interface, const ipv6_addr_conf_t * p_addr) { uint32_t index; uint32_t addr_index; uint32_t err_code; uint32_t interface_id = (uint32_t)p_interface->p_upper_stack; // Try to find address. err_code = addr_find(&p_addr->addr, &addr_index); if (err_code != NRF_SUCCESS) { // Find first empty one. err_code = addr_find_free(&addr_index); } if (err_code == NRF_SUCCESS) { err_code = IOT_IPV6_ERR_ADDR_IF_MISMATCH; // Check if this index entry exists in the p_interface for which API is requested. for (index = 0; index < IPV6_MAX_ADDRESS_PER_INTERFACE; index++) { if (m_interfaces[interface_id].addr_range[index] == addr_index) { m_address_table[index].state = p_addr->state; err_code = NRF_SUCCESS; break; } } if (err_code == IOT_IPV6_ERR_ADDR_IF_MISMATCH) { err_code = (IOT_IPV6_ERR_BASE | NRF_ERROR_NO_MEM); for (index = 0; index < IPV6_MAX_ADDRESS_PER_INTERFACE; index++) { if (m_interfaces[interface_id].addr_range[index] == IPV6_INVALID_ADDR_INDEX) { m_address_table[index].state = p_addr->state; memcpy(&m_address_table[index].addr, p_addr, IPV6_ADDR_SIZE); m_interfaces[interface_id].addr_range[index] = addr_index; err_code = NRF_SUCCESS; break; } } } } return err_code; }
void myfree(void* addr) { size_t i = MEM_SIZ_LARGE; node_t* prev = NULL; node_t* pn = NULL; if (addr_find(addr, &prev, &pn, &i)) { if (i != MEM_SIZ_LARGE) { node_t* free = get_free_node(); node_t* used = get_free_node(); used->len = pn->len - ((size_t)addr - (size_t)pn->addr) - indsiz[i]; pn->len = (size_t)addr - (size_t)pn->addr; used->next = pn->next; free->next = used; pn->next = free; free->addr = addr; free->len = indsiz[i]; free->stat = MEM_STAT_FREE; used->addr = (void*)((size_t)free->addr + indsiz[i]); used->stat = MEM_STAT_USED; if (pn->len == 0) { if (prev) { prev->next = pn->next; pn->next = heap->free_node; heap->free_node = pn; } else { heap->index[i] = pn->next; pn->next = heap->free_node; heap->free_node = pn; } } if (used->len == 0) { free->next = used->next; used->next = heap->free_node; heap->free_node = used; } merge(heap->index[i]); } else if(prev) { prev->next = pn->next; sys_free(pn->addr, pn->len); pn->next = heap->free_node; heap->free_node = pn; } else { heap->index[MEM_SIZ_LARGE] = pn->next; sys_free(pn->addr, pn->len); pn->next = heap->free_node; heap->free_node = pn; } } else { fprintf(stderr, "illegal free: %16zx\n", addr); } }
void* myrealloc(void* addr, size_t len) { size_t i1 = ind(len); size_t i2 = MEM_SIZ_LARGE; node_t* prev = NULL; node_t* pn = NULL; if (addr_find(addr, &prev, &pn, &i2)) { if (i2 != MEM_SIZ_LARGE) { if (i1 == i2) { return addr; } else { void* ret = myalloc(len); memcpy(ret, addr, (pn->len < len) ? pn->len : len); myfree(addr); return ret; } } else { if (i1 == i2) { ALIGN4096(len); if (len <= pn->len) { return pn->addr; } else { size_t delta = len - pn->len; void* p = sys_try_alloc((void*)((size_t)pn->addr + pn->len), delta); if (p) { pn->len = len; return pn->addr; } else { void* src = pn->addr; pn->addr = sys_alloc(NULL, len); memcpy(pn->addr, src, pn->len); sys_free(src, pn->len); pn->len = len; return pn->addr; } } } else { void* ret = myalloc(len); memcpy(ret, addr, len); myfree(addr); return ret; } } } return NULL; }