From cddcc5e6b3d63e42ded5bca4a3e5e7972cb2e216 Mon Sep 17 00:00:00 2001 From: nadiramra Date: Sun, 30 May 2010 20:43:13 +0000 Subject: AXIS2C-1478 Changes due to port to IBM i (aka OS/400). git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@949568 13f79535-47bb-0310-9956-ffa450edef68 --- util/src/platforms/os400/uuid_gen_os400.c | 244 ++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 util/src/platforms/os400/uuid_gen_os400.c (limited to 'util/src/platforms/os400/uuid_gen_os400.c') diff --git a/util/src/platforms/os400/uuid_gen_os400.c b/util/src/platforms/os400/uuid_gen_os400.c new file mode 100644 index 0000000..6c40a82 --- /dev/null +++ b/util/src/platforms/os400/uuid_gen_os400.c @@ -0,0 +1,244 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +# include + +#include "platforms/os400/axutil_uuid_gen_os400.h" +#include "platforms/axutil_platform_auto_sense.h" + +/* We need these static variables to track throughout the program execution */ +static axis2_bool_t axutil_uuid_gen_is_first = AXIS2_TRUE; +static struct axutil_uuid_st axutil_uuid_static; + +axutil_uuid_t *AXIS2_CALL +axutil_uuid_gen_v1() +{ + struct timeval time_now; + struct timeval tv; + unsigned long long time_val; + unsigned long long time_val2; + unsigned short int clck = 0; + axutil_uuid_t *ret_uuid = NULL; + unsigned short int time_high_version = 0; + + if (AXIS2_TRUE == axutil_uuid_gen_is_first) + { + char *mac_addr = axutil_uuid_get_mac_addr(); + memcpy(axutil_uuid_static.mac, mac_addr, 6); + axutil_uuid_static.time_seq = 0; + axutil_uuid_static.clock = 0; + free(mac_addr); + axutil_uuid_gen_is_first = AXIS2_FALSE; + } + /* + * GENERATE TIME + */ + + /* determine current system time and sequence counter */ + if (gettimeofday(&time_now, NULL) == -1) + return NULL; + + /* check whether system time changed since last retrieve */ + if(!(time_now.tv_sec == axutil_uuid_static.time_last.tv_sec && time_now.tv_usec + == axutil_uuid_static.time_last.tv_usec)) + { + /* reset time sequence counter and continue */ + axutil_uuid_static.time_seq = 0; + } + + /* until we are out of UUIDs per tick, increment + the time/tick sequence counter and continue */ + while (axutil_uuid_static.time_seq < UUIDS_PER_TICK) + { + axutil_uuid_static.time_seq++; + } + /* sleep for 1000ns (1us) */ + tv.tv_sec = 0; + tv.tv_usec = 1; + /* + The following select causes severe performance problems. + Hence commenting out. I am not sure why this is required. - Samisa. + select(0, NULL, NULL, NULL, &tv); */ + + time_val = (unsigned long long) time_now.tv_sec * 10000000ull; + time_val += (unsigned long long) time_now.tv_usec * 10ull; + + ret_uuid = malloc(sizeof(axutil_uuid_t)); + + time_val += UUID_TIMEOFFSET; + /* compensate for low resolution system clock by adding + the time/tick sequence counter */ + if (axutil_uuid_static.time_seq > 0) + time_val += (unsigned long long) axutil_uuid_static.time_seq; + + time_val2 = time_val; + ret_uuid->time_low = (unsigned long) time_val2; + time_val2 >>= 32; + ret_uuid->time_mid = (unsigned short int) time_val2; + time_val2 >>= 16; + time_high_version = (unsigned short int) time_val2; + + /* store the 60 LSB of the time in the UUID and make version 1 */ + time_high_version <<= 4; + time_high_version &= 0xFFF0; + time_high_version |= 0x0001; + ret_uuid->time_high_version = time_high_version; + + /* + * GENERATE CLOCK + */ + + /* retrieve current clock sequence */ + clck = axutil_uuid_static.clock; + + /* generate new random clock sequence (initially or if the + time has stepped backwards) or else just increase it */ + if(clck == 0 || (time_now.tv_sec < axutil_uuid_static.time_last.tv_sec || (time_now.tv_sec + == axutil_uuid_static.time_last.tv_sec && time_now.tv_usec + < axutil_uuid_static.time_last.tv_usec))) + { + srand(time_now.tv_usec); + clck = rand(); + } + else + { + clck++; + } + clck %= (2 << 14); + + /* store back new clock sequence */ + axutil_uuid_static.clock = clck; + + clck &= 0x1FFF; + clck |= 0x2000; + + /* + * FINISH + */ + /* remember current system time for next iteration */ + axutil_uuid_static.time_last.tv_sec = time_now.tv_sec; + axutil_uuid_static.time_last.tv_usec = time_now.tv_usec; + + if (!ret_uuid) + { + return NULL; + } + ret_uuid->clock_variant = clck; + memcpy(ret_uuid->mac_addr, axutil_uuid_static.mac, 6); + return ret_uuid; +} + +axis2_char_t *AXIS2_CALL +axutil_platform_uuid_gen( + char *s) +{ + axutil_uuid_t *uuid_struct = NULL; + axis2_char_t *uuid_str = NULL; + unsigned char mac[7]; + char mac_hex[13]; + + if (!s) + { + return NULL; + } + uuid_struct = axutil_uuid_gen_v1(); + if (!uuid_struct) + { + return NULL; + } + uuid_str = s; + if (!uuid_str) + { + return NULL; + } + memcpy(mac, uuid_struct->mac_addr, 6); + sprintf(mac_hex, "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + sprintf(uuid_str, "%08x-%04x-%04x-%04x-%s", uuid_struct->time_low, uuid_struct->time_mid, + uuid_struct->time_high_version, uuid_struct->clock_variant, mac_hex); + free(uuid_struct); + uuid_struct = NULL; + return uuid_str; +} + +char *AXIS2_CALL +axutil_uuid_get_mac_addr( + ) +{ + struct ifreq ifr; + struct ifreq *IFR; + struct ifconf ifc; + struct sockaddr *sa; + int s = 0; + int i = 0; + char *buffer = NULL; + char buf[1024]; + int ok = AXIS2_FALSE; + + if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) + return NULL; + + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + ioctl(s, SIOCGIFCONF, &ifc); + IFR = ifc.ifc_req; + + for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; IFR++) + { + strcpy(ifr.ifr_name, IFR->ifr_name); + /*sprintf(ifr.ifr_name, "eth0"); */ + if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) + { + if (!(ifr.ifr_flags & IFF_LOOPBACK)) + { + +// TODO-AMRA if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0) + { + ok = AXIS2_TRUE; + break; + } + } + } + } + buffer = (char *) malloc(6 * sizeof(char)); + if (ok) + { + sa = (struct sockaddr *) &ifr.ifr_addr; + for (i = 0; i < 6; i++) + buffer[i] = (unsigned char) (sa->sa_data[i] & 0xff); + } + else + { + for (i = 0; i < 6; i++) + buffer[i] = (unsigned char) ((AXIS2_LOCAL_MAC_ADDR[i]) - '0'); + } + close(s); + return buffer; +} + -- cgit v1.1-32-gdbae