Update to odulow per maintenance bronze
[o-du/phy.git] / fhi_lib / lib / src / xran_sync_api.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2019 Intel.
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 *
17 *******************************************************************************/
18 /**
19  * @brief This file provides implementation of synchronization related APIs (PTP/1588)
20  *        for XRAN.
21  *
22  * @file xran_sync_api.c
23  * @ingroup group_lte_source_xran
24  * @author Intel Corporation
25  *
26  **/
27
28 #include <assert.h>
29 #include <dirent.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "xran_sync_api.h"
35 #include "xran_printf.h"
36
37 #define BUF_LEN 256
38 #define PROC_DIR "/proc"
39 #define COMM_FILE "comm"
40 #define PMC_CMD "pmc -u -b 0 'GET PORT_DATA_SET'"
41 #define PTP4L_PROC_NAME "ptp4l"
42 #define PHC2SYS_PROC_NAME "phc2sys"
43
44 static int find_substr(const char *str, const unsigned int str_len,
45     const char *substr, const unsigned int substr_len)
46 {
47     assert(str);
48     assert(substr);
49     unsigned int ind = 0;
50
51     while (ind + substr_len <= str_len) {
52         if (0 == strncmp(&str[ind], substr, substr_len))
53             return 0;
54         ++ind;
55     }
56     return 1;
57 }
58
59 static int is_process_running(char *pname)
60 {
61     char full_path[BUF_LEN] = {0};
62     char read_proc_name[BUF_LEN] = {0};
63     int res = 1;
64     DIR *dir = opendir(PROC_DIR);
65     if (NULL == dir) {
66         return 1;
67     }
68
69     struct dirent *entry = NULL;
70     while (entry = readdir(dir)) {
71         long pid = atol(entry->d_name);
72         if (0 == pid)
73             continue;
74         sprintf(full_path, "%s/%ld/%s", PROC_DIR, pid, COMM_FILE);
75         FILE *proc_name_file = fopen(full_path, "r");
76         if (NULL == proc_name_file)
77             continue;
78         fgets( read_proc_name, BUF_LEN, proc_name_file);
79         if (0 == strncmp(read_proc_name, pname, strlen(pname))) {
80             res = 0;
81             fclose(proc_name_file);
82             break;
83         }
84         fclose(proc_name_file);
85     }
86     closedir(dir);
87     return res;
88 }
89
90 static int check_ptp_status()
91 {
92     char pmc_out_line[BUF_LEN];
93     const char *keywords[2] = {"portState", "SLAVE"};
94     int res = 1;
95     FILE *pmc_pipe = popen(PMC_CMD, "r");
96     if (NULL == pmc_pipe)
97         return 1;
98
99     while(fgets(pmc_out_line, BUF_LEN, pmc_pipe)) {
100         if (0 == find_substr(pmc_out_line, strlen(pmc_out_line), keywords[0],
101             strlen(keywords[0]))) {
102             if (0 == find_substr(pmc_out_line, strlen(pmc_out_line),
103                 keywords[1], strlen(keywords[1]))) {
104                 res = 0;
105                 break;
106             }
107         }
108     }
109     fclose(pmc_pipe);
110     return res;
111 }
112
113 int xran_is_synchronized()
114 {
115     int res = 0;
116     res |= is_process_running(PTP4L_PROC_NAME);
117     print_dbg("PTP4L_PROC_NAME %d\n", res);
118     res |= is_process_running(PHC2SYS_PROC_NAME);
119     print_dbg("PHC2SYS_PROC_NAME %d\n", res);
120     res |= check_ptp_status();
121     print_dbg("check_ptp_status %d\n", res);
122     return res;
123 }