* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fhi_lib / app / src / aux_cline.c
diff --git a/fhi_lib/app/src/aux_cline.c b/fhi_lib/app/src/aux_cline.c
new file mode 100644 (file)
index 0000000..071a6df
--- /dev/null
@@ -0,0 +1,743 @@
+/******************************************************************************
+*
+*   Copyright (c) 2020 Intel.
+*
+*   Licensed 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.
+*
+*******************************************************************************/
+
+/**
+ * @brief This file has utilities to parse the parameters passed in through the command
+ *        line and configure the application based on these parameters
+ * @file aux_cline.c
+ * @ingroup xran
+ * @author Intel Corporation
+ **/
+
+
+#include "aux_cline.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+
+
+typedef struct _CLINE_KEY_TABLE_
+{
+    char *name;
+    char *value;
+} CLINE_KEY_TABLE;
+
+
+#define CLINE_MAXKEYS               (256)
+#define CLINE_MAX_STRING_LENGTH     (128)
+#define CLINE_MAXKEYSIZE            (2048)
+
+static CLINE_KEY_TABLE PhyAppKeys[CLINE_MAXKEYS];
+static uint32_t pPhyCfgNumEntries = 0;
+
+
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_source_auxlib_cline
+ *
+ *  @param   void
+ *
+ *  @return  0 if AUX_SUCCESS
+ *
+ *  @description
+ *  Initialize Cline Interface
+ *
+**/
+//-------------------------------------------------------------------------------------------
+int cline_init(void)
+{
+    uint32_t i;
+    pPhyCfgNumEntries = 0;
+    for (i = 0; i < CLINE_MAXKEYS; i++)
+    {
+       PhyAppKeys[i].name = NULL;
+       PhyAppKeys[i].value = NULL;
+    }
+
+    return AUX_SUCCESS;
+}
+
+
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_source_auxlib_cline
+ *
+ *  @param[in]   *name String to search for
+ *  @param[out]  *value Pointer to location where number needs to be stored
+ *  @param[in]   deflt Default value to put into the value field if string is not found
+ *
+ *  @return  0 if AUX_SUCCESS
+ *
+ *  @description
+ *  This funtion searchs for a string from the phycfg.xml file and returns the number that
+ *  was associated in file
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint32_t cline_set_int(const char *name, int *value, int deflt)
+{
+    uint32_t i;
+
+    for (i = 0; i < pPhyCfgNumEntries; i++)
+    {
+        if (PhyAppKeys[i].name)
+        {
+            if (strcasecmp(name, PhyAppKeys[i].name) == 0)
+            {
+                char *p1 = PhyAppKeys[i].value;
+                if (strstr(p1, "0x") || strstr(p1, "0X"))
+                {
+                    uint64_t core;
+                    if (cline_covert_hex_2_dec(p1, &core) != AUX_SUCCESS)
+                    {
+                        printf("cline_set_int Failed (%s)\n", p1);
+                        return AUX_FAILURE;
+                    }
+                    *value = (int)core;
+                }
+                else
+                {
+                    *value = (int)strtol(PhyAppKeys[i].value, NULL, 0);
+                    if ((*value == 0 && errno == EINVAL) || (*value == INT_MAX && errno == ERANGE))
+                    {
+                        *value = deflt;
+                        return AUX_FAILURE;
+                    }
+                }
+                break;
+            }
+        }
+        else
+        {
+            // End of list reached
+            *value = deflt;
+            printf("incomming setting in XML: param \"%s\" is not found!\n", name);
+            return AUX_FAILURE;
+        }
+    }
+
+    return AUX_SUCCESS;
+}
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_source_auxlib_cline
+ *
+ *  @param[in]   *name String to search for
+ *  @param[out]  *value Pointer to location where number needs to be stored
+ *  @param[in]   deflt Default value to put into the value field if string is not found
+ *
+ *  @return  0 if AUX_SUCCESS
+ *
+ *  @description
+ *  This funtion searchs for a string from the phycfg.xml file and returns the number that
+ *  was associated in file
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint32_t cline_set_uint64(const char *name, uint64_t *value, uint64_t deflt)
+{
+    uint32_t i;
+
+    for (i = 0; i < pPhyCfgNumEntries; i++)
+    {
+        if (PhyAppKeys[i].name)
+        {
+            if (strcasecmp(name, PhyAppKeys[i].name) == 0)
+            {
+                if (strstr(PhyAppKeys[i].value, "0x") || strstr(PhyAppKeys[i].value, "0X"))
+                {
+                    if (cline_covert_hex_2_dec(PhyAppKeys[i].value, value) != AUX_SUCCESS)
+                    {
+                        printf("cline_covert_hex_2_dec Failed (%s)\n", PhyAppKeys[i].value);
+                        return AUX_FAILURE;
+                    }
+                }
+                else
+                {
+                    *value = strtoull(PhyAppKeys[i].value, NULL, 0);
+                }
+                if ((*value == 0 && errno == EINVAL) || (*value == LONG_MAX && errno == ERANGE))
+                {
+                    *value = deflt;
+                    return AUX_FAILURE;
+                }
+                break;
+            }
+        }
+        else
+        {
+            // End of list reached
+            *value = deflt;
+            printf("incomming setting in XML: param \"%s\" is not found!\n", name);
+            return AUX_FAILURE;
+        }
+    }
+
+    return AUX_SUCCESS;
+}
+
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_source_auxlib_cline
+ *
+ *  @param[in]   *pStr String to search for
+ *  @param[out]  *pDst Pointer to location where number needs to be stored
+ *
+ *  @return  0 if AUX_SUCCESS
+ *
+ *  @description
+ *  This funtion takes a char string as input and converts it to a unit61_t
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint32_t cline_covert_hex_2_dec(char *pStr, uint64_t *pDst)
+{
+    char nibble;
+    int32_t i;
+    uint32_t len;
+    uint64_t value = 0, mult = 1, nibble_val = 0;
+
+    // Skip over "0x"
+    pStr += 2;
+
+    len = strlen(pStr);
+    if (len > 16)
+    {
+        printf("String Length is invalid: %p [%d]\n", pStr, len);
+    }
+
+    for (i = len - 1; i >= 0; i--)
+    {
+        nibble = pStr[i];
+        if ((nibble >= '0') && (nibble <= '9'))
+        {
+            nibble_val = nibble - '0';
+        }
+        else if ((nibble >= 'A') && (nibble <= 'F'))
+        {
+            nibble_val = nibble - 'A' + 10;
+        }
+        else if ((nibble >= 'a') && (nibble <= 'f'))
+        {
+            nibble_val = nibble - 'a' + 10;
+        }
+        else
+        {
+            printf("String is invalid: %p[%d] %c\n", pStr, i, nibble);
+            return AUX_FAILURE;
+        }
+
+        value += (nibble_val * mult);
+
+        mult = mult * 16;
+    }
+
+    *pDst = value;
+
+    return AUX_SUCCESS;
+}
+
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_source_auxlib_cline
+ *
+ *  @param[in]   *name String to search for
+ *  @param[out]  *core Pointer to location where core id needs to be stored
+ *  @param[out]  *priority Pointer to location where priority needs to be stored
+ *  @param[out]  *policy Pointer to location where policy needs to be stored
+ *
+ *  @return  0 if AUX_SUCCESS
+ *
+ *  @description
+ *  This funtion searchs for a string from the phycfg.xml file stores all thread related info into
+ *  output locations
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint32_t cline_set_thread_info(const char *name, uint64_t *core, int *priority, int *policy)
+{
+#ifndef TEST_APP
+    uint32_t i;
+    int sched;
+    char *p1, *p2, *p3;
+
+    for (i = 0; i < pPhyCfgNumEntries; i++)
+    {
+        if (PhyAppKeys[i].name)
+        {
+            if (strcasecmp(name, PhyAppKeys[i].name) == 0)
+            {
+                p1 = (char*)PhyAppKeys[i].value;
+                p2 = strstr(p1, ",");
+                if (p2)
+                {
+                    *p2 = '\0';
+                    p2++;
+                    p3 = strstr(p2, ",");
+                    if (p3)
+                    {
+                        *p3 = '\0';
+                        p3++;
+
+                        if (strstr(p1, "0x") || strstr(p1, "0X"))
+                        {
+                            if (cline_covert_hex_2_dec(p1, core) != AUX_SUCCESS)
+                            {
+                                printf("cline_covert_hex_2_dec Failed (%s)\n", p1);
+                                return AUX_FAILURE;
+                            }
+                        }
+                        else
+                        {
+                            *core = strtoull(p1, NULL, 0);
+                        }
+                        *priority = strtol(p2, NULL, 0);
+                        sched = strtol(p3, NULL, 0);
+
+                        *policy = (sched ? SCHED_RR : SCHED_FIFO);
+
+                        //print_info_log("%s %ld %d %d\n", name, *core, *priority, *policy);
+
+                        return AUX_SUCCESS;
+                    }
+                    else
+                    {
+                        printf("p3 is null %s\n", p2);
+                    }
+                }
+                else
+                {
+                    printf("p2 is null %s\n", p1);
+                }
+
+                printf("%s FAIL1\n", name);
+                return AUX_FAILURE;
+            }
+        }
+        else
+        {
+            // End of list reached
+            printf("incomming setting in XML: param \"%s\" is not found!\n", name);
+
+            printf("cline_set_thread_info: %s FAIL2\n", name);
+            return AUX_FAILURE;
+        }
+    }
+
+    printf("cline_set_thread_info: %s FAIL3\n", name);
+    return AUX_FAILURE;
+#else
+    return AUX_SUCCESS;
+#endif
+}
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_source_auxlib_cline
+ *
+ *  @param[in]   *name String to search for
+ *  @param[in]   maxLen Max lenth of output array
+ *  @param[out]  *dataOut Pointer to the data array filled by each int element of the input string
+ *  @param[out]  *outLen Filled length of the array
+ *
+ *  @return  0 if AUX_SUCCESS
+ *
+ *  @description
+ *  This funtion searchs for a string from the phycfg.xml file stores all int value to output array
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint32_t cline_set_int_array(const char *name, int maxLen, int *dataOut, int *outLen)
+{
+    uint32_t i;
+    char *p1, *p2;
+    *outLen = 0;
+
+    for (i = 0; i < pPhyCfgNumEntries; i++)
+    {
+        if (PhyAppKeys[i].name)
+        {
+            if (strcasecmp(name, PhyAppKeys[i].name) == 0)
+            {
+                p1 = (char*)PhyAppKeys[i].value;
+                while(*outLen < maxLen)
+                {
+                    p2 = strstr(p1, ",");
+                    if(p2)
+                    {
+                        *p2 = '\0';
+                        p2 ++;
+                        dataOut[*outLen] = strtol(p1, NULL, 0);
+                        //printf("\ngranularity %d in idx %d",dataOut[*outLen],*outLen);
+                        p1 = p2;
+                        *outLen += 1;
+                    }
+                    else
+                    {
+                        dataOut[*outLen] = strtol(p1, NULL, 0);
+                        //printf("\ngranularity %d in idx %d",dataOut[*outLen],*outLen);
+                        *outLen += 1;
+                        break;
+                    }
+                }
+                return AUX_SUCCESS;
+            }
+        }
+    }
+
+    //printf("cline_set_int_array: Could not find %s\n", name);
+
+    return AUX_SUCCESS;
+}
+
+
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_source_auxlib_cline
+ *
+ *  @param[in]   *name String to search for
+ *  @param[out]  *value Pointer to location where string needs to be stored
+ *  @param[in]   deflt Default value to put into the value field if string is not found
+ *
+ *  @return  0 if AUX_SUCCESS
+ *
+ *  @description
+ *  This funtion searchs for a string from the phycfg.xml file and returns the string that
+ *  was associated in file
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint32_t cline_set_str(const char *name, char *value, const char *deflt)
+{
+    uint32_t i;
+
+    for (i = 0; i < CLINE_MAXKEYS; i++)
+    {
+        if (PhyAppKeys[i].name)
+        {
+            if (strcasecmp(name, PhyAppKeys[i].name) == 0)
+            {
+                strcpy(value, PhyAppKeys[i].value);
+                break;
+            }
+        }
+        else
+        {
+            // End of list reached
+            strcpy(value, deflt);
+            return AUX_FAILURE;
+        }
+    }
+
+    return AUX_SUCCESS;
+}
+
+
+
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_source_auxlib_cline
+ *
+ *  @param[in]   *pString Pointer to string that needs to be parsed
+ *
+ *  @return  0 if AUX_SUCCESS
+ *
+ *  @description
+ *  This function takes a line from phycfg.xml and parses it and if valid fields are found,
+ *  stores the xml tag and the value associated with the tag into a global structure.
+ *
+**/
+//-------------------------------------------------------------------------------------------
+int cline_parse_line(char *pString)
+{
+    char *stringLocal, *ptr1, *ptr2, *ptr3;
+//    char stringName[CLINE_MAX_STRING_LENGTH] = "", stringValue[CLINE_MAX_STRING_LENGTH] = "";
+    char *stringName, *stringValue;
+
+    stringLocal = NULL;
+    stringName = NULL;
+    stringValue = NULL;
+    ptr1 = ptr2 = ptr3 = NULL;
+    uint32_t strLen = strlen(pString);
+    if (strLen)
+    {
+        stringLocal = (char *)malloc(strLen + 1);
+        if (stringLocal == NULL)
+        {
+            printf("Cannot allocate stringLocal of size %d\n", (strLen + 1));
+            return AUX_FAILURE;
+        }
+    }
+
+    // Dont Destroy Original String
+    if (stringLocal)
+        strcpy(stringLocal, pString);
+
+    if (stringLocal)
+    {
+        if (strlen(stringLocal) <= 2)           // Probably line feed
+        {
+            if (stringLocal)
+                free(stringLocal);
+            return AUX_SUCCESS;
+        }
+    }
+    ptr1 = stringLocal;
+
+    // Locate Starting
+    if (ptr1)
+        ptr2 = strstr(ptr1, "<");
+    if (ptr2 == NULL)
+    {
+        if (stringLocal)
+            free(stringLocal);
+        printf("no begin at parameters string");
+        return AUX_FAILURE;
+    }
+
+    // See if this is a comment
+    if (ptr2)
+        ptr3 = strstr(ptr2, "!--");
+    if (ptr3 != NULL)
+    {
+        if (stringLocal)
+            free(stringLocal);
+        return AUX_SUCCESS;
+    }
+
+    // Locate Ending
+    if (ptr2)
+        ptr3 = strstr(ptr2, ">");
+    if (ptr3 == NULL)
+    {
+        if (stringLocal)
+            free(stringLocal);
+        printf("no ending at parameters string");
+        return AUX_FAILURE;
+    }
+
+    // Copy string
+    if (ptr3)
+        *ptr3 = '\0';
+    if (ptr2)
+        strLen = strlen(ptr2 + 1);
+    if (strLen)
+    {
+        stringName = (char *)malloc(strLen + 1);
+        if (stringName == NULL)
+        {
+            if (stringLocal)
+                free(stringLocal);
+            printf("Cannot allocate stringName of size %d\n", (strLen + 1));
+            return AUX_FAILURE;
+        }
+        else
+        {
+            if (ptr2)
+                strcpy(stringName, ptr2 + 1);
+        }
+    }
+
+    ptr1 = ptr3+1;
+
+    // Locate Starting
+    if (ptr1)
+        ptr2 = strstr(ptr1, "<");
+    if (ptr2 != NULL)
+    {
+        // Locate Ending
+        if (ptr2)
+            ptr3 = strstr(ptr2, ">");
+        if (ptr3 == NULL)
+        {
+            if (stringName)
+                free(stringName);
+            if (stringLocal)
+                free(stringLocal);
+            printf("no ending at parameters string");
+            return AUX_FAILURE;
+        }
+
+        // Copy string
+        strLen = 0;
+        if (ptr2)
+            *ptr2 = '\0';
+        if (ptr1)
+            strLen = strlen(ptr1);
+        if (strLen)
+        {
+            stringValue = (char *)malloc(strLen + 1);
+            if (stringValue == NULL)
+            {
+                if (stringName)
+                    free(stringName);
+                if (stringLocal)
+                    free(stringLocal);
+                printf("Cannot allocate stringValue of size %d\n", (strLen + 1));
+                return AUX_FAILURE;
+            }
+            if (ptr1)
+                strcpy(stringValue, ptr1);
+        }
+
+#ifdef WIN32
+        printf("Found String: %s with Value: %s\n", stringName, stringValue);
+#endif
+        {
+            uint32_t len = 0;
+
+            if (stringName)
+            {
+                len = strlen(stringName);
+                if (len)
+                {
+                    PhyAppKeys[pPhyCfgNumEntries].name = (char *) malloc(len+1);
+                    if (PhyAppKeys[pPhyCfgNumEntries].name == NULL)
+                    {
+                        if (stringName)
+                            free(stringName);
+                        if (stringLocal)
+                            free(stringLocal);
+                        if (stringValue)
+                            free(stringValue);
+                        printf("Cannot allocate PhyAppKeys[pPhyCfgNumEntries].name of size %d\n", (strLen + 1));
+                        return AUX_FAILURE;
+                    }
+                    if (stringName)
+                        strcpy(PhyAppKeys[pPhyCfgNumEntries].name, stringName);
+                }
+            }
+
+            len = 0;
+            if (stringValue)
+            {
+                len = strlen(stringValue);
+                if (len)
+                {
+                    PhyAppKeys[pPhyCfgNumEntries].value = (char *)malloc(len + 1);
+                    if (PhyAppKeys[pPhyCfgNumEntries].value == NULL)
+                    {
+                        if (stringName)
+                            free(stringName);
+                        if (stringLocal)
+                            free(stringLocal);
+                        if (stringValue)
+                            free(stringValue);
+                        printf("Cannot allocate PhyAppKeys[pPhyCfgNumEntries].value of size %d\n", (strLen + 1));
+                        return AUX_FAILURE;
+                    }
+                    if (stringValue)
+                        strcpy(PhyAppKeys[pPhyCfgNumEntries].value, stringValue);
+                }
+            }
+        }
+        pPhyCfgNumEntries++;
+    }
+
+    if(stringLocal)
+        free(stringLocal);
+    if (stringName)
+        free(stringName);
+    if (stringValue)
+        free(stringValue);
+
+    return AUX_SUCCESS;
+}
+
+
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_source_auxlib_cline
+ *
+ *  @param   void
+ *
+ *  @return  void
+ *
+ *  @description
+ *  This function prints all the tags and values found in the phycfg.xml file after parsing
+ *
+**/
+//-------------------------------------------------------------------------------------------
+void cline_print_info(void)
+{
+#ifndef TEST_APP
+    uint32_t i;
+
+    for (i = 0; i < pPhyCfgNumEntries; i++)
+    {
+        if (PhyAppKeys[i].name)
+        {
+            printf(" --%s=%s\n", PhyAppKeys[i].name, PhyAppKeys[i].value);
+        }
+    }
+    printf("\n");
+#endif
+    return;
+}
+
+
+
+//-------------------------------------------------------------------------------------------
+/** @ingroup group_source_auxlib_cline
+ *
+ *  @param[in]   argc Number of command line params
+ *  @param[in]   *argv[] Array of command line params
+ *  @param[in]   pString String to search for
+ *  @param[out]   *pDest Location where to store the payload
+ *
+ *  @return  0 if AUX_SUCCESS
+ *
+ *  @description
+ *  This function looks for a string passed in from the command line and returns the immediate
+ *  next parameter passed after this.
+ *
+**/
+//-------------------------------------------------------------------------------------------
+uint32_t cline_get_string(int argc, char *argv[], char* pString, char *pDest)
+{
+    uint32_t ret = AUX_FAILURE;
+    int i = 1, length = (int)strlen(pString);
+    char *filename = NULL;
+
+    //print_info_log("Searching for string: %s. Length of string: %d\n", pString, length);
+    while (i < argc)
+    {
+        if (strstr(argv[i], pString) != NULL)
+        {
+            filename = strstr(argv[i], pString);
+            filename += (length + 1);
+
+            //print_info_log("Found %s: Val = %s\n", pString, filename);
+            strcpy(pDest, filename);
+
+            ret = AUX_SUCCESS;
+            break;
+        }
+
+        i++;
+    }
+
+    return ret;
+}