uint16_t read_os(void *dst, uint16_t length, const char *ignore_string){
	uint16_t counter = 0;
	uint16_t c;
	uint8_t v, tmp = 0, idx = 0;
	if(!ignore_string){
		ignore_string = block_ignore_string;
	}
	while(counter < length){
		c = cli_getc();
		if(c > 0xff){
			return counter;
		}
		if(strchr(ignore_string, c)){
			continue;
		}
		v = convert_nibble(c);
		if(v > 0x0f){
			return counter;
		}
		if(idx){
			((uint8_t*)dst)[counter++] = (tmp << 4) | v;
			idx = 0;
			if(counter % (BUFFER_LIMIT/2) == 0){
				cli_putc('.');
			}
		}else{
			tmp = v;
			idx = 1;
		}
	}
	return counter;
}
xed_int64_t xed_atoi_hex(char* buf) {
    xed_int64_t o=0;
    xed_uint_t i;
    xed_uint_t len = XED_STATIC_CAST(xed_uint_t,strlen(buf));
    for(i=0; i<len ; i++) 
        o = o*16 + convert_nibble(buf[i]);
    return o;
}
uip_ipaddr_t * coap_getIpFromURI(const char * uri)
{
    char * ipStart = NULL;
    char * ipEnd = NULL;
    static uip_ipaddr_t ipaddr;

    memset(&ipaddr, 0, sizeof(uip_ipaddr_t));

    ipStart = strchr(uri, '[') + 1;

    if(ipStart != NULL)
    {
        ipEnd = strchr(ipStart, ']');
        if(ipEnd != NULL)
        {
            int ipLen = ipEnd - ipStart;
            char * str = ipStart;
            int colonCount;

            //Count colons
            for (colonCount = 0; ipEnd != &str[colonCount]; str[colonCount] == ':' ? colonCount++ : *str++);

            if(colonCount < 8)
            {
                int currentWord = 0;
                int currentNibble = strchr(ipStart, ':') - (ipStart+1);
                bool jump = false;
                int i;

                if((currentNibble > 3) || (currentNibble < 0))
                {
                    i = ipLen;
                }
                else
                {
                    i = 0;
                }

                for(; i < ipLen; i++)
                {
                    if(ipStart[i] == ':')
                    {
                        if(ipStart[i+1] == ':')
                        {
                            if(!jump)
                            {
                                currentWord += (8 - colonCount);
                                i++;
                                jump = true;
                            }
                            else
                            {
                                break;
                            }
                        }

                        currentWord++;
                        if(currentWord < 7)
                        {
                            currentNibble =  strchr(&ipStart[i]+1, ':') - (&ipStart[i]+2);
                        }
                        else
                        {
                            currentNibble = ipEnd - (&ipStart[i]+2);
                        }

                        if((currentNibble > 3) || (currentNibble < 0))
                        {
                            break;
                        }
                    }
                    else
                    {
                        if(currentNibble >= 0)
                        {
                            uint8_t nibble;
                            if(convert_nibble((uint8_t)ipStart[i], &nibble) != -1)
                            {
                                ipaddr.u16[currentWord] += nibble << (currentNibble*4);

                                if(currentNibble == 0)
                                {
                                    ipaddr.u16[currentWord] = uip_htons(ipaddr.u16[currentWord]);
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                        currentNibble--;
                    }

                }
            }
        }
    }

    return &ipaddr;
}