text: /*
   * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The OpenAirInterface Software Alliance licenses this file to You under
   * the OAI Public License, Version 1.1  (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.openairinterface.org/?page_id=698
   *
   * 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.
   *-------------------------------------------------------------------------------
   * For more information about the OpenAirInterface (OAI) Software Alliance:
   *      contact@openairinterface.org
   */
  
  /*! \file conversions.cpp
    \brief
    \author Sebastien ROUX
    \company Eurecom
  */
  #include "conversions.hpp"
  
  #include <arpa/inet.h>
  #include <ctype.h>
  #include <inttypes.h>
  #include <stdbool.h>
  #include <stdint.h>
  #include <stdlib.h>
  
  static const char hex_to_ascii_table[16] = {
      '0', '1', '2', '3', '4', '5', '6', '7',
      '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
  };
  
  static const signed char ascii_to_hex_table[0x100] = {
      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0,  1,  2,  3,  4,  5,  6,  7,  8,
      9,  -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      -1, -1, -1, -1, -1, -1, -1, -1, -1};
  
  void conv::hexa_to_ascii(uint8_t *from, char *to, size_t length) {
    size_t i;
  
    for (i = 0; i < length; i++) {
      uint8_t upper = (from[i] & 0xf0) >> 4;
      uint8_t lower = from[i] & 0x0f;
  
      to[2 * i] = hex_to_ascii_table[upper];
      to[2 * i + 1] = hex_to_ascii_table[lower];
    }
  }
  
  int conv::ascii_to_hex(uint8_t *dst, const char *h) {
    const unsigned char *hex = (const unsigned char *)h;
    unsigned i = 0;
  
    for (;;) {
      int high, low;
  
      while (*hex && isspace(*hex)) hex++;
  
      if (!*hex) return 1;
  
      high = ascii_to_hex_table[*hex++];
  
      if (high < 0) return 0;
  
      while (*hex && isspace(*hex)) hex++;
  
      if (!*hex) return 0;
  
      low = ascii_to_hex_table[*hex++];
  
      if (low < 0) return 0;
  
      dst[i++] = (high << 4) | low;
    }
  }
  
  //------------------------------------------------------------------------------
  std::string conv::mccToString(const uint8_t digit1, const uint8_t digit2,
                                const uint8_t digit3) {
    std::string s = {};
    uint16_t mcc16 = digit1 * 100 + digit2 * 10 + digit3;
    // s.append(std::to_string(digit1)).append(std::to_string(digit2)).append(std::to_string(digit3));
    s.append(std::to_string(mcc16));
    return s;
  }
  //------------------------------------------------------------------------------
  std::string conv::mncToString(const uint8_t digit1, const uint8_t digit2,
                                const uint8_t digit3) {
    std::string s = {};
    uint16_t mcc16 = 0;
  
    if (digit3 == 0x0F) {
      mcc16 = digit1 * 10 + digit2;
    } else {
      mcc16 = digit1 * 100 + digit2 * 10 + digit3;
    }
    s.append(std::to_string(mcc16));
    return s;
  }
  
  //------------------------------------------------------------------------------
  struct in_addr conv::fromString(const std::string addr4) {
    unsigned char buf[sizeof(struct in6_addr)] = {};
    int s = inet_pton(AF_INET, addr4.c_str(), buf);
    struct in_addr *ia = (struct in_addr *)buf;
    return *ia;
  }
  //------------------------------------------------------------------------------
  std::string conv::toString(const struct in_addr &inaddr) {
    std::string s = {};
    char str[INET6_ADDRSTRLEN] = {};
    if (inet_ntop(AF_INET, (const void *)&inaddr, str, INET6_ADDRSTRLEN) ==
        NULL) {
      s.append("Error in_addr");
    } else {
      s.append(str);
    }
    return s;
  }
  //------------------------------------------------------------------------------
  std::string conv::toString(const struct in6_addr &in6addr) {
    std::string s = {};
    char str[INET6_ADDRSTRLEN] = {};
    if (inet_ntop(AF_INET6, (const void *)&in6addr, str, INET6_ADDRSTRLEN) ==
        nullptr) {
      s.append("Error in6_addr");
    } else {
      s.append(str);
    }
    return s;
  }
  