1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include <pw_log_tokenized/base64.h>
16 #include <pw_log_tokenized/config.h>
17 #include <pw_log_tokenized/handler.h>
18 #include <pw_log_tokenized/metadata.h>
19 #include <pw_span/span.h>
20 #include <pw_sync/interrupt_spin_lock.h>
21 #include <pw_tokenizer/base64.h>
22 #include <zephyr/logging/log_core.h>
23
24 namespace pw::log_zephyr {
25 namespace {
26
27 // The Zephyr console may output raw text along with Base64 tokenized messages,
28 // which could interfere with detokenization. Output a character to mark the end
29 // of a Base64 message.
30 constexpr char kEndDelimiter = '#';
31
32 sync::InterruptSpinLock log_encode_lock;
33
34 } // namespace
35
pw_log_tokenized_HandleLog(uint32_t metadata,const uint8_t log_buffer[],size_t size_bytes)36 extern "C" void pw_log_tokenized_HandleLog(uint32_t metadata,
37 const uint8_t log_buffer[],
38 size_t size_bytes) {
39 pw::log_tokenized::Metadata meta(metadata);
40
41 // Encode the tokenized message as Base64.
42 const InlineBasicString base64_string =
43 log_tokenized::PrefixedBase64Encode(log_buffer, size_bytes);
44
45 if (base64_string.empty()) {
46 return;
47 }
48
49 // TODO(asemjonovs): https://github.com/zephyrproject-rtos/zephyr/issues/59454
50 // Zephyr frontend should protect messages from getting corrupted
51 // from multiple threads.
52 log_encode_lock.lock();
53 // _is_raw is set to 0 here because the print string is required to be a
54 // string literal if _is_raw is set to 1.
55 Z_LOG_PRINTK(/*_is_raw=*/0, "%s%c", base64_string.c_str(), kEndDelimiter);
56 log_encode_lock.unlock();
57 }
58
59 } // namespace pw::log_zephyr
60