Line data Source code
1 : /**
2 : * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "eid_util.h"
12 : #include <stdio.h>
13 : #include <stdlib.h>
14 : #include <ctype.h>
15 : #include "securec.h"
16 :
17 : #define UE_ID_POS (14)
18 : #define HEX_BASE (16)
19 : #define PORT_POS (30)
20 : #define DIE_POS (39)
21 : #define DIE_OFFSET (3)
22 :
23 0 : static int Char2Int(char c, unsigned char* i)
24 : {
25 0 : if (!isxdigit(c)) {
26 0 : return -1;
27 : }
28 0 : if (!isdigit(c)) {
29 0 : return -1;
30 : }
31 0 : *i = toupper(c) - '0';
32 0 : return 0;
33 : }
34 :
35 0 : int EidGetFeId(const char* eidhexstr)
36 : {
37 0 : char fe = eidhexstr[UE_ID_POS];
38 0 : int fe_id = (int)strtol(&fe, NULL, HEX_BASE) >> 1;
39 0 : return fe_id;
40 : }
41 :
42 12 : int EidGetPortId(const char* eidhexstr, int* port_id)
43 : {
44 12 : unsigned char end = (unsigned char)strtoul(&eidhexstr[PORT_POS], NULL, HEX_BASE);
45 12 : unsigned int flag = 0x80;
46 12 : unsigned int tmp = (~flag & end);
47 12 : unsigned int port = tmp >> 3;
48 12 : *port_id = (int)port;
49 12 : return 0;
50 : }
51 :
52 0 : int EidGetDieId(const char* eidhexstr, int* die_id)
53 : {
54 0 : unsigned char d = 0;
55 0 : Char2Int(eidhexstr[DIE_POS], &d);
56 0 : *die_id = (int)((8 & d) >> DIE_OFFSET);
57 0 : return 0;
58 : }
59 :
60 : // 标卡
61 3 : int UrmaEidGetDieIdForCard(dcmi_urma_eid_t* eid)
62 : {
63 3 : unsigned char last = eid->raw[DCMI_URMA_EID_SIZE - 1];
64 3 : int die_id = (4 & last) == 0 ? 0 : 1;
65 3 : return die_id;
66 : }
67 :
68 8 : int UrmaEidGetPortIdForCard(dcmi_urma_eid_t* eid)
69 : {
70 : #define EID_PORT_LEFT_OFFSET (1)
71 : #define EID_PORT_RIGHT_OFFSET (4)
72 8 : unsigned char last = eid->raw[DCMI_URMA_EID_SIZE - 1];
73 8 : last = last << EID_PORT_LEFT_OFFSET;
74 8 : last = last >> EID_PORT_RIGHT_OFFSET;
75 8 : return (int)last;
76 : }
77 :
78 : // 服务器和PoD
79 45 : int UrmaEidGetFeId(const dcmi_urma_eid_t* eid)
80 : {
81 : #define FE_POS (6)
82 45 : unsigned char fe = eid->raw[FE_POS];
83 45 : const unsigned char mask = 0x7f; // fe使用7bit
84 45 : fe = fe & mask;
85 45 : return (int)fe;
86 : }
87 :
88 : #define RAW_PORT_AND_DIE_POS (5)
89 : #define RAW_PORT_BIT_LEN (6)
90 : /**
91 : * @brief 获取URMA eid中的portID
92 : * port_id和die id 在同一个unsigned char中
93 : * |0|1|2|3|4|5|6|7|
94 : * |die| port_id |
95 : * @param eid URMA eid结构体指针
96 : * @return int portID
97 : */
98 233 : int UrmaEidGetPortId(const dcmi_urma_eid_t* eid)
99 : {
100 233 : unsigned char dieAndPort = eid->raw[RAW_PORT_AND_DIE_POS];
101 233 : const unsigned char mask = 0x3F;
102 233 : unsigned char port = dieAndPort & mask;
103 233 : return (int)port;
104 : }
105 :
106 103 : int UrmaEidGetDieId(const dcmi_urma_eid_t* eid)
107 : {
108 103 : unsigned char dieAndPort = eid->raw[RAW_PORT_AND_DIE_POS];
109 103 : unsigned char dieId = dieAndPort >> RAW_PORT_BIT_LEN;
110 103 : return (int)dieId;
111 : }
112 :
113 0 : int GetMaxFeId(const dcmi_urma_eid_info_t* eidList, size_t eidCnt)
114 : {
115 0 : int maxFeId = -1;
116 0 : for (size_t i = 0; i < eidCnt; ++i) {
117 0 : int feId = UrmaEidGetFeId(&eidList[i].eid);
118 0 : if (feId > maxFeId) {
119 0 : maxFeId = feId;
120 : }
121 : }
122 0 : return maxFeId;
123 : }
124 :
125 : /**
126 : * @brief 判断是否为portgroup
127 : * 判断依据:portID为0x3F时,为portgroup
128 : * @param eid URMA eid结构体指针
129 : * @return int 1为portgroup,0为物理ID
130 : */
131 126 : int UrmaEidIsPortGroup(const dcmi_urma_eid_t* eid)
132 : {
133 126 : const int pgPortId = 0x3F;
134 126 : int port = UrmaEidGetPortId(eid);
135 126 : if (port == pgPortId) {
136 25 : return 1;
137 : }
138 101 : return 0;
139 : }
140 :
141 : /**
142 : * 判断是否是UBOE
143 : * 在第7 btye位置上
144 : * 11000000 为UBOE, 使用0xc0判断
145 : * 10000000 为UBOE, 使用0x80判断
146 : * @param eid URMA eid结构体指针
147 : * @return int 1为UBOE,0为不是UBOE
148 : */
149 55 : int UrmaEidIsUBOE(const dcmi_urma_eid_t* eid)
150 : {
151 55 : const int uboeMask = 0xc0;
152 55 : const int flagPos = 7; // UBOE和UB_RTP标志位的位置
153 55 : unsigned char flag = eid->raw[flagPos];
154 55 : if ((uboeMask & flag) == uboeMask) {
155 7 : return 1;
156 : }
157 48 : return 0;
158 : }
159 :
160 : /**
161 : * 判断是否是UB_RTP, 判断原理见UrmaEidIsUBOE
162 : * @param eid URMA eid结构体指针
163 : * @return int 1为UB_RTP,0为不是UB_RTP
164 : */
165 3 : int UrmaEidIsUbRtp(const dcmi_urma_eid_t* eid)
166 : {
167 3 : const unsigned char bitMask = 0xc0;
168 3 : const unsigned char ubRtpFlag = 0x80; // UB_RTP的flag
169 3 : const int flagPos = 7; // UBOE和UB_RTP标志位的位置
170 3 : unsigned char flag = eid->raw[flagPos];
171 3 : int bit = (flag & bitMask); //
172 3 : if (bit == ubRtpFlag) {
173 1 : return 1;
174 : }
175 2 : return 0;
176 : }
177 :
178 5 : int UrmaEid2CNA(const dcmi_urma_eid_t* eid, char* cna, size_t cnaSize)
179 : {
180 5 : if (cna == NULL || cnaSize == 0) {
181 0 : return -1;
182 : }
183 5 : const int ipPos1 = 6; // ip 第一个字节位置
184 5 : const int ipPos2 = 12;
185 5 : const int ipPos3 = 13;
186 5 : const int ipPos4 = 14;
187 5 : unsigned char ip1 = eid->raw[ipPos1];
188 5 : unsigned char ip2 = eid->raw[ipPos2];
189 5 : unsigned char ip3 = eid->raw[ipPos3];
190 5 : unsigned char ip4 = eid->raw[ipPos4];
191 5 : return sprintf_s(cna, cnaSize, "%u.%u.%u.%u", ip1, ip2, ip3, ip4);
192 : }
193 :
194 42 : int UBEntityGetId(const UBEntity* ue)
195 : {
196 42 : if (ue->eidNum == 0) {
197 0 : return -1;
198 : }
199 42 : return UrmaEidGetFeId(&ue->eidList[0].eid);
200 : }
201 :
202 8 : int UBEntityGetDieId(const UBEntity* ue)
203 : {
204 8 : if (ue->eidNum == 0) {
205 0 : return -1;
206 : }
207 8 : return UrmaEidGetDieId(&ue->eidList[0].eid);
208 : }
209 :
210 9 : int UBEntityGetPortGroupIdx(const UBEntity* ue)
211 : {
212 20 : for (int i = 0; i < (int)ue->eidNum; ++i) {
213 20 : if (UrmaEidIsPortGroup(&ue->eidList[i].eid)) {
214 9 : return i;
215 : }
216 : }
217 : // 没有找到
218 0 : return -1;
219 : }
220 :
221 65 : int UBGetMaxEntityId(const UEList* ueList, int dieId)
222 : {
223 65 : int maxId = -1;
224 69 : for (unsigned int i = 0; i < ueList->ueNum; ++i) {
225 4 : if (ueList->ueList[i].eidNum == 0 || UBEntityGetDieId(&ueList->ueList[i]) != dieId) {
226 2 : continue;
227 : }
228 : // 一个UBEntity下的所有eid的Entity ID相同
229 2 : int id = UrmaEidGetFeId(&ueList->ueList[i].eidList[0].eid);
230 2 : if (id > maxId) {
231 2 : maxId = id;
232 : }
233 : }
234 65 : return maxId;
235 : }
|