Contiki-NG
Loading...
Searching...
No Matches
tsch-log.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014, SICS Swedish ICT.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * This file is part of the Contiki operating system.
30 *
31 */
32
33/**
34 * \file
35 * Log functions for TSCH, meant for logging from interrupt
36 * during a timeslot operation. Saves ASN, slot and link information
37 * and adds the log to a ringbuf for later printout.
38 * \author
39 * Simon Duquennoy <simonduq@sics.se>
40 *
41 */
42
43/**
44 * \addtogroup tsch
45 * @{
46*/
47
48#include "contiki.h"
49#include <stdio.h>
50#include <inttypes.h>
51#include "net/mac/tsch/tsch.h"
52#include "lib/ringbufindex.h"
53#include "sys/log.h"
54
55#if TSCH_LOG_PER_SLOT
56
57PROCESS_NAME(tsch_pending_events_process);
58
59/* Check if TSCH_LOG_QUEUE_LEN is a power of two */
60#if (TSCH_LOG_QUEUE_LEN & (TSCH_LOG_QUEUE_LEN - 1)) != 0
61#error TSCH_LOG_QUEUE_LEN must be power of two
62#endif
63static struct ringbufindex log_ringbuf;
64static struct tsch_log_t log_array[TSCH_LOG_QUEUE_LEN];
65static int log_dropped = 0;
66static int log_active = 0;
67
68/*---------------------------------------------------------------------------*/
69/* Process pending log messages */
70void
72{
73 static int last_log_dropped = 0;
74 int16_t log_index;
75 /* Loop on accessing (without removing) a pending input packet */
76 if(log_dropped != last_log_dropped) {
77 printf("[WARN: TSCH-LOG ] logs dropped %u\n", log_dropped);
78 last_log_dropped = log_dropped;
79 }
80 while((log_index = ringbufindex_peek_get(&log_ringbuf)) != -1) {
81 struct tsch_log_t *log = &log_array[log_index];
82 if(log->link == NULL) {
83 printf("[INFO: TSCH-LOG ] {asn %02x.%08"PRIx32" link-NULL} ", log->asn.ms1b, log->asn.ls4b);
84 } else {
85 struct tsch_slotframe *sf = tsch_schedule_get_slotframe_by_handle(log->link->slotframe_handle);
86 printf("[INFO: TSCH-LOG ] {asn %02x.%08"PRIx32" link %2u %3u %3u %2u %2u ch %2u} ",
87 log->asn.ms1b, log->asn.ls4b,
88 log->link->slotframe_handle, sf ? sf->size.val : 0,
89 log->burst_count, log->link->timeslot + log->burst_count, log->channel_offset,
90 log->channel);
91 }
92 switch(log->type) {
93 case tsch_log_tx:
94 printf("%s-%u-%u tx ",
95 linkaddr_cmp(&log->tx.dest, &linkaddr_null) ? "bc" : "uc", log->tx.is_data, log->tx.sec_level);
97 printf("->");
98 log_lladdr_compact(&log->tx.dest);
99 printf(", len %3u, seq %3u, st %d %2d",
100 log->tx.datalen, log->tx.seqno, log->tx.mac_tx_status, log->tx.num_tx);
101 if(log->tx.drift_used) {
102 printf(", dr %3d", log->tx.drift);
103 }
104 printf("\n");
105 break;
106 case tsch_log_rx:
107 printf("%s-%u-%u rx ",
108 log->rx.is_unicast == 0 ? "bc" : "uc", log->rx.is_data, log->rx.sec_level);
109 log_lladdr_compact(&log->rx.src);
110 printf("->");
111 log_lladdr_compact(log->rx.is_unicast ? &linkaddr_node_addr : NULL);
112 printf(", len %3u, seq %3u",
113 log->rx.datalen, log->rx.seqno);
114 printf(", edr %3d", (int)log->rx.estimated_drift);
115 if(log->rx.drift_used) {
116 printf(", dr %3d\n", log->rx.drift);
117 } else {
118 printf("\n");
119 }
120 break;
121 case tsch_log_message:
122 printf("%s\n", log->message);
123 break;
124 }
125 /* Remove input from ringbuf */
126 ringbufindex_get(&log_ringbuf);
127 }
128}
129/*---------------------------------------------------------------------------*/
130/* Prepare addition of a new log.
131 * Returns pointer to log structure if success, NULL otherwise */
132struct tsch_log_t *
134{
135 int log_index = ringbufindex_peek_put(&log_ringbuf);
136 if(log_index != -1) {
137 struct tsch_log_t *log = &log_array[log_index];
138 log->asn = tsch_current_asn;
139 log->link = current_link;
140 log->burst_count = tsch_current_burst_count;
141 log->channel = tsch_current_channel;
142 log->channel_offset = tsch_current_channel_offset;
143 return log;
144 } else {
145 log_dropped++;
146 return NULL;
147 }
148}
149/*---------------------------------------------------------------------------*/
150/* Actually add the previously prepared log */
151void
152tsch_log_commit(void)
153{
154 if(log_active == 1) {
155 ringbufindex_put(&log_ringbuf);
156 process_poll(&tsch_pending_events_process);
157 }
158}
159/*---------------------------------------------------------------------------*/
160/* Initialize log module */
161void
162tsch_log_init(void)
163{
164 if(log_active == 0) {
165 ringbufindex_init(&log_ringbuf, TSCH_LOG_QUEUE_LEN);
166 log_active = 1;
167 }
168}
169/*---------------------------------------------------------------------------*/
170/* Stop log module */
171void
172tsch_log_stop(void)
173{
174 if(log_active == 1) {
176 log_active = 0;
177 }
178}
179
180#endif /* TSCH_LOG_PER_SLOT */
181/** @} */
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
Definition linkaddr.c:48
bool linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
Definition linkaddr.c:69
const linkaddr_t linkaddr_null
The null link-layer address.
void log_lladdr_compact(const linkaddr_t *lladdr)
Logs a link-layer address with a compact format.
Definition log.c:147
#define PROCESS_NAME(name)
Declare the name of a process.
Definition process.h:286
void process_poll(struct process *p)
Request a process to be polled.
Definition process.c:375
void tsch_log_commit(void)
Actually add the previously prepared log.
struct tsch_slotframe * tsch_schedule_get_slotframe_by_handle(uint16_t handle)
Looks up a slotframe by handle.
void tsch_log_init(void)
Initialize log module.
struct tsch_log_t * tsch_log_prepare_add(void)
Prepare addition of a new log.
void tsch_log_process_pending(void)
Process pending log messages.
void tsch_log_stop(void)
Stop logging module.
Header file for the logging system.
int ringbufindex_peek_get(const struct ringbufindex *r)
Return the index of the first element which will be removed if calling ringbufindex_get.
void ringbufindex_init(struct ringbufindex *r, uint8_t size)
Initialize a ring buffer.
int ringbufindex_put(struct ringbufindex *r)
Put one element to the ring buffer.
int ringbufindex_get(struct ringbufindex *r)
Remove the first element and return its index.
int ringbufindex_peek_put(const struct ringbufindex *r)
Check if there is space to put an element.
Header file for the ringbufindex library.
Structure for a log.
Definition tsch-log.h:76
802.15.4e slotframe (contains links)
Definition tsch-types.h:84
Main API declarations for TSCH.