Contiki 3.x
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 #include "contiki.h"
44 #include <stdio.h>
45 #include "net/mac/tsch/tsch.h"
46 #include "net/mac/tsch/tsch-queue.h"
48 #include "net/mac/tsch/tsch-log.h"
49 #include "net/mac/tsch/tsch-packet.h"
50 #include "net/mac/tsch/tsch-schedule.h"
51 #include "net/mac/tsch/tsch-slot-operation.h"
52 #include "lib/ringbufindex.h"
53 
54 #if TSCH_LOG_LEVEL >= 1
55 #define DEBUG DEBUG_PRINT
56 #else /* TSCH_LOG_LEVEL */
57 #define DEBUG DEBUG_NONE
58 #endif /* TSCH_LOG_LEVEL */
59 #include "net/net-debug.h"
60 
61 #if TSCH_LOG_LEVEL >= 2 /* Skip this file for log levels 0 or 1 */
62 
63 PROCESS_NAME(tsch_pending_events_process);
64 
65 /* Check if TSCH_LOG_QUEUE_LEN is a power of two */
66 #if (TSCH_LOG_QUEUE_LEN & (TSCH_LOG_QUEUE_LEN - 1)) != 0
67 #error TSCH_LOG_QUEUE_LEN must be power of two
68 #endif
69 static struct ringbufindex log_ringbuf;
70 static struct tsch_log_t log_array[TSCH_LOG_QUEUE_LEN];
71 static int log_dropped = 0;
72 
73 /*---------------------------------------------------------------------------*/
74 /* Process pending log messages */
75 void
76 tsch_log_process_pending(void)
77 {
78  static int last_log_dropped = 0;
79  int16_t log_index;
80  /* Loop on accessing (without removing) a pending input packet */
81  if(log_dropped != last_log_dropped) {
82  printf("TSCH:! logs dropped %u\n", log_dropped);
83  last_log_dropped = log_dropped;
84  }
85  while((log_index = ringbufindex_peek_get(&log_ringbuf)) != -1) {
86  struct tsch_log_t *log = &log_array[log_index];
87  if(log->link == NULL) {
88  printf("TSCH: {asn-%x.%lx link-NULL} ", log->asn.ms1b, log->asn.ls4b);
89  } else {
90  struct tsch_slotframe *sf = tsch_schedule_get_slotframe_by_handle(log->link->slotframe_handle);
91  printf("TSCH: {asn-%x.%lx link-%u-%u-%u-%u ch-%u} ",
92  log->asn.ms1b, log->asn.ls4b,
93  log->link->slotframe_handle, sf ? sf->size.val : 0, log->link->timeslot, log->link->channel_offset,
94  tsch_calculate_channel(&log->asn, log->link->channel_offset));
95  }
96  switch(log->type) {
97  case tsch_log_tx:
98  printf("%s-%u-%u %u tx %d, st %d-%d",
99  log->tx.dest == 0 ? "bc" : "uc", log->tx.is_data, log->tx.sec_level,
100  log->tx.datalen,
101  log->tx.dest,
102  log->tx.mac_tx_status, log->tx.num_tx);
103  if(log->tx.drift_used) {
104  printf(", dr %d", log->tx.drift);
105  }
106  printf("\n");
107  break;
108  case tsch_log_rx:
109  printf("%s-%u-%u %u rx %d",
110  log->rx.is_unicast == 0 ? "bc" : "uc", log->rx.is_data, log->rx.sec_level,
111  log->rx.datalen,
112  log->rx.src);
113  if(log->rx.drift_used) {
114  printf(", dr %d", log->rx.drift);
115  }
116  printf(", edr %d\n", (int)log->rx.estimated_drift);
117  break;
118  case tsch_log_message:
119  printf("%s\n", log->message);
120  break;
121  }
122  /* Remove input from ringbuf */
123  ringbufindex_get(&log_ringbuf);
124  }
125 }
126 /*---------------------------------------------------------------------------*/
127 /* Prepare addition of a new log.
128  * Returns pointer to log structure if success, NULL otherwise */
129 struct tsch_log_t *
130 tsch_log_prepare_add(void)
131 {
132  int log_index = ringbufindex_peek_put(&log_ringbuf);
133  if(log_index != -1) {
134  struct tsch_log_t *log = &log_array[log_index];
135  log->asn = current_asn;
136  log->link = current_link;
137  return log;
138  } else {
139  log_dropped++;
140  return NULL;
141  }
142 }
143 /*---------------------------------------------------------------------------*/
144 /* Actually add the previously prepared log */
145 void
146 tsch_log_commit(void)
147 {
148  ringbufindex_put(&log_ringbuf);
149  process_poll(&tsch_pending_events_process);
150 }
151 /*---------------------------------------------------------------------------*/
152 /* Initialize log module */
153 void
154 tsch_log_init(void)
155 {
156  ringbufindex_init(&log_ringbuf, TSCH_LOG_QUEUE_LEN);
157 }
158 
159 #endif /* TSCH_LOG_LEVEL */
void process_poll(struct process *p)
Request a process to be polled.
Definition: process.c:371
Private TSCH definitions (meant for use by TSCH implementation files only) ...
Header file for the ringbufindex library
PROCESS_NAME(sample_process)
Process the sampler runs as.
A set of debugging macros for the netstack
#define NULL
The null pointer.