1 // SPDX-License-Identifier: BSD-2-Clause
3 * Copyright (C) 2020 Andre Heider <a.heider@gmail.com>
16 #include "dsl_cpe_control.h"
17 #include <drv_dsl_cpe_api_ioctl.h>
18 #ifdef INCLUDE_DSL_CPE_API_VRX
19 #include <drv_mei_cpe_interface.h>
22 #define U16(v1, v2) ( \
23 ((uint16_t)(v1) << 8) | \
26 #define U32(v1, v2, v3, v4) ( \
27 ((uint32_t)(v1) << 24) | \
28 ((uint32_t)(v2) << 16) | \
29 ((uint32_t)(v3) << 8) | \
32 #define STR_CASE(id, text) \
37 #define IOCTL(type, request) \
39 memset(&out, 0, sizeof(type)); \
40 if (ioctl(fd, request, &out)) \
43 #define IOCTL_DIR(type, request, dir) \
45 memset(&out, 0, sizeof(type)); \
46 out.nDirection = dir; \
47 if (ioctl(fd, request, &out)) \
50 #define IOCTL_DIR_DELT(type, request, dir, delt) \
52 memset(&out, 0, sizeof(type)); \
53 out.nDirection = dir; \
54 out.nDeltDataType = delt; \
55 if (ioctl(fd, request, &out)) \
102 static DSL_CPE_ThreadCtrl_t thread
;
103 static struct ubus_context
*ctx
;
104 static struct blob_buf b
;
106 static inline void m_double(const char *id
, double value
) {
107 blobmsg_add_double(&b
, id
, value
);
110 static inline void m_bool(const char *id
, bool value
) {
111 blobmsg_add_u8(&b
, id
, value
);
114 static inline void m_u32(const char *id
, uint32_t value
) {
115 blobmsg_add_u32(&b
, id
, value
);
118 static inline void m_str(const char *id
, const char *value
) {
119 blobmsg_add_string(&b
, id
, value
);
122 static inline void m_db(const char *id
, int value
) {
123 m_double(id
, (double)value
/ 10);
126 static inline void m_array(const char *id
, const uint8_t *value
, uint8_t len
) {
127 void *c
= blobmsg_open_array(&b
, id
);
129 for (uint8_t i
= 0; i
< len
; ++i
)
130 blobmsg_add_u16(&b
, "", value
[i
]);
132 blobmsg_close_array(&b
, c
);
135 static void m_vendor(const char *id
, const uint8_t *value
) {
137 if (U16(value
[0], value
[1]) != 0xb500)
140 const char *str
= NULL
;
141 switch (U32(value
[2], value
[3], value
[4], value
[5])) {
142 STR_CASE(0x414C4342, "Alcatel")
143 STR_CASE(0x414E4456, "Analog Devices")
144 STR_CASE(0x4244434D, "Broadcom")
145 STR_CASE(0x43454E54, "Centillium")
146 STR_CASE(0x4753504E, "Globespan")
147 STR_CASE(0x494B4E53, "Ikanos")
148 STR_CASE(0x4946544E, "Infineon")
149 STR_CASE(0x54535443, "Texas Instruments")
150 STR_CASE(0x544D4D42, "Thomson MultiMedia Broadband")
151 STR_CASE(0x5443544E, "Trend Chip Technologies")
152 STR_CASE(0x53544D49, "ST Micro")
158 if ((value
[6] == 0) && (value
[7] == 0)) {
164 sprintf(buf
, "%s %d.%d", str
, value
[6], value
[7]);
170 annex_t
get_annex(const uint8_t *xtse
) {
171 if ((xtse
[0] & XTSE_1_01_A_T1_413
) ||
172 (xtse
[0] & XTSE_1_03_A_1_NO
) ||
173 (xtse
[0] & XTSE_1_04_A_1_O
) ||
174 (xtse
[1] & XTSE_2_01_A_2_NO
) ||
175 (xtse
[2] & XTSE_3_03_A_3_NO
) ||
176 (xtse
[2] & XTSE_3_04_A_3_O
) ||
177 (xtse
[3] & XTSE_4_01_A_4_NO
) ||
178 (xtse
[3] & XTSE_4_02_A_4_O
) ||
179 (xtse
[5] & XTSE_6_01_A_5_NO
) ||
180 (xtse
[5] & XTSE_6_02_A_5_O
) ||
181 (xtse
[7] & XTSE_8_01_A
))
184 if ((xtse
[0] & XTSE_1_05_B_1_NO
) ||
185 (xtse
[0] & XTSE_1_06_B_1_O
) ||
186 (xtse
[1] & XTSE_2_02_B_2_O
) ||
187 (xtse
[2] & XTSE_3_05_B_3_NO
) ||
188 (xtse
[2] & XTSE_3_06_B_3_O
) ||
189 (xtse
[5] & XTSE_6_03_B_5_NO
) ||
190 (xtse
[5] & XTSE_6_04_B_5_O
) ||
191 (xtse
[7] & XTSE_8_02_B
))
194 if ((xtse
[0] & XTSE_1_02_C_TS_101388
) ||
195 (xtse
[0] & XTSE_1_07_C_1_NO
) ||
196 (xtse
[0] & XTSE_1_08_C_1_O
) ||
197 (xtse
[1] & XTSE_2_03_C_2_NO
) ||
198 (xtse
[1] & XTSE_2_04_C_2_O
) ||
199 (xtse
[7] & XTSE_8_03_C
))
202 if ((xtse
[3] & XTSE_4_05_I_3_NO
) ||
203 (xtse
[3] & XTSE_4_06_I_3_O
) ||
204 (xtse
[4] & XTSE_5_01_I_4_NO
) ||
205 (xtse
[4] & XTSE_5_02_I_4_O
) ||
206 (xtse
[5] & XTSE_6_07_I_5_NO
) ||
207 (xtse
[5] & XTSE_6_08_I_5_O
))
210 if ((xtse
[3] & XTSE_4_07_J_3_NO
) ||
211 (xtse
[3] & XTSE_4_08_J_3_O
) ||
212 (xtse
[6] & XTSE_7_01_J_5_NO
) ||
213 (xtse
[6] & XTSE_7_02_J_5_O
))
216 if ((xtse
[4] & XTSE_5_03_L_3_NO
) ||
217 (xtse
[4] & XTSE_5_04_L_3_NO
) ||
218 (xtse
[4] & XTSE_5_05_L_3_O
) ||
219 (xtse
[4] & XTSE_5_06_L_3_O
))
222 if ((xtse
[4] & XTSE_5_07_M_3_NO
) ||
223 (xtse
[4] & XTSE_5_08_M_3_O
) ||
224 (xtse
[6] & XTSE_7_03_M_5_NO
) ||
225 (xtse
[6] & XTSE_7_04_M_5_O
))
228 return ANNEX_UNKNOWN
;
231 static standard_t
get_standard(const uint8_t *xtse
) {
232 if (xtse
[0] & XTSE_1_01_A_T1_413
)
235 if (xtse
[0] & XTSE_1_02_C_TS_101388
)
236 return STD_TS_101_388
;
238 if ((xtse
[0] & XTSE_1_03_A_1_NO
) ||
239 (xtse
[0] & XTSE_1_04_A_1_O
) ||
240 (xtse
[0] & XTSE_1_05_B_1_NO
) ||
241 (xtse
[0] & XTSE_1_06_B_1_O
) ||
242 (xtse
[0] & XTSE_1_07_C_1_NO
) ||
243 (xtse
[0] & XTSE_1_08_C_1_O
))
246 if ((xtse
[1] & XTSE_2_01_A_2_NO
) ||
247 (xtse
[1] & XTSE_2_02_B_2_O
) ||
248 (xtse
[1] & XTSE_2_03_C_2_NO
) ||
249 (xtse
[1] & XTSE_2_04_C_2_O
))
252 if ((xtse
[2] & XTSE_3_03_A_3_NO
) ||
253 (xtse
[2] & XTSE_3_04_A_3_O
) ||
254 (xtse
[2] & XTSE_3_05_B_3_NO
) ||
255 (xtse
[2] & XTSE_3_06_B_3_O
) ||
256 (xtse
[3] & XTSE_4_05_I_3_NO
) ||
257 (xtse
[3] & XTSE_4_06_I_3_O
) ||
258 (xtse
[3] & XTSE_4_07_J_3_NO
) ||
259 (xtse
[3] & XTSE_4_08_J_3_O
) ||
260 (xtse
[4] & XTSE_5_03_L_3_NO
) ||
261 (xtse
[4] & XTSE_5_04_L_3_NO
) ||
262 (xtse
[4] & XTSE_5_05_L_3_O
) ||
263 (xtse
[4] & XTSE_5_06_L_3_O
) ||
264 (xtse
[4] & XTSE_5_07_M_3_NO
) ||
265 (xtse
[4] & XTSE_5_08_M_3_O
))
268 if ((xtse
[3] & XTSE_4_01_A_4_NO
) ||
269 (xtse
[3] & XTSE_4_02_A_4_O
) ||
270 (xtse
[4] & XTSE_5_01_I_4_NO
) ||
271 (xtse
[4] & XTSE_5_02_I_4_O
))
274 if ((xtse
[5] & XTSE_6_01_A_5_NO
) ||
275 (xtse
[5] & XTSE_6_02_A_5_O
) ||
276 (xtse
[5] & XTSE_6_03_B_5_NO
) ||
277 (xtse
[5] & XTSE_6_04_B_5_O
) ||
278 (xtse
[5] & XTSE_6_07_I_5_NO
) ||
279 (xtse
[5] & XTSE_6_08_I_5_O
) ||
280 (xtse
[6] & XTSE_7_01_J_5_NO
) ||
281 (xtse
[6] & XTSE_7_02_J_5_O
) ||
282 (xtse
[6] & XTSE_7_03_M_5_NO
) ||
283 (xtse
[6] & XTSE_7_04_M_5_O
))
286 if (xtse
[7] & XTSE_8_08
)
289 if ((xtse
[7] & XTSE_8_01_A
) ||
290 (xtse
[7] & XTSE_8_02_B
) ||
291 (xtse
[7] & XTSE_8_03_C
))
297 static void version_information(int fd
) {
298 IOCTL(DSL_VersionInformation_t
, DSL_FIO_VERSION_INFORMATION_GET
)
300 m_str("api_version", out
.data
.DSL_DriverVersionApi
);
301 m_str("firmware_version", out
.data
.DSL_ChipSetFWVersion
);
302 m_str("chipset", out
.data
.DSL_ChipSetType
);
303 m_str("driver_version", out
.data
.DSL_DriverVersionMeiBsp
);
306 static void line_state(int fd
) {
307 IOCTL(DSL_LineState_t
, DSL_FIO_LINE_STATE_GET
)
310 switch (out
.data
.nLineState
) {
311 STR_CASE(DSL_LINESTATE_NOT_INITIALIZED
, "Not initialized")
312 STR_CASE(DSL_LINESTATE_EXCEPTION
, "Exception")
313 STR_CASE(DSL_LINESTATE_NOT_UPDATED
, "Not updated")
314 STR_CASE(DSL_LINESTATE_IDLE_REQUEST
, "Idle request")
315 STR_CASE(DSL_LINESTATE_IDLE
, "Idle")
316 STR_CASE(DSL_LINESTATE_SILENT_REQUEST
, "Silent request")
317 STR_CASE(DSL_LINESTATE_SILENT
, "Silent")
318 STR_CASE(DSL_LINESTATE_HANDSHAKE
, "Handshake")
319 STR_CASE(DSL_LINESTATE_BONDING_CLR
, "Bonding CLR")
320 STR_CASE(DSL_LINESTATE_FULL_INIT
, "Full init")
321 STR_CASE(DSL_LINESTATE_SHORT_INIT_ENTRY
, "Short init entry")
322 STR_CASE(DSL_LINESTATE_DISCOVERY
, "Discovery")
323 STR_CASE(DSL_LINESTATE_TRAINING
, "Training")
324 STR_CASE(DSL_LINESTATE_ANALYSIS
, "Analysis")
325 STR_CASE(DSL_LINESTATE_EXCHANGE
, "Exchange")
326 STR_CASE(DSL_LINESTATE_SHOWTIME_NO_SYNC
, "Showtime without TC-Layer sync")
327 STR_CASE(DSL_LINESTATE_SHOWTIME_TC_SYNC
, "Showtime with TC-Layer sync")
328 STR_CASE(DSL_LINESTATE_FASTRETRAIN
, "Fastretrain")
329 STR_CASE(DSL_LINESTATE_LOWPOWER_L2
, "Lowpower L2")
330 STR_CASE(DSL_LINESTATE_LOOPDIAGNOSTIC_ACTIVE
, "Loopdiagnostic active")
331 STR_CASE(DSL_LINESTATE_LOOPDIAGNOSTIC_DATA_EXCHANGE
, "Loopdiagnostic data exchange")
332 STR_CASE(DSL_LINESTATE_LOOPDIAGNOSTIC_DATA_REQUEST
, "Loopdiagnostic data request")
333 STR_CASE(DSL_LINESTATE_LOOPDIAGNOSTIC_COMPLETE
, "Loopdiagnostic complete")
334 STR_CASE(DSL_LINESTATE_RESYNC
, "Resync")
335 STR_CASE(DSL_LINESTATE_TEST
, "Test")
336 STR_CASE(DSL_LINESTATE_TEST_LOOP
, "Test loop")
337 STR_CASE(DSL_LINESTATE_TEST_REVERB
, "Test reverb")
338 STR_CASE(DSL_LINESTATE_TEST_MEDLEY
, "Test medley")
339 STR_CASE(DSL_LINESTATE_TEST_SHOWTIME_LOCK
, "Showtime lock")
340 STR_CASE(DSL_LINESTATE_TEST_QUIET
, "Quiet")
341 STR_CASE(DSL_LINESTATE_LOWPOWER_L3
, "Lowpower L3")
342 #ifndef INCLUDE_DSL_CPE_API_DANUBE
343 STR_CASE(DSL_LINESTATE_DISABLED
, "Disabled")
344 STR_CASE(DSL_LINESTATE_T1413
, "T1413")
345 STR_CASE(DSL_LINESTATE_ORDERLY_SHUTDOWN_REQUEST
, "Orderly shutdown request")
346 STR_CASE(DSL_LINESTATE_ORDERLY_SHUTDOWN
, "Orderly shutdown")
347 STR_CASE(DSL_LINESTATE_TEST_FILTERDETECTION_ACTIVE
, "Test filterdetection active")
348 STR_CASE(DSL_LINESTATE_TEST_FILTERDETECTION_COMPLETE
, "Test filterdetection complete")
357 m_bool("up", out
.data
.nLineState
== DSL_LINESTATE_SHOWTIME_TC_SYNC
);
360 static void pm_channel_counters_showtime(int fd
) {
361 IOCTL_DIR(DSL_PM_ChannelCounters_t
, DSL_FIO_PM_CHANNEL_COUNTERS_SHOWTIME_GET
, DSL_NEAR_END
);
363 m_u32("uptime", out
.interval
.nElapsedTime
);
366 static void g997_line_inventory(int fd
) {
367 IOCTL_DIR(DSL_G997_LineInventory_t
, DSL_FIO_G997_LINE_INVENTORY_GET
, DSL_DOWNSTREAM
)
369 m_array("vendor_id", out
.data
.G994VendorID
, DSL_G997_LI_MAXLEN_VENDOR_ID
);
370 m_vendor("vendor", out
.data
.G994VendorID
);
371 m_array("system_vendor_id", out
.data
.SystemVendorID
, DSL_G997_LI_MAXLEN_VENDOR_ID
);
372 m_vendor("system_vendor", out
.data
.SystemVendorID
);
373 m_array("version", out
.data
.VersionNumber
, DSL_G997_LI_MAXLEN_VERSION
);
374 m_array("serial", out
.data
.SerialNumber
, DSL_G997_LI_MAXLEN_SERIAL
);
377 static void g997_power_management_status(int fd
) {
378 IOCTL(DSL_G997_PowerManagementStatus_t
, DSL_FIO_G997_POWER_MANAGEMENT_STATUS_GET
)
381 switch (out
.data
.nPowerManagementStatus
) {
382 STR_CASE(DSL_G997_PMS_NA
, "Power management state is not available")
383 STR_CASE(DSL_G997_PMS_L0
, "L0 - Synchronized")
384 STR_CASE(DSL_G997_PMS_L1
, "L1 - Power Down Data transmission (G.992.2)")
385 STR_CASE(DSL_G997_PMS_L2
, "L2 - Power Down Data transmission (G.992.3 and G.992.4)")
386 STR_CASE(DSL_G997_PMS_L3
, "L3 - No power")
392 m_str("power_state", str
);
395 static void g997_xtu_system_enabling(int fd
, standard_t
*standard
) {
396 IOCTL(DSL_G997_XTUSystemEnabling_t
, DSL_FIO_G997_XTU_SYSTEM_ENABLING_STATUS_GET
)
398 m_array("xtse", out
.data
.XTSE
, DSL_G997_NUM_XTSE_OCTETS
);
401 switch (get_annex(out
.data
.XTSE
)) {
402 STR_CASE(ANNEX_A
, "A")
403 STR_CASE(ANNEX_B
, "B")
404 STR_CASE(ANNEX_C
, "C")
405 STR_CASE(ANNEX_I
, "I")
406 STR_CASE(ANNEX_J
, "J")
407 STR_CASE(ANNEX_L
, "L")
408 STR_CASE(ANNEX_M
, "M")
416 *standard
= get_standard(out
.data
.XTSE
);
419 STR_CASE(STD_T1_413
, "T1.413")
420 STR_CASE(STD_TS_101_388
, "TS 101 388")
421 STR_CASE(STD_G_992_1
, "G.992.1")
422 STR_CASE(STD_G_992_2
, "G.992.2")
423 STR_CASE(STD_G_992_3
, "G.992.3")
424 STR_CASE(STD_G_992_4
, "G.992.4")
425 STR_CASE(STD_G_992_5
, "G.992.5")
426 STR_CASE(STD_G_993_1
, "G.993.1")
427 STR_CASE(STD_G_993_2
, "G.993.2")
433 m_str("standard", str
);
436 static vector_t
get_vector_status() {
437 #ifdef INCLUDE_DSL_CPE_API_VRX
438 int fd
= open(DSL_CPE_DSL_LOW_DEV
"/0", O_RDWR
, 0644);
440 return VECTOR_UNKNOWN
;
442 IOCTL_MEI_dsmStatus_t out
;
443 memset(&out
, 0, sizeof(IOCTL_MEI_dsmStatus_t
));
444 int ret
= ioctl(fd
, FIO_MEI_DSM_STATUS_GET
, &out
);
448 return VECTOR_UNKNOWN
;
450 switch (out
.eVectorStatus
) {
451 case e_MEI_VECTOR_STAT_OFF
:
453 case e_MEI_VECTOR_STAT_ON_DS
:
455 case e_MEI_VECTOR_STAT_ON_DS_US
:
456 return VECTOR_ON_DS_US
;
458 return VECTOR_UNKNOWN
;
461 return VECTOR_UNKNOWN
;
465 static void band_plan_status(int fd
, profile_t
*profile
) {
466 #if (INCLUDE_DSL_CPE_API_VDSL_SUPPORT == 1)
467 IOCTL(DSL_BandPlanStatus_t
, DSL_FIO_BAND_PLAN_STATUS_GET
)
469 switch (out
.data
.nProfile
) {
471 *profile
= PROFILE_8A
;
474 *profile
= PROFILE_8B
;
477 *profile
= PROFILE_8C
;
480 *profile
= PROFILE_8D
;
482 case DSL_PROFILE_12A
:
483 *profile
= PROFILE_12A
;
485 case DSL_PROFILE_12B
:
486 *profile
= PROFILE_12B
;
488 case DSL_PROFILE_17A
:
489 *profile
= PROFILE_17A
;
491 case DSL_PROFILE_30A
:
492 *profile
= PROFILE_30A
;
494 case DSL_PROFILE_35B
:
495 *profile
= PROFILE_35B
;
498 *profile
= PROFILE_UNKNOWN
;
504 STR_CASE(PROFILE_8A
, "8a")
505 STR_CASE(PROFILE_8B
, "8b")
506 STR_CASE(PROFILE_8C
, "8c")
507 STR_CASE(PROFILE_8D
, "8d")
508 STR_CASE(PROFILE_12A
, "12a")
509 STR_CASE(PROFILE_12B
, "12b")
510 STR_CASE(PROFILE_17A
, "17a")
511 STR_CASE(PROFILE_30A
, "30a")
512 STR_CASE(PROFILE_35B
, "35b")
518 m_str("profile", str
);
522 static void line_feature_config(int fd
, DSL_AccessDir_t direction
) {
523 IOCTL_DIR(DSL_LineFeature_t
, DSL_FIO_LINE_FEATURE_STATUS_GET
, direction
)
525 m_bool("trellis", out
.data
.bTrellisEnable
);
526 m_bool("bitswap", out
.data
.bBitswapEnable
);
527 m_bool("retx", out
.data
.bReTxEnable
);
528 m_bool("virtual_noise", out
.data
.bVirtualNoiseSupport
);
531 static void g997_channel_status(int fd
, DSL_AccessDir_t direction
) {
532 IOCTL_DIR(DSL_G997_ChannelStatus_t
, DSL_FIO_G997_CHANNEL_STATUS_GET
, direction
);
534 m_u32("interleave_delay", out
.data
.ActualInterleaveDelay
* 10);
535 m_u32("data_rate", out
.data
.ActualDataRate
);
538 static void g997_line_status(int fd
, DSL_AccessDir_t direction
) {
539 IOCTL_DIR_DELT(DSL_G997_LineStatus_t
, DSL_FIO_G997_LINE_STATUS_GET
, direction
, DSL_DELT_DATA_SHOWTIME
);
541 m_db("latn", out
.data
.LATN
);
542 m_db("satn", out
.data
.SATN
);
543 m_db("snr", out
.data
.SNR
);
544 m_db("actps", out
.data
.ACTPS
);
545 m_db("actatp", out
.data
.ACTATP
);
546 m_u32("attndr", out
.data
.ATTNDR
);
549 static void pm_line_sec_counters_total(int fd
, DSL_XTUDir_t direction
) {
550 IOCTL_DIR(DSL_PM_LineSecCountersTotal_t
, DSL_FIO_PM_LINE_SEC_COUNTERS_TOTAL_GET
, direction
)
552 m_u32("es", out
.data
.nES
);
553 m_u32("ses", out
.data
.nSES
);
554 m_u32("loss", out
.data
.nLOSS
);
555 m_u32("uas", out
.data
.nUAS
);
556 m_u32("lofs", out
.data
.nLOFS
);
557 #ifndef INCLUDE_DSL_CPE_API_DANUBE
558 m_u32("fecs", out
.data
.nFECS
);
562 static void pm_data_path_counters_total(int fd
, DSL_XTUDir_t direction
) {
563 IOCTL_DIR(DSL_PM_DataPathCountersTotal_t
, DSL_FIO_PM_DATA_PATH_COUNTERS_TOTAL_GET
, direction
);
565 m_u32("hec", out
.data
.nHEC
);
566 m_u32("ibe", out
.data
.nIBE
);
567 m_u32("crc_p", out
.data
.nCRC_P
);
568 m_u32("crcp_p", out
.data
.nCRCP_P
);
569 m_u32("cv_p", out
.data
.nCV_P
);
570 m_u32("cvp_p", out
.data
.nCVP_P
);
573 static void retx_statistics(int fd
, DSL_XTUDir_t direction
) {
574 #ifdef INCLUDE_DSL_CPE_PM_RETX_COUNTERS
575 #ifdef INCLUDE_DSL_CPE_PM_RETX_THRESHOLDS
576 IOCTL_DIR(DSL_ReTxStatistics_t
, DSL_FIO_RETX_STATISTICS_GET
, direction
);
578 m_u32("rx_corrupted", out
.data
.nRxCorruptedTotal
);
579 m_u32("rx_uncorrected_protected", out
.data
.nRxUncorrectedProtected
);
580 m_u32("rx_retransmitted", out
.data
.nRxRetransmitted
);
581 m_u32("rx_corrected", out
.data
.nRxCorrected
);
582 m_u32("tx_retransmitted", out
.data
.nTxRetransmitted
);
587 static void describe_mode(standard_t standard
, profile_t profile
, vector_t vector
) {
592 strcpy(buf
, "T1.413");
595 strcpy(buf
, "TS 101 388");
598 strcpy(buf
, "G.992.1 (ADSL)");
601 strcpy(buf
, "G.992.2 (ADSL lite)");
604 strcpy(buf
, "G.992.3 (ADSL2)");
607 strcpy(buf
, "G.992.4 (ADSL2 lite)");
610 strcpy(buf
, "G.992.5 (ADSL2+)");
613 strcpy(buf
, "G.993.1 (VDSL)");
616 strcpy(buf
, "G.993.2 (VDSL2");
620 strcat(buf
, ", Profile 8a");
623 strcat(buf
, ", Profile 8b");
626 strcat(buf
, ", Profile 8c");
629 strcat(buf
, ", Profile 8d");
632 strcat(buf
, ", Profile 12a");
635 strcat(buf
, ", Profile 12b");
638 strcat(buf
, ", Profile 17a");
641 strcat(buf
, ", Profile 30a");
644 strcat(buf
, ", Profile 35b");
652 strcat(buf
, ", with downstream vectoring");
654 case VECTOR_ON_DS_US
:
655 strcat(buf
, ", with down- and upstream vectoring");
670 static int metrics(struct ubus_context
*ctx
, struct ubus_object
*obj
,
671 struct ubus_request_data
*req
, const char *method
,
672 struct blob_attr
*msg
)
676 standard_t standard
= STD_UNKNOWN
;
677 profile_t profile
= PROFILE_UNKNOWN
;
678 vector_t vector
= VECTOR_UNKNOWN
;
680 #ifndef INCLUDE_DSL_CPE_API_DANUBE
681 fd
= open(DSL_CPE_DEVICE_NAME
"0", O_RDWR
, 0644);
683 fd
= open(DSL_CPE_DEVICE_NAME
, O_RDWR
, 0644);
686 return UBUS_STATUS_UNKNOWN_ERROR
;
688 blob_buf_init(&b
, 0);
690 version_information(fd
);
692 pm_channel_counters_showtime(fd
);
694 c
= blobmsg_open_table(&b
, "atu_c");
695 g997_line_inventory(fd
);
696 blobmsg_close_table(&b
, c
);
698 g997_power_management_status(fd
);
699 g997_xtu_system_enabling(fd
, &standard
);
701 if (standard
== STD_G_993_2
) {
702 band_plan_status(fd
, &profile
);
703 vector
= get_vector_status();
706 describe_mode(standard
, profile
, vector
);
708 c
= blobmsg_open_table(&b
, "upstream");
711 m_bool("vector", false);
713 case VECTOR_ON_DS_US
:
714 m_bool("vector", true);
719 line_feature_config(fd
, DSL_UPSTREAM
);
720 g997_channel_status(fd
, DSL_UPSTREAM
);
721 g997_line_status(fd
, DSL_UPSTREAM
);
722 blobmsg_close_table(&b
, c
);
724 c
= blobmsg_open_table(&b
, "downstream");
727 m_bool("vector", false);
730 case VECTOR_ON_DS_US
:
731 m_bool("vector", true);
736 line_feature_config(fd
, DSL_DOWNSTREAM
);
737 g997_channel_status(fd
, DSL_DOWNSTREAM
);
738 g997_line_status(fd
, DSL_DOWNSTREAM
);
739 blobmsg_close_table(&b
, c
);
741 c
= blobmsg_open_table(&b
, "errors");
742 c2
= blobmsg_open_table(&b
, "near");
743 pm_line_sec_counters_total(fd
, DSL_NEAR_END
);
744 pm_data_path_counters_total(fd
, DSL_NEAR_END
);
745 retx_statistics(fd
, DSL_NEAR_END
);
746 blobmsg_close_table(&b
, c2
);
748 c2
= blobmsg_open_table(&b
, "far");
749 pm_line_sec_counters_total(fd
, DSL_FAR_END
);
750 pm_data_path_counters_total(fd
, DSL_FAR_END
);
751 retx_statistics(fd
, DSL_FAR_END
);
752 blobmsg_close_table(&b
, c2
);
753 blobmsg_close_table(&b
, c
);
755 ubus_send_reply(ctx
, req
, b
.head
);
762 static const struct ubus_method dsl_methods
[] = {
763 UBUS_METHOD_NOARG("metrics", metrics
),
766 static struct ubus_object_type dsl_object_type
=
767 UBUS_OBJECT_TYPE("dsl", dsl_methods
);
769 static struct ubus_object dsl_object
= {
771 .type
= &dsl_object_type
,
772 .methods
= dsl_methods
,
773 .n_methods
= ARRAY_SIZE(dsl_methods
),
776 static DSL_int_t
ubus_main(DSL_CPE_Thread_Params_t
*params
) {
784 ctx
= ubus_connect(NULL
);
788 if (ubus_add_object(ctx
, &dsl_object
)) {
796 DSL_CPE_ThreadInit(&thread
, "ubus", ubus_main
, DSL_CPE_PIPE_STACK_SIZE
, DSL_CPE_PIPE_PRIORITY
, 0, 0);
806 DSL_CPE_ThreadShutdown(&thread
, 1000);