Project

General

Profile

Diag » History » Version 13

laforge, 12/23/2016 03:29 PM
logs mask updating in linux programs

1 4 laforge
{{>toc}}
2
3 1 laforge
h1. Diag
4
5 12 laforge
Qualcomm _Diag_ is the qualcomm diagnostics interface built into many Qualcomm based chipsets (or rather their software) for a long time (more than a decade).  It is not publicly documented, but there are tools from Qualcomm (QPST, QXDM) as well as proprietary third-party tools and some Free Softare projects that implement parts of it.
6
7
The general idea is that there is some physical transport medium between the chipset/modem and an external PC, and the PC can request certain diagnostic information to be sent via that physical transport.  Initially, this transport was a dedicated serial port/UART.  Later, this became a virtual serial port over USB.
8
9
In a single-processor Modem (with only a baseband processor) it is rather simple: Some software on the baseband processor implements the DIAG protocol, and responds to any related requests received on the DIAG port.
10
11
In a multi-processor situation (like the MDM9215/MDM9x07 with their Linux-running Cortex-A5), the situation becomes slightly more complex.  First of all, not only the external host/PC might want to consume DIAG information, but also code on the Linux processor inside the chip.  Furthermore, code in the Linux processor might also want to offer some DIAG information towards the external host/PC.
12
13
The Qualcomm Android Linux kernel (usd even on the non-Android devices) implements several related kernel drivers, see [[Qualcomm_Kernel#diag]]
14
15
In userspace on the Linux inside the modem, there is a (unfortunately again non-free) library called @libdiag@ which offers some convenience API for programs to either consume DIAG or to generate/respond to DIAG received from the host/PC.  Luckily the library is not performing much required functionality, so third-party programs like "SnoopSnitch":https://opensource.srlabs.de/projects/snoopsnitch have managed to talk directly to the @/dev/diag@ kernel device without needing to use that non-free library.
16
17 6 laforge
18 1 laforge
h2. Acronyms
19
20
|DCI|Diag Consumer Interface|
21
22 4 laforge
h2. Child Pages
23
24
{{child_pages()}}
25 6 laforge
26
h2. Subsystems
27
28
h3. Logging
29
30
Logging works by so-called log-codes.  The Log code identifies the source/category of the logged information.  Log codes are 16bit unsigned integers.
31
32
|_.Base Code|_.Purpose|
33
|0x1000|CDMA 1x|
34
|0x4000|WCDMA|
35
|0x5000|GSM|
36
|0x6000|Location Based Services|
37
|0x7000|UMTS|
38
|0x8000|TDMA|
39
|0xA000|DTV|
40
|0xB000|APPS|
41
|0xB010|LTE (until 0xB1FF)|
42
|0xB400|WIMAX|
43
|0xC000|DSP|
44
|0xD000|TD-SCDMA (until 0xD1FF)|
45
|0xF000|LOG TOOLS|
46 4 laforge
47 3 laforge
h2. Kernel support
48
49 1 laforge
See [[Qualcomm_Kernel#diag]]
50
51 4 laforge
h2. Library
52 1 laforge
53 4 laforge
There is @/usr/lib/libdiag.so.1@ which is linked by virtually any Qualcomm or Quectel proprietary program running on the Linux in the Modem.
54
55
it offers the follwing symbols:
56
<pre>
57 9 laforge
log_submit
58
pools
59
diag_vote_md_real_time
60
DiagSvc_Free
61
diag_dci_get_real_time_status_proc
62
diagpkt_subsys_get_delayed_rsp_id
63
diagpkt_subsys_alloc_v2
64
diag_read_mask_file_list
65
diagpkt_subsys_get_cmd_code
66
Diag_LSM_Event_DeInit
67
diag_wakelock_init
68
mask_file2
69
cleanup_mask
70
diag_register_dci_client
71
mask_file
72
msg_send_var
73
diagpkt_subsys_alloc_v2_delay
74
log_to_memory
75
diagpkt_alloc
76
db_thread_initialized
77
_init
78
stop_cond
79
diag_hdlc_toggle
80
diag_wakelock_acquire
81
parser_state
82
num_bytes_read
83
log_update_dci_mask
84
send_mask_modem
85
qsr4_db_file_fd
86
qsr4_db_write_buf_pool
87
event_update_mask
88
mask_sync_initialize
89
file_name_curr
90
msg_sprintf
91
mask_file_mdm2
92
event_report_payload
93
DiagSvc_Malloc_Init
94
diag_release_dci_client
95
update_sync_mask
96
diag_send_socket_data
97
diag_register_dci_stream_proc
98
DiagSvc_Malloc
99
buffer_init
100
msg_mask_tbl_size
101
curr_write_idx
102
diag_logger_flush
103
pool0_buffers
104
log_set_length
105
hdlc_disabled
106
fd_qsr4_xml
107
qsr4_xml_file_name
108
diagpkt_LSM_process_request
109
diag_get_real_time_status
110
Diag_LSM_Pkt_DeInit
111
flush_buffer
112
diag_callback_send_data
113
dci_cumulative_event_mask
114
dci_transaction_id
115
diag_get_health_stats_proc
116
stop_mutex
117
diag_get_health_stats
118
log_free
119
mask_file_mdm
120
diagpkt_subsys_reset_delayed_rsp_id
121
diag_logger_init
122
dummy_handler
123
diag_send_data
124
diag_kill_qshrink4_threads
125
ts_get_lohi
126
diagpkt_subsys_set_rsp_cnt
127
diag_notify_parser_thread
128
diag_disable_all_logs
129
diagpkt_commit
130
proc_type
131
diag_log_stream_config
132
log_status
133
msg_send
134
WriteToDisk
135
Diag_LSM_Log_DeInit
136
fd_dev
137
diag_dci_get_real_time_status
138
qsr4_db_cmd_req_buf
139
diagpkt_subsys_alloc
140
get_sync_mask
141
diag_get_dci_support_list_proc
142
diag_get_real_time_status_proc
143
qsr4_read_db_mutex
144
dir_name
145
diag_set_socket_fd
146
diag_switch_logging_proc
147
diagpkt_get_cmd_code
148
diagpkt_subsys_get_status
149
in_read
150
Diag_LSM_Event_Init
151
diag_dci_error_type
152
diag_disable_all_events
153
pid_file
154
qsr4_db_parser_thread_hdl
155
num_dci_proc
156
in_wait_for_peripheral_status
157
write_in_progress
158
Diag_LSM_Pkt_Init
159
max_file_size
160
ts_get
161
diag_get_event_status
162
log_set_timestamp
163
curr_read
164
diag_register_dci_signal_data
165
diagpkt_shorten
166
curr_read_idx
167
pool1_buffers
168
lookup_pkt_rsp_transaction
169
diag_disable_console
170
max_file_num
171
diag_send_dci_async_req
172
log_get_length
173
diagpkt_set_cmd_code
174
diagpkt_subsys_set_status
175
diag_peripheral_buffering_drain_immediate
176
event_mask
177
log_commit
178
min_file_size
179
gdwClientID
180
msg_send_ts
181
read_thread_hdl
182
valid_token
183
add_guid_to_qshrink4_header
184
msg_mask
185
file_list_size
186
log_shorten
187
diagpkt_free
188
fd_socket
189
flush_log
190
create_diag_qshrink4_db_parser_thread
191
diag_read_mask_file
192
diag_deregister_dci_signal_data
193
num_dci_clients_event
194
proc_name
195
diag_lsm_dci_deinit
196
diag_wakelock_release
197
read_buffer
198
diagpkt_subsys_get_id
199
peripheral_name
200
Diag_LSM_Init
201
diag_configure_peripheral_buffering_tx_mode
202
curr_write
203
diag_callback_send_data_hdlc
204
qsr_msg_send_1
205
qsr_msg_send_2
206
db_write_thread_hdl
207
Diag_LSM_Msg_Init
208
qsr_msg_send_3
209
token_list
210
diag_has_remote_device
211
diag_register_remote_callback
212
in_write
213
file_list
214
process_incoming_data
215
delete_log
216
log_to_device
217
logging_mode
218
log_set_code
219
diagpkt_delay_commit
220
flush_in_progress
221
diag_send_to_output
222
diag_get_max_channels
223
Diag_LSM_Log_Init
224
file_name_del
225
uart_logging_proc
226
DiagSvc_Malloc_Exit
227
output_dir
228
diag_event_stream_config
229
Diag_LSM_DeInit
230
diagpkt_tbl_reg
231
diag_dci_vote_real_time
232
kill_thread
233
count_written_bytes_1
234
qsr_msg_send
235
event_report
236
diag_fd
237
event_update_dci_mask
238
diag_get_dci_support_list
239
log_update_mask
240
parse_data_for_qsr4_db_file_op_rsp
241
file_list_index
242
rename_file_names
243
diag_register_callback
244
diag_lsm_dci_init
245
diag_vote_md_real_time_proc
246
msg_send_1
247
msg_send_2
248
msg_send_3
249
diag_is_wakelock_init
250
disk_write_hdl
251
diag_register_socket_cb
252
msg_update_mask
253
diag_set_peripheral_mask
254
log_alloc
255
dci_client_tbl
256
do_mask_sync
257
write_qshrink_header
258
fd_uart
259
qsr_msg_send_var
260
periph_info
261
diag_logger_exit
262
send_empty_mask
263
gnDiag_LSM_Event_Initialized
264
diagpkt_err_rsp
265
diag_logger_write
266
diag_get_log_status
267
qsr4_read_db_cond
268
rename_dir_name
269
diag_wakelock_destroy
270
diag_register_dci_stream
271
log_get_code
272
msg_mask_tbl
273
Diag_LSM_Msg_DeInit
274
to_integer
275
_fini
276
diag_get_peripheral_name_from_mask
277
count_written_bytes
278
diag_switch_logging
279
fd_md
280 4 laforge
</pre>
281 5 laforge
282 10 laforge
h3. Initialization
283
284
|_.Function|_.Purpose|
285
|Diag_LSM_Init()|Registering with Diag which gives the client a handle to the Diag. Called once per process|
286
287 5 laforge
h3. Logging Service API
288
289
This is about sending log messages via the Diag interface.
290
291
|_.Function|_.Purpose|
292
|log_alloc(u16 code, len)|Allocate a buffer + fill header|
293
|log_shorten(ptr, len)|Shorten the length of a previously allocated buffer|
294
|log_commit(ptr)|Send the log to diag|
295
|log_free(ptr)|Free a buffer previously allocated with log_alloc()|
296
|log_submit(ptr)|Convenience wrapper around log_alloc()/memcpy()/log_commit()|
297
298 7 laforge
On the [[EC25]], it seems only the following Linux programs use the avove API to generate logs via Diag:
299
* @/usr/bin/cnss_diag@
300
* @/usr/bin/ftmdaemon@
301
* @/usr/bin/mbimd@
302
* @/usr/bin/test_diag@
303
304 5 laforge
h3. Diag Consumer Interface
305
306 1 laforge
This seems to be about implementing a program that consumes Diag events. You can register to certain events/masks and then receive the related information in call-backs.
307 8 laforge
308
|_.Function|_.Description|
309
|diag_lsm_dci_init()|Initialize DCI subsystem of libdiag|
310 11 laforge
|diag_register_dci_client()|Register a DCI client, issues DIAG_IOCTL_DCI_REG to /dev/diag|
311
|diag_get_dci_support_list()|Get list of peripherals supported, issues DIAG_IOCTL_DCI_SUPPORT to /dev/diag|
312
|diag_register_dci_stream()|Register call-backs for events and logs, writes to /dev/diag|
313
|diag_event_stream_config()|Set up event streaming to the client, writes to /dev/diag|
314
|diag_log_stream_config()|Specify array of requested log codes, writes to /dev/diag|
315
|diag_get_health_stats()|Get statistics about missed/succeeded logs and events, issues DIAG_IOCTL_DCI_HEALTH_STATS to /dev/diag|
316 8 laforge
|diag_register_dci_signal_data()|Request OS signal when DCI data is received|
317 13 laforge
318
h3. How to configure/enable logging
319
320
An external DIAG receiver (e.g. on the host PC) can configure which particular log messages he wants to receive and which not.
321
322
For the Linux programs using the libdiag.so logging service API, this means that every time an external DIAG log receiver updates the DIAG mask, that mask is passed into every program using libdiag, so they can update their log masks.  This is done by reading on the @/dev/diag@ device and calling into  @process_diag_payload()@ which in turn calls @log_update_mask()@ pr @msg_update_mask()@ which updates the @log_mask@ array.
323
324
When a given log line is created, exactly that @log_mask@ or @read_mask@ array is consulted to check if the given subsystem is enabled or not.
Add picture from clipboard (Maximum size: 48.8 MB)