1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 #if defined(__ANDROID__) || defined(__linux__) || defined(__APPLE__)
29 #if defined(__linux__) || defined(__APPLE__)
30 #include <uuid/uuid.h>
36 uint8_t GetRandomBitRaw() {
37 return analogRead((uint8_t)ANALOG_IN) & 0x1;
40 uint8_t GetRandomBitRaw2() {
43 a = GetRandomBitRaw() | (GetRandomBitRaw()<<1);
45 return 0; // 1 to 0 transition: log a zero bit
48 return 1;// 0 to 1 transition: log a one bit
50 // For other cases, try again.
54 uint8_t GetRandomBit() {
57 a = GetRandomBitRaw2() | (GetRandomBitRaw2()<<1);
59 return 0; // 1 to 0 transition: log a zero bit
62 return 1;// 0 to 1 transition: log a one bit
64 // For other cases, try again.
69 int8_t OCSeedRandom() {
70 #if defined(__ANDROID__) || defined(__linux__) || defined(__APPLE__)
71 int32_t fd = open("/dev/urandom", O_RDONLY);
74 uint32_t totalRead = 0; //how many integers were read
75 int32_t currentRead = 0;
76 while (totalRead < sizeof(randomSeed)) {
77 currentRead = read(fd, (uint8_t*) &randomSeed + totalRead,
78 sizeof(randomSeed) - totalRead);
80 totalRead += currentRead;
93 result += result + GetRandomBit();
101 void OCFillRandomMem(uint8_t * location, uint16_t len) {
106 *location++ = OCGetRandomByte();
110 uint32_t OCGetRandom() {
112 OCFillRandomMem((uint8_t*) &result, 4);
116 uint8_t OCGetRandomByte(void) {
117 #if defined(__ANDROID__) || defined(__linux__) || defined(__APPLE__)
118 return rand() & 0x00FF;
119 #elif defined ARDUINO
120 return random(256) & 0x00FF;
124 uint32_t OCGetRandomRange(uint32_t firstBound, uint32_t secondBound){
128 if(firstBound > secondBound){
130 diff = firstBound - secondBound;
131 }else if(firstBound < secondBound){
133 diff = secondBound - firstBound;
137 result = ((float)OCGetRandom()/((float)(0xFFFFFFFF))*(float)diff) + (float) base;
141 #if defined(__ANDROID__)
142 uint8_t parseUuidChar(char c)
153 uint8_t parseUuidPart(const char *c)
155 return (parseUuidChar(c[0])<<4) + parseUuidChar(c[1]);
159 OCRandomUuidResult OCGenerateUuid(uint8_t uuid[UUID_SIZE])
163 return RAND_UUID_INVALID_PARAM;
165 #if defined(__linux__) || defined(__APPLE__)
166 // note: uuid_t is typedefed as unsigned char[16] on linux/apple
169 #elif defined(__ANDROID__)
170 char uuidString[UUID_STRING_SIZE];
171 int8_t ret = OCGenerateUuidString(uuidString);
178 uuid[ 0] = parseUuidPart(&uuidString[0]);
179 uuid[ 1] = parseUuidPart(&uuidString[2]);
180 uuid[ 2] = parseUuidPart(&uuidString[4]);
181 uuid[ 3] = parseUuidPart(&uuidString[6]);
183 uuid[ 4] = parseUuidPart(&uuidString[9]);
184 uuid[ 5] = parseUuidPart(&uuidString[11]);
186 uuid[ 6] = parseUuidPart(&uuidString[14]);
187 uuid[ 7] = parseUuidPart(&uuidString[16]);
189 uuid[ 8] = parseUuidPart(&uuidString[19]);
190 uuid[ 9] = parseUuidPart(&uuidString[21]);
192 uuid[10] = parseUuidPart(&uuidString[24]);
193 uuid[11] = parseUuidPart(&uuidString[26]);
194 uuid[12] = parseUuidPart(&uuidString[28]);
195 uuid[13] = parseUuidPart(&uuidString[30]);
196 uuid[14] = parseUuidPart(&uuidString[32]);
197 uuid[15] = parseUuidPart(&uuidString[34]);
201 // Fallback for all platforms is filling the array with random data
202 OCFillRandomMem(uuid, UUID_SIZE);
207 OCRandomUuidResult OCGenerateUuidString(char uuidString[UUID_STRING_SIZE])
211 return RAND_UUID_INVALID_PARAM;
213 #if defined(__linux__) || defined(__APPLE__)
214 uint8_t uuid[UUID_SIZE];
215 int8_t ret = OCGenerateUuid(uuid);
222 uuid_unparse_lower(uuid, uuidString);
225 #elif defined(__ANDROID__)
226 int32_t fd = open("/proc/sys/kernel/random/uuid", O_RDONLY);
229 ssize_t readResult = read(fd, uuidString, UUID_STRING_SIZE - 1);
233 return RAND_UUID_READ_ERROR;
235 else if(readResult < UUID_STRING_SIZE - 1)
237 uuidString[0] = '\0';
238 return RAND_UUID_READ_ERROR;
241 uuidString[UUID_STRING_SIZE - 1] = '\0';
242 for(char* p = uuidString; *p; ++p)
251 return RAND_UUID_READ_ERROR;
254 uint8_t uuid[UUID_SIZE];
255 OCGenerateUuid(uuid);
257 return OCConvertUuidToString(uuid, uuidString);
261 OCRandomUuidResult OCConvertUuidToString(const uint8_t uuid[UUID_SIZE],
262 char uuidString[UUID_STRING_SIZE])
264 if (uuid == NULL || uuidString == NULL)
266 return RAND_UUID_INVALID_PARAM;
270 int ret = snprintf(uuidString, UUID_STRING_SIZE,
271 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
272 uuid[0], uuid[1], uuid[2], uuid[3],
273 uuid[4], uuid[5], uuid[6], uuid[7],
274 uuid[8], uuid[9], uuid[10], uuid[11],
275 uuid[12], uuid[13], uuid[14], uuid[15]
278 if (ret != UUID_STRING_SIZE - 1)
280 return RAND_UUID_CONVERT_ERROR;