1284990Scy#include <config.h> 2284990Scy 3284990Scy#include <ntp.h> 4284990Scy#include <ntp_fp.h> 5293650Sglebius#include <ntp_assert.h> 6284990Scy 7284990Scy/* 8284990Scy * we want to test a refid format of: 9284990Scy * 254.x.y.x 10284990Scy * 11284990Scy * where x.y.z are 24 bits containing 2 (signed) integer bits 12284990Scy * and 22 fractional bits. 13284990Scy * 14284990Scy * we want functions to convert to/from this format, with unit tests. 15284990Scy * 16284990Scy * Interesting test cases include: 17284990Scy * 254.0.0.0 18284990Scy * 254.0.0.1 19284990Scy * 254.127.255.255 20284990Scy * 254.128.0.0 21284990Scy * 254.255.255.255 22284990Scy */ 23284990Scy 24284990Scychar *progname = ""; 25284990Scy 26284990Scyl_fp convertRefIDToLFP(uint32_t r); 27284990Scyuint32_t convertLFPToRefID(l_fp num); 28284990Scy 29284990Scy 30284990Scy/* 31284990Scy * The smear data in the refid is the bottom 3 bytes of the refid, 32284990Scy * 2 bits of integer 33284990Scy * 22 bits of fraction 34284990Scy */ 35284990Scyl_fp 36284990ScyconvertRefIDToLFP(uint32_t r) 37284990Scy{ 38284990Scy l_fp temp; 39284990Scy 40284990Scy r = ntohl(r); 41284990Scy 42284990Scy printf("%03d %08x: ", (r >> 24) & 0xFF, (r & 0x00FFFFFF) ); 43284990Scy 44284990Scy temp.l_uf = (r << 10); /* 22 fractional bits */ 45284990Scy 46284990Scy temp.l_ui = (r >> 22) & 0x3; 47284990Scy temp.l_ui |= ~(temp.l_ui & 2) + 1; 48284990Scy 49284990Scy return temp; 50284990Scy} 51284990Scy 52284990Scy 53284990Scyuint32_t 54284990ScyconvertLFPToRefID(l_fp num) 55284990Scy{ 56284990Scy uint32_t temp; 57284990Scy 58284990Scy /* round the input with the highest bit to shift out from the 59284990Scy * fraction, then keep just two bits from the integral part. 60284990Scy * 61284990Scy * TODO: check for overflows; should we clamp/saturate or just 62284990Scy * complain? 63284990Scy */ 64284990Scy L_ADDUF(&num, 0x200); 65284990Scy num.l_ui &= 3; 66284990Scy 67284990Scy /* combine integral and fractional part to 24 bits */ 68284990Scy temp = (num.l_ui << 22) | (num.l_uf >> 10); 69284990Scy 70284990Scy /* put in the leading 254.0.0.0 */ 71284990Scy temp |= UINT32_C(0xFE000000); 72284990Scy 73284990Scy printf("%03d %08x: ", (temp >> 24) & 0xFF, (temp & 0x00FFFFFF) ); 74284990Scy 75284990Scy return htonl(temp); 76284990Scy} 77284990Scy 78284990Scy/* Tests start here */ 79284990Scy 80284990Scyvoid rtol(uint32_t r); 81284990Scy 82284990Scyvoid 83284990Scyrtol(uint32_t r) 84284990Scy{ 85284990Scy l_fp l; 86284990Scy 87284990Scy printf("rtol: "); 88284990Scy 89284990Scy l = convertRefIDToLFP(htonl(r)); 90284990Scy printf("refid %#x, smear %s\n", r, lfptoa(&l, 8)); 91284990Scy 92284990Scy return; 93284990Scy} 94284990Scy 95284990Scy 96284990Scyvoid rtoltor(uint32_t r); 97284990Scy 98284990Scyvoid 99284990Scyrtoltor(uint32_t r) 100284990Scy{ 101284990Scy l_fp l; 102284990Scy 103284990Scy printf("rtoltor: "); 104284990Scy l = convertRefIDToLFP(htonl(r)); 105284990Scy 106284990Scy r = convertLFPToRefID(l); 107284990Scy printf("smear %s, refid %#.8x\n", lfptoa(&l, 8), ntohl(r)); 108284990Scy 109284990Scy return; 110284990Scy} 111284990Scy 112284990Scy 113284990Scyvoid ltor(l_fp l); 114284990Scy 115284990Scyvoid 116284990Scyltor(l_fp l) 117284990Scy{ 118284990Scy uint32_t r; 119284990Scy 120284990Scy printf("ltor: "); 121284990Scy 122284990Scy r = convertLFPToRefID(l); 123284990Scy printf("smear %s, refid %#.8x\n", lfptoa(&l, 8), ntohl(r)); 124284990Scy 125284990Scy return; 126284990Scy} 127284990Scy 128284990Scy 129293650Sglebiusint 130284990Scymain() 131284990Scy{ 132289997Sglebius l_fp l; 133289997Sglebius int rc; 134284990Scy 135293650Sglebius init_lib(); 136293650Sglebius 137284990Scy rtol(0xfe800000); 138284990Scy rtol(0xfe800001); 139284990Scy rtol(0xfe8ffffe); 140284990Scy rtol(0xfe8fffff); 141284990Scy rtol(0xfef00000); 142284990Scy rtol(0xfef00001); 143284990Scy rtol(0xfefffffe); 144284990Scy rtol(0xfeffffff); 145284990Scy 146284990Scy rtol(0xfe000000); 147284990Scy rtol(0xfe000001); 148284990Scy rtol(0xfe6ffffe); 149284990Scy rtol(0xfe6fffff); 150284990Scy rtol(0xfe700000); 151284990Scy rtol(0xfe700001); 152284990Scy rtol(0xfe7ffffe); 153284990Scy rtol(0xfe7fffff); 154284990Scy 155284990Scy rtoltor(0xfe800000); 156284990Scy rtoltor(0xfe800001); 157284990Scy rtoltor(0xfe8ffffe); 158284990Scy rtoltor(0xfe8fffff); 159284990Scy rtoltor(0xfef00000); 160284990Scy rtoltor(0xfef00001); 161284990Scy rtoltor(0xfefffffe); 162284990Scy rtoltor(0xfeffffff); 163284990Scy 164284990Scy rtoltor(0xfe000000); 165284990Scy rtoltor(0xfe000001); 166284990Scy rtoltor(0xfe6ffffe); 167284990Scy rtoltor(0xfe6fffff); 168284990Scy rtoltor(0xfe700000); 169284990Scy rtoltor(0xfe700001); 170284990Scy rtoltor(0xfe7ffffe); 171284990Scy rtoltor(0xfe7fffff); 172284990Scy 173289997Sglebius rc = atolfp("-.932087", &l); 174293650Sglebius INSIST(1 == rc); 175293650Sglebius 176289997Sglebius ltor(l); 177289997Sglebius rtol(0xfec458b0); 178289997Sglebius printf("%x -> %d.%d.%d.%d\n", 179289997Sglebius 0xfec458b0, 180289997Sglebius 0xfe, 181289997Sglebius 0xc4, 182289997Sglebius 0x58, 183289997Sglebius 0xb0); 184289997Sglebius 185284990Scy return 0; 186284990Scy} 187