27
27
from itertools import groupby
28
28
from twisted .python import log , failure
29
29
from twisted .python .logfile import LogFile
30
- from twisted .internet import reactor , defer , main as ti_main
30
+ from twisted .internet import reactor , defer , main as ti_main , threads , task
31
31
from twisted .internet .protocol import ProcessProtocol , Protocol , Factory
32
32
from twisted .protocols .basic import LineReceiver , Int32StringReceiver
33
33
from twisted .internet .serialport import SerialPort
@@ -83,6 +83,7 @@ class StatsAndSelectorFactory(Factory):
83
83
"""
84
84
85
85
def __init__ (self , profile , wlans , link_domain ):
86
+ self .wlans = tuple (wlans )
86
87
self .ant_sel_cb_list = []
87
88
self .rssi_cb_l = []
88
89
@@ -96,6 +97,46 @@ def __init__(self, profile, wlans, link_domain):
96
97
# CLI title
97
98
self .cli_title = 'WFB-ng_%s @%s %s [%s]' % (settings .common .version , profile , ', ' .join (wlans ), link_domain )
98
99
100
+ # RF module temperature by rf_path
101
+ self .rf_temperature = {}
102
+
103
+ self .lc = task .LoopingCall (self .read_temperature )
104
+ self .lc .start (settings .common .temp_measurement_interval , now = True )
105
+
106
+ def _cleanup (self ):
107
+ self .lc .stop ()
108
+
109
+ def read_temperature (self ):
110
+ def _read_temperature ():
111
+ res = {}
112
+ for idx , wlan in enumerate (self .wlans ):
113
+ fname = '/proc/net/rtl88x2eu/%s/thermal_state' % (wlan ,)
114
+ try :
115
+ with open (fname ) as fd :
116
+ for line in fd :
117
+ line = line .strip ()
118
+ if not line :
119
+ continue
120
+
121
+ d = {}
122
+ for f in line .split (',' ):
123
+ k , v = f .split (':' , 1 )
124
+ d [k .strip ()] = int (v .strip ())
125
+
126
+ ant_id = (idx << 8 ) + d ['rf_path' ]
127
+ res [ant_id ] = d ['temperature' ]
128
+ except FileNotFoundError :
129
+ pass
130
+ except Exception as v :
131
+ reactor .callFromThread (log .err , v , 'Unable to parse %s:' % (fname ,))
132
+ return res
133
+
134
+ def _got_temp (temp_d ):
135
+ self .rf_temperature = temp_d
136
+
137
+ return threads .deferToThread (_read_temperature ).addCallback (_got_temp )
138
+
139
+
99
140
def add_ant_sel_cb (self , ant_sel_cb ):
100
141
self .ant_sel_cb_list .append (ant_sel_cb )
101
142
ant_sel_cb (self .tx_sel )
@@ -208,7 +249,10 @@ def update_tx_stats(self, tx_id, packet_stats, ant_latency):
208
249
209
250
# Send stats to CLI sessions
210
251
for s in self .ui_sessions :
211
- s .send_stats (dict (type = 'tx' , id = tx_id , packets = packet_stats , latency = ant_latency ))
252
+ s .send_stats (dict (type = 'tx' , id = tx_id ,
253
+ packets = packet_stats ,
254
+ latency = ant_latency ,
255
+ rf_temperature = self .rf_temperature ))
212
256
213
257
214
258
@@ -506,21 +550,33 @@ def init(profiles, wlans):
506
550
yield init_wlans (max_bw , wlans )
507
551
508
552
dl = []
553
+ sockets = []
554
+ ant_sel_l = []
555
+
556
+ def _cleanup (x ):
557
+ for s in sockets :
558
+ s .stopListening ()
559
+
560
+ for f in ant_sel_l :
561
+ f ._cleanup ()
562
+
563
+ return x
509
564
510
565
for profile , service_list in services :
511
566
# Domain wide antenna selector
512
567
profile_cfg = getattr (settings , profile )
513
568
ant_sel_f = StatsAndSelectorFactory (profile , wlans , profile_cfg .link_domain )
569
+ ant_sel_l .append (ant_sel_f )
514
570
link_id = int .from_bytes (hashlib .sha1 (profile_cfg .link_domain .encode ('utf-8' )).digest ()[:3 ], 'big' )
515
571
516
572
if profile_cfg .stats_port :
517
- reactor .listenTCP (profile_cfg .stats_port , ant_sel_f )
573
+ sockets . append ( reactor .listenTCP (profile_cfg .stats_port , ant_sel_f ) )
518
574
519
575
for service_name , service_type , srv_cfg in service_list :
520
576
log .msg ('Starting %s/%s@%s on %s' % (profile , service_name , profile_cfg .link_domain , ', ' .join (wlans )))
521
577
dl .append (defer .maybeDeferred (type_map [service_type ], service_name , srv_cfg , wlans , link_id , ant_sel_f ))
522
578
523
- yield defer .gatherResults (dl , consumeErrors = True ).addErrback (lambda f : f .trap (defer .FirstError ) and f .value .subFailure )
579
+ yield defer .gatherResults (dl , consumeErrors = True ).addBoth ( _cleanup ). addErrback (lambda f : f .trap (defer .FirstError ) and f .value .subFailure )
524
580
525
581
526
582
def init_udp_direct_tx (service_name , cfg , wlans , link_id , ant_sel_f ):
0 commit comments