static int8_t blink_msg_handler(Message *msg) { switch (msg->type){ case 1: { pid = msg->did; blink_state = 0; printf("LED_RED_TOGGLE\n"); sys_timer_start(0, 1024L, 1); break; } case 2: { sys_timer_stop(0); printf("Blink Stop\n"); break; } case 3: { printf("LED_GREEN_TOGGLE"); break; } default: return -1; } return 0; }
static int8_t pre_blink_msg_handler(void *state, Message *msg) { switch (msg->type){ case MSG_INIT: { sys_timer_start(BLINK_TID, BLINK_TIMER_INTERVAL, TIMER_REPEAT); break; } case MSG_FINAL: { sys_timer_stop(BLINK_TID); break; } case MSG_TIMER_TIMEOUT: { sys_led(LED_GREEN_TOGGLE); break; } default: return -EINVAL; } return SOS_OK; }
void static inline go_to_sleep(){ // stop / disable peripherals cli(); // disable interrupts sys_timer_stop(); _delay_us(300); // small delay in order for the colorduino to be ready for transmission display_sleep(); while(uart_async_run()); // put display to sleep _delay_us(60); p_out_low(); interface_disable(); // turn leds + display off // disable UART UCSRnB = 0x00; //disable Rx and Tx // enable external pin change interrupt on PA7: PCINT7 PCMSK0 |= (1<<PCINT7); // set interrupt mask for PA7 PCICR |= (1<<PCIE0); // enable pin change interrupt 0 // go to sleep set_sleep_mode(SLEEP_MODE_STANDBY); sleep_enable(); sei(); sleep_cpu(); sleep_disable(); // wake up cli(); // disable interrupts PCICR = 0x00; // disable pin change interrupt PCMSK0 = 0x00; // restart peripherals UCSRnB = (1<<RXENn) | (1<<TXENn); //enable Rx and Tx interface_init(); display_wake_up(); sys_timer_start(); green_led_on(); sei(); // reenable interrupts }
static int8_t tpsn_net_module_handler(void *state, Message *msg) { app_state_t *s = (app_state_t *) state; MsgParam *p = (MsgParam*)(msg->data); /** * Switch to the correct message handler */ switch (msg->type) { case MSG_INIT: { msg_adv_level_t* msg_adv_level = (msg_adv_level_t*)sys_malloc(sizeof(msg_adv_level_t)); DEBUG("TPSN NET: Started\n"); s->pid = msg->did; s->level = -1; s->parent_id = 0; s->last_refresh = 0; s->sync_state = INIT; s->current_seq_no = 0; // try to join the sync tree msg_adv_level->level = s->level; sys_post_net(s->pid, MSG_ADV_LEVEL, sizeof(msg_adv_level_t), msg_adv_level, SOS_MSG_RELEASE, BCAST_ADDRESS); sys_timer_start(ADV_TIMER_ID, 5*1024, TIMER_REPEAT); return SOS_OK; } case MSG_GET_GLOBAL_TIME: { DEBUG("TPSN_NET: state: %d\n", s->sync_state); msg_global_time_t* time_msg = (msg_global_time_t*)msg->data; msg_global_time_t* time_reply_msg = (msg_global_time_t*)sys_malloc(sizeof(msg_global_time_t)); if(s->sync_state == SYNCED || s->sync_state == SYNCING) { // we are synced, and thus had at least one time sync exchange // if we are level 1, then just return our time if(s->level == 1) { time_reply_msg->time = time_msg->time; time_reply_msg->refreshed = 0; } else { uint32_t delta_refresh = 0; uint32_t cur_time = sys_time32(); // check for overflow if(cur_time < s->last_refresh) { cur_time += 0x7F000000; } delta_refresh = cur_time - s->last_refresh; // only try to refresh if we are not already syncing. if (s->sync_state == SYNCED && delta_refresh > REFRESH_INTERVAL) { DEBUG("TPSN_NET: Refresh needed refresh: %d\n", delta_refresh); s->sync_state = SYNCING; start_sync(); } // even though we might be syncing, reply with the current estimate. time_reply_msg->time = time_msg->time + s->clock_drift; time_reply_msg->refreshed = delta_refresh; } } else { time_reply_msg->time = NOT_SYNCED; time_reply_msg->refreshed = NOT_SYNCED; } DEBUG("TPSN_NET: converted time for module %d, drift %d, refreshed %d, global time %d, sync state %d\n", msg->sid, s->clock_drift, time_reply_msg->refreshed, time_reply_msg->time, s->sync_state); sys_post(msg->sid, MSG_GLOBAL_TIME_REPLY, sizeof(msg_global_time_t), time_reply_msg, SOS_MSG_RELEASE); return SOS_OK; } case MSG_TIMESTAMP: { DEBUG("TPSN_NET: state: %d\n", s->sync_state); LED_DBG(LED_RED_TOGGLE); tpsn_req_t *tpsn_req_ptr = (tpsn_req_t *)msg->data; switch(tpsn_req_ptr->type) { case TPSN_REQUEST: { DEBUG("TPSN_NET: Received TPSN_REQUEST (seq_no=%d) from node %d\n", tpsn_req_ptr->seq_no, msg->saddr); DEBUG("TPSN_NET: Transmitting TPSN_REPLY to node %d at time %d\n", msg->saddr, sys_time32()); tpsn_reply_t *tpsn_reply_ptr = (tpsn_reply_t *)sys_malloc(sizeof(tpsn_reply_t)); memcpy(tpsn_reply_ptr->previous_time, tpsn_req_ptr->time, sizeof(tpsn_req_ptr->time)); tpsn_reply_ptr->type = TPSN_REPLY; tpsn_reply_ptr->seq_no = tpsn_req_ptr->seq_no; if(msg->saddr == UART_ADDRESS) { sys_post_uart(s->pid, MSG_TIMESTAMP, sizeof(tpsn_reply_t), tpsn_reply_ptr, SOS_MSG_RELEASE, msg->saddr); } else { sys_post_net(s->pid, MSG_TIMESTAMP, sizeof(tpsn_reply_t), tpsn_reply_ptr, SOS_MSG_RELEASE, msg->saddr); } break; } case TPSN_REPLY: { if(s->sync_state == SYNCING || s->sync_state == INIT_SYNCING) { //LED_DBG(LED_YELLOW_TOGGLE); DEBUG("TPSN: Received TPSN_REPLY from node %d\n", msg->saddr); tpsn_reply_t *tpsn_reply_ptr = (tpsn_reply_t *)msg->data; if (tpsn_reply_ptr->seq_no == s->current_seq_no) { sys_timer_stop(SYNC_TIMER_ID); s->current_seq_no++; //T1=tpsn_reply_ptr->previous_time[0] //T2=tpsn_reply_ptr->previous_time[1] //T3=tpsn_reply_ptr->time[0] //T4=tpsn_reply_ptr->time[1] //CLOCK_DRIFT = ((T2 - T1) - (T4 - T3))/2 //PROPAGATION_DELAY=((T2 - T1) + (T4 - T3))/2 //Take care of overflow in the node that sent the TPSN request (T1 > T4) if(tpsn_reply_ptr->previous_time[0] > tpsn_reply_ptr->time[1]) tpsn_reply_ptr->time[1] += INT_MAX_GTIME; //Take care of overflow in the node that sent the TPSN reply (T2 > T3) if(tpsn_reply_ptr->previous_time[1] > tpsn_reply_ptr->time[0]) tpsn_reply_ptr->time[0] += INT_MAX_GTIME; s->clock_drift = ( ((int32_t)tpsn_reply_ptr->previous_time[1] - (int32_t)tpsn_reply_ptr->previous_time[0]) - ((int32_t)tpsn_reply_ptr->time[1] - (int32_t)tpsn_reply_ptr->time[0]) )/2; s->last_refresh = sys_time32(); s->sync_state = SYNCED; DEBUG("TPSN: The clock offset for node %d is %d\n", msg->saddr, s->clock_drift); } } break; } default: { DEBUG("Received unknown packet\n"); break; } } } case MSG_TIMER_TIMEOUT: { DEBUG("TPSN_NET: state: %d\n", s->sync_state); switch(p->byte) { case ADV_TIMER_ID: { if( s->sync_state == INIT) { // try to join the sync tree DEBUG("TPSN_NET: Trying to join sync tree. Sending out ADV\n"); msg_adv_level_t* msg_adv_level = (msg_adv_level_t*)sys_malloc(sizeof(msg_adv_level_t)); msg_adv_level->level = s->level; sys_post_net(s->pid, MSG_ADV_LEVEL, sizeof(msg_adv_level_t), msg_adv_level, SOS_MSG_RELEASE, BCAST_ADDRESS); } break; } case SYNC_TIMER_ID: { if(s->sync_state == SYNCING || s->sync_state == INIT_SYNCING) { // didn't receive the timestamp in time. Try to resend DEBUG("TPSN_NET: SYNC_TIMER fired. Trying to sync again.\n"); start_sync(); } break; } default: break; } return SOS_OK; } case MSG_ADV_LEVEL: { // FIXME: only allow level 1 to reply for now! if ( s->sync_state == SYNCED && s->level < 2) { msg_adv_level_t* msg_adv_level = (msg_adv_level_t*)sys_malloc(sizeof(msg_adv_level_t)); msg_adv_level->level = s->level; sys_post_net(s->pid, MSG_ADV_REPLY, sizeof(msg_adv_level_t), msg_adv_level, SOS_MSG_RELEASE, msg->saddr); } return SOS_OK; } case MSG_ADV_REPLY: { DEBUG("TPSN_NET: state: %d\n", s->sync_state); msg_adv_level_t* msg_adv_level = (msg_adv_level_t*)msg->data; if ( (s->sync_state == INIT) || msg_adv_level->level < s->level) { DEBUG("TPSN_NET: received new level %d from %d\n", msg_adv_level->level, msg->saddr); sys_timer_stop(ADV_TIMER_ID); s->level = msg_adv_level->level+1; s->parent_id = msg->saddr; if(s->level == 1) { // special case for root. msg_adv_level_t* msg_adv_level = (msg_adv_level_t*)sys_malloc(sizeof(msg_adv_level_t)); msg_adv_level->level = s->level; sys_post_net(s->pid, MSG_ADV_REPLY, sizeof(msg_adv_level_t), msg_adv_level, SOS_MSG_RELEASE, msg->saddr); s->sync_state = SYNCED; } else { s->sync_state = INIT_SYNCING; start_sync(); } } return SOS_OK; } case MSG_FINAL: { return SOS_OK; } default: return -EINVAL; } /** * Return SOS_OK for those handlers that have successfully been handled. */ return SOS_OK; }
static int8_t generic_test_msg_handler(void *state, Message *msg) { app_state_t *s = (app_state_t *) state; switch ( msg->type ) { /* do any initialization steps here, * in general it is good to set all the leds to off so that you can analyze what happens later more accurately * also be sure to start and enable any timers which your driver might need */ case MSG_INIT: sys_led(LED_GREEN_OFF); sys_led(LED_YELLOW_OFF); sys_led(LED_RED_OFF); s->state = TEST_APP_INIT; s->count = 0; s->order = 0; s->pid = msg->did; sys_timer_start(TEST_APP_TID, TEST_APP_INTERVAL, SLOW_TIMER_REPEAT); send_new_data(START_DATA, 0); break; case MSG_FINAL: sys_timer_stop(TEST_APP_TID); s->state = TEST_APP_FINAL; send_new_data(FINAL_DATA, 1); break; /* here we handle messages of type MSG_TEST_DATA * in most cases, only the base station node should be doing this since it is the only one connected to the uart * if your test does not use multiple nodes, or your messages are sent via another module, this is not needed */ case MSG_TEST_DATA: { uint8_t *payload; uint8_t msg_len; msg_len = msg->len; payload = sys_msg_take_data(msg); sys_post_uart( s->pid, MSG_TEST_DATA, msg_len, payload, SOS_MSG_RELEASE, BCAST_ADDRESS); } break; case MSG_HP_DATA: { data_msg_t *d; d = (data_msg_t*) sys_msg_take_data(msg); if (d->state != 155 || s->order != 0){ send_new_data(55, d->data); sys_led(LED_RED_TOGGLE); } s->order = 1; sys_free(d); } break; case MSG_LP_DATA: { data_msg_t *d; d = (data_msg_t*) sys_msg_take_data(msg); if (d->state != 255 || s->order != 1){ send_new_data(155, d->data); sys_led(LED_RED_TOGGLE); }else send_new_data(255, d->data); s->order = 0; sys_free(d); } break; default: return -EINVAL; break; } return SOS_OK; }
static int8_t generic_test_msg_handler(void *state, Message *msg) { app_state_t *s = (app_state_t *) state; switch ( msg->type ) { /* do any initialization steps here, * in general it is good to set all the leds to off so that you can analyze what happens later more accurately * also be sure to start and enable any timers which your driver might need */ case MSG_INIT: sys_led(LED_GREEN_OFF); sys_led(LED_YELLOW_OFF); sys_led(LED_RED_OFF); s->state = TEST_APP_INIT; s->count = 0; s->pid = msg->did; sys_timer_start(TEST_APP_TID, TEST_APP_INTERVAL, SLOW_TIMER_REPEAT); send_new_data(START_DATA, 0); break; case MSG_ERROR: s->state = TEST_APP_INIT; s->count = 0; s->pid = msg->did; sys_timer_start(TEST_APP_TID, TEST_APP_INTERVAL, SLOW_TIMER_REPEAT); send_new_data(START_DATA, 0); break; case MSG_FINAL: sys_timer_stop(TEST_APP_TID); s->state = TEST_APP_FINAL; send_new_data(FINAL_DATA, 1); break; /* here we handle messages of type MSG_TEST_DATA * in most cases, only the base station node should be doing this since it is the only one connected to the uart * if your test does not use multiple nodes, or your messages are sent via another module, this is not needed */ case MSG_TEST_DATA: { uint8_t *payload; uint8_t msg_len; msg_len = msg->len; payload = sys_msg_take_data(msg); sys_post_uart( s->pid, MSG_TEST_DATA, msg_len, payload, SOS_MSG_RELEASE, BCAST_ADDRESS); } break; case MSG_WAITING: s->state = TEST_APP_WAIT; break; case MSG_TIMER_TIMEOUT: { switch(s->state){ case TEST_APP_INIT: { uint8_t *d; d = (uint8_t*) sys_malloc(sizeof(uint8_t)); *d = s->count; sys_shm_open(sys_shm_name(TEST_PID, 0),d); s->state = TEST_APP_FINAL; } break; case TEST_APP_WAIT: { uint8_t *d; d = (uint8_t *) sys_shm_get(sys_shm_name(TEST_PID, 0)); *d = s->count; sys_shm_update(sys_shm_name(TEST_PID, 0), d); s->count++; if (s->count == 0){ s->state = TEST_APP_INIT; sys_shm_close(sys_shm_name(TEST_PID, 0)); sys_free(d); } } break; case TEST_APP_FINAL: { sys_post_value( OTHER_PID, MSG_WAIT_READY, 0, SOS_MSG_RELEASE); } break; default: return -EINVAL; break; } } break; default: return -EINVAL; break; } return SOS_OK; }
static int8_t module(void *state, Message *msg) { app_state_t *s = (app_state_t *) state; MsgParam *p = (MsgParam*)(msg->data); /** * Switch to the correct message handler */ switch (msg->type){ case MSG_INIT: { DEBUG("RATS: node %d initializing\n", ker_id()); s->pid = msg->did; s->ts_list = NULL; s->ts_packet.type = NORMAL_PACKET; //Notify neighbors that RATS is starting (in case node rebooted while it was //synchronizing with another node post_net(s->pid, s->pid, MSG_INVALIDATE_ENTRY, 0, NULL, 0, BCAST_ADDRESS); return SOS_OK; } case MSG_RATS_CLIENT_START: { MsgParam *p = (MsgParam *)msg->data; DEBUG("RATS: Received MSG_RATS_CLIENT_START for node %d\n", p->word); uint8_t request_status = add_request(s, p->word, p->byte); //If a new request was created, then send packet to parent if(request_status != NO_REQUEST_CREATED) { DEBUG("RATS: Transmitting request to node %d\n", p->word); LED_DBG(LED_RED_TOGGLE); //If the current node is the parent of the target node, then the target node will //reply by informing the parent, who will add the target to its list of children. post_net(s->pid, s->pid, MSG_RATS_SERVER_START, 0, NULL, 0, p->word); } else { //Request already exists DEBUG("RATS: Request already exists\n"); } //If this was the first request that was created, we need to start the panic timer if(request_status == CREATED_FIRST_REQUEST) { DEBUG("RATS: PANIC_TIMER started\n"); #ifdef USE_PANIC_PACKETS sys_timer_start(PANIC_TIMER, MIN_SAMPLING_PERIOD*1024, TIMER_REPEAT); #endif //USE_PANIC_PACKETS } return SOS_OK; } case MSG_RATS_SERVER_START: { timesync_t * temp_ts_ptr = get_timesync_ptr(s, msg->saddr); DEBUG("RATS: Received request from node %d\n", msg->saddr); if(temp_ts_ptr == NULL) { DEBUG("RATS: Starting timesync with node %d\n", msg->saddr); LED_DBG(LED_RED_TOGGLE); //If request is coming from node, with whom the node is not synchronizing, then //synchronization is starting sys_timer_stop(TRANSMIT_TIMER); sys_timer_stop(VALIDATION_TIMER); s->ts_packet.transmission_period = INITIAL_TRANSMISSION_PERIOD; s->ts_packet.min_period_node_id = msg->saddr; s->transmit_timer_counter = 1; //s->ts_packet.transmission_period/INITIAL_TRANSMISSION_PERIOD; s->validation_timer_counter = 5; //s->transmit_timer_counter + 4; s->validation_timer_retransmissions = TOTAL_VALIDATION_RETRANSMISSIONS; sys_timer_start(TRANSMIT_TIMER, MIN_SAMPLING_PERIOD*1024, TIMER_REPEAT); sys_timer_start(VALIDATION_TIMER, MIN_SAMPLING_PERIOD*1024, TIMER_REPEAT); } return SOS_OK; } case MSG_RATS_GET_TIME: { //If the module passed a NULL pointer or if the data size is wrong, then discard if( (msg->data == NULL) #ifndef PC_PLATFORM || (msg->len != sizeof(rats_t) ) #endif //PC_PLATFORM ) { DEBUG("RATS: Invalid data received in MSG_RATS_GET_TIME\n"); break; } rats_t * rats_ptr = (rats_t *)sys_msg_take_data(msg); DEBUG("RATS: Received MSG_RATS_GET_TIME (mod_id=%d node=%d)\n", rats_ptr->mod_id, msg->saddr); if(rats_ptr->source_node_id == ker_id()) { timesync_t * temp_ts_ptr = get_timesync_ptr(s, rats_ptr->target_node_id); if(temp_ts_ptr == NULL) { DEBUG("RATS: Target node %d is not time synced\n", rats_ptr->target_node_id); sys_free(rats_ptr); break; } else { DEBUG("RATS: Calculating time for target node %d locally\n", rats_ptr->target_node_id); if(temp_ts_ptr->packet_count < BUFFER_SIZE) // learning state { rats_ptr->time_at_target_node = 0; rats_ptr->error = 0; } else { rats_ptr->time_at_target_node = convert_from_mine_to_parent_time(rats_ptr->time_at_source_node, rats_ptr->target_node_id); rats_ptr->error = getError(&temp_ts_ptr->timestamps[0], &temp_ts_ptr->my_time[0], BUFFER_SIZE, temp_ts_ptr->window_size, BUFFER_SIZE - temp_ts_ptr->window_size, &temp_ts_ptr->a, &temp_ts_ptr->b, temp_ts_ptr->sampling_period, FALSE); } } } else if (rats_ptr->target_node_id == ker_id()) { timesync_t * temp_ts_ptr = get_timesync_ptr(s, rats_ptr->source_node_id); if(temp_ts_ptr == NULL) { DEBUG("RATS: Source node %d is not time synced\n", rats_ptr->source_node_id); sys_free(rats_ptr); break; } else { DEBUG("RATS: Calculating time for source node %d locally\n", rats_ptr->source_node_id); if(temp_ts_ptr->packet_count < BUFFER_SIZE) // learning state { rats_ptr->time_at_target_node = 0; rats_ptr->error = 0; } else { rats_ptr->time_at_target_node = convert_from_parent_to_my_time(rats_ptr->time_at_source_node, rats_ptr->source_node_id); rats_ptr->error = getError(&temp_ts_ptr->timestamps[0], &temp_ts_ptr->my_time[0], BUFFER_SIZE, temp_ts_ptr->window_size, BUFFER_SIZE - temp_ts_ptr->window_size, &temp_ts_ptr->a, &temp_ts_ptr->b, temp_ts_ptr->sampling_period, TRUE); } } } else { DEBUG("RATS: Invalid request (source = %d, target - %d)\n", rats_ptr->source_node_id, rats_ptr->target_node_id); sys_free(rats_ptr); break; } DEBUG("RATS: Sending reply to module %d\n", rats_ptr->mod_id); post_long(rats_ptr->mod_id, s->pid, rats_ptr->msg_type, sizeof(rats_t), rats_ptr, SOS_MSG_RELEASE); break; } case MSG_RATS_CLIENT_STOP: { MsgParam *p = (MsgParam *)msg->data; uint16_t node_id = p->word; //First we need to remove node from list of parents /* Select node at head of list */ timesync_t * ts_list_ptr = s->ts_list; timesync_t * ts_delete_list_ptr; timesync_t * ts_previous_list_ptr = s->ts_list; /* Loop until we've reached the end of the list */ while( ts_list_ptr != NULL ) { if(ts_list_ptr->node_id == node_id) { if(--ts_list_ptr->ref_counter > 0) return SOS_OK; DEBUG("RATS: Removing node %d from list of parents. Sending MSG_RATS_SERVER_STOP.\n", node_id); post_net(s->pid, s->pid, MSG_RATS_SERVER_STOP, 0, NULL, 0, node_id); /* Found the item to be deleted, re-link the list around it */ if( ts_list_ptr == s->ts_list ) /* We're deleting the head */ s->ts_list = ts_list_ptr->next; else ts_previous_list_ptr->next = ts_list_ptr->next; ts_delete_list_ptr = ts_list_ptr; ts_list_ptr = ts_list_ptr->next; /* Free the node */ sys_free( ts_delete_list_ptr ); //If the parent list is empty, then we're stopping the panic timer if(s->ts_list == NULL) { DEBUG("RATS: Parent list is empty. Stopping panic timer\n"); #ifdef USE_PANIC_PACKETS sys_timer_stop(PANIC_TIMER); #endif //USE_PANIC_PACKETS } return SOS_OK; } ts_previous_list_ptr = ts_list_ptr; ts_list_ptr = ts_list_ptr->next; } DEBUG("RATS: Requested parent %d was not found\n", node_id); break; } case MSG_RATS_SERVER_STOP: { DEBUG("RATS: Received MSG_RATS_SERVER_STOP from %d\n", msg->saddr); //If node has minimum period, then go to validation protocol if(msg->saddr == s->ts_packet.min_period_node_id) { DEBUG("RATS: Going to validation protocol\n"); s->validation_timer_counter = 1; s->validation_timer_retransmissions = BROADCAST_VALIDATION_RETRANSMISSIONS; s->validation_node_id = ker_id(); } break; } case MSG_TIMER_TIMEOUT: { switch(p->byte) { case TRANSMIT_TIMER: { if( (--(s->transmit_timer_counter)) == 0) { DEBUG("RATS: Broadcasting MSG_TIMESTAMP packet\n"); LED_DBG(LED_GREEN_TOGGLE); post_net(s->pid, s->pid, MSG_TIMESTAMP, sizeof(ts_packet_t), &s->ts_packet, 0, BCAST_ADDRESS); #ifdef UART_DEBUG post_uart(s->pid, s->pid, UART_TIMESTAMP, sizeof(ts_packet_t), &s->ts_packet, 0, BCAST_ADDRESS); #endif //UART_DEBUG s->transmit_timer_counter = (uint16_t)(s->ts_packet.transmission_period / MIN_SAMPLING_PERIOD); } break; } case VALIDATION_TIMER: { if( (--(s->validation_timer_counter)) == 0) { s->validation_timer_counter = 1; //Send up to MSG_PERIOD_REQUEST packets (UNICAST_VALIDATION_RETRANSMISSIONS times) to node with minimum period. //If the node doesn't respond until then, then broadcast BROADCAST_VALIDATION_RETRANSMISSIONS times //After the transmitting BROADCAST_VALIDATION_RETRANSMISSIONS packets, use the minimum period that //was sent during that interval if( s->validation_timer_retransmissions > BROADCAST_VALIDATION_RETRANSMISSIONS ) { --s->validation_timer_retransmissions; DEBUG("RATS: Transmitting MSG_PERIOD_REQUEST (retries left = %d) to node %d\n", s->validation_timer_retransmissions, s->ts_packet.min_period_node_id); post_net(s->pid, s->pid, MSG_PERIOD_REQUEST, 0, NULL, 0, s->ts_packet.min_period_node_id); #ifdef UART_DEBUG post_uart(s->pid, s->pid, UART_PERIOD_REQUEST, 0, NULL, 0, s->ts_packet.min_period_node_id); #endif //UART_DEBUG } else if( s->validation_timer_retransmissions > 0) { --s->validation_timer_retransmissions; DEBUG("RATS: Broadcasting MSG_PERIOD_REQUEST (retries left = %d)\n", s->validation_timer_retransmissions); //Invalidate node with minimum period s->validation_node_id = ker_id(); post_net(s->pid, s->pid, MSG_PERIOD_REQUEST, 0, NULL, 0, BCAST_ADDRESS); #ifdef UART_DEBUG post_uart(s->pid, s->pid, UART_PERIOD_REQUEST, 0, NULL, 0, BCAST_ADDRESS); #endif //UART_DEBUG } else //s->validation_timer_retransmissions == 0 { sys_timer_stop(TRANSMIT_TIMER); sys_timer_stop(VALIDATION_TIMER); //Restart normal procedure only if there was a reply if(ker_id() != s->validation_node_id) { DEBUG("RATS: Setting node %d as the one with min period (%d)\n", s->validation_node_id, s->validation_period); s->ts_packet.min_period_node_id = s->validation_node_id; s->ts_packet.transmission_period = s->validation_period; s->transmit_timer_counter = s->ts_packet.transmission_period/INITIAL_TRANSMISSION_PERIOD; s->validation_timer_counter = s->transmit_timer_counter + 4; s->validation_timer_retransmissions = TOTAL_VALIDATION_RETRANSMISSIONS; sys_timer_start(TRANSMIT_TIMER, MIN_SAMPLING_PERIOD*1024, TIMER_REPEAT); sys_timer_start(VALIDATION_TIMER, MIN_SAMPLING_PERIOD*1024, TIMER_REPEAT); } else { DEBUG("RATS: Validation timer expired, without receiving any packets\n"); sys_timer_stop(TRANSMIT_TIMER); sys_timer_stop(VALIDATION_TIMER); } } } break; } case PANIC_TIMER: { //There is a fixed number of retransmissions. If the corresponding counter //reaches zero, then the child is removed from the list /* Select node at head of list */ timesync_t * ts_list_ptr = s->ts_list; timesync_t * ts_delete_list_ptr; timesync_t * ts_previous_list_ptr = s->ts_list; /* Loop until we've reached the end of the list */ while( ts_list_ptr != NULL ) { if(--ts_list_ptr->panic_timer_counter == 0) { if(ts_list_ptr->panic_timer_retransmissions > 0) { //Transmit the packet --ts_list_ptr->panic_timer_retransmissions; DEBUG("RATS: Sending panic packet to node %d (retries=%d)\n", ts_list_ptr->node_id, ts_list_ptr->panic_timer_retransmissions); post_net(s->pid, s->pid, MSG_PANIC, 0, NULL, 0, ts_list_ptr->node_id); //The retransmission period should be INITIAL_TRANSMISSION_PERIOD ts_list_ptr->panic_timer_counter = 1; } else { DEBUG("RATS: Removing node %d from list of parents\n", ts_list_ptr->node_id); /* Found the item to be deleted, re-link the list around it */ if( ts_list_ptr == s->ts_list ) /* We're deleting the head */ s->ts_list = ts_list_ptr->next; else ts_previous_list_ptr->next = ts_list_ptr->next; ts_delete_list_ptr = ts_list_ptr; ts_list_ptr = ts_list_ptr->next; /* Free the node */ sys_free( ts_delete_list_ptr ); continue; } } ts_previous_list_ptr = ts_list_ptr; ts_list_ptr = ts_list_ptr->next; } //If the parent list is empty, then we're stopping the panic timer if(s->ts_list == NULL) { DEBUG("RATS: Parent list is empty. Stopping panic timer\n"); #ifdef USE_PANIC_PACKETS sys_timer_stop(PANIC_TIMER); #endif //USE_PANIC_PACKETS } break; } default: break; } return SOS_OK; } case MSG_PERIOD_CHANGE: { uint16_t temp_transmission_period; DEBUG("RATS: Received packet for period change from %d\n", msg->saddr); LED_DBG(LED_YELLOW_TOGGLE); if((msg->data == NULL) || (msg->len != sizeof(uint16_t)) ) { DEBUG("RATS: Invalid parameters in MSG_PERIOD_CHANGE\n"); break; } temp_transmission_period = (* (uint16_t*)(msg->data)); //Change period if: //a)received period is smaller than period in use //b)node that sent period is the one that has the current smallest period //c)I am currently using myself as the node with the smallest period (used in the beginning and in transitive modes) if((temp_transmission_period < s->ts_packet.transmission_period) || (s->ts_packet.min_period_node_id == msg->saddr) || (s->ts_packet.min_period_node_id == ker_id()) ) { DEBUG("RATS: Changing period (new_period=%d new_node=%d). Sending to UART\n", temp_transmission_period, msg->saddr); sys_timer_stop(TRANSMIT_TIMER); sys_timer_stop(VALIDATION_TIMER); #ifdef UART_DEBUG period_packet_t * period_packet_ptr = sys_malloc(sizeof(period_packet_t)); period_packet_ptr->saddr = msg->saddr; period_packet_ptr->old_period = s->ts_packet.transmission_period; period_packet_ptr->new_period = temp_transmission_period; post_uart(s->pid, s->pid, UART_PERIOD_CHANGE, sizeof(period_packet_t), period_packet_ptr, SOS_MSG_RELEASE, UART_ADDRESS); #endif //UART_DEBUG s->ts_packet.transmission_period = temp_transmission_period; s->ts_packet.min_period_node_id = msg->saddr; s->transmit_timer_counter = (uint16_t)(s->ts_packet.transmission_period / MIN_SAMPLING_PERIOD); s->validation_timer_counter = s->transmit_timer_counter + 4; s->validation_timer_retransmissions = TOTAL_VALIDATION_RETRANSMISSIONS; sys_timer_start(TRANSMIT_TIMER, INITIAL_TRANSMISSION_PERIOD*1024, TIMER_REPEAT); sys_timer_start(VALIDATION_TIMER, INITIAL_TRANSMISSION_PERIOD*1024, TIMER_REPEAT); } return SOS_OK; } case MSG_TIMESTAMP: { ts_packet_t *ts_packet_ptr = (ts_packet_t *)msg->data; DEBUG("RATS: MSG_TIMESTAMP with type = %d\n", ts_packet_ptr->type); if(ts_packet_ptr->type == NORMAL_PACKET) { DEBUG("RATS: Receiving timestamp data from node %d\n", msg->saddr); if( add_values(s, msg) == TRUE) { LED_DBG(LED_GREEN_TOGGLE); DEBUG("RATS: Accessed internal structure\n"); } else { DEBUG("RATS: Discarding MSG_TIMESTAMP from node %d\n", msg->saddr); } } else // TEST_PACKET { if(ker_id() == ROOT_NODE) { DEBUG("RATS: Receiving test data from node %d. Sending to UART\n", msg->saddr); #ifdef UART_DEBUG ext_packet_t * ext_packet_ptr = (ext_packet_t *)msg->data; debug_packet_t * debug_packet_ptr = (debug_packet_t *)sys_malloc(sizeof(debug_packet_t)); debug_packet_ptr->time[0] = ticks_to_msec_float(ext_packet_ptr->time[0]); debug_packet_ptr->time[1] = ticks_to_msec_float(ext_packet_ptr->time[1]); debug_packet_ptr->node_id = ker_id(); debug_packet_ptr->int_parent_time = ext_packet_ptr->time[1]; post_uart(s->pid, s->pid, UART_FORWARD_EXT, sizeof(debug_packet_t), debug_packet_ptr, SOS_MSG_RELEASE, UART_ADDRESS); #endif //UART_DEBUG } else { DEBUG("RATS: Receiving test data from node %d. Sending to parent\n", msg->saddr); #ifdef UART_DEBUG ext_packet_t * ext_packet_ptr = (ext_packet_t *)msg->data; uint32_t parent_time = convert_from_mine_to_parent_time(ext_packet_ptr->time[1], ROOT_NODE); //Break if the parent is not found in the timestamping list if(parent_time == 0) { break; } debug_packet_t * debug_packet_ptr = (debug_packet_t *)sys_malloc(sizeof(debug_packet_t)); debug_packet_ptr->time[0] = ticks_to_msec_float(ext_packet_ptr->time[0]); debug_packet_ptr->time[1] = ticks_to_msec_float(parent_time); debug_packet_ptr->int_parent_time = parent_time; debug_packet_ptr->node_id = ker_id(); post_uart(s->pid, s->pid, UART_FORWARD_EXT, sizeof(debug_packet_t), debug_packet_ptr, SOS_MSG_RELEASE, UART_ADDRESS); #endif //UART_DEBUG } } break; } case MSG_PERIOD_REQUEST: { DEBUG("RATS: Received MSG_PERIOD_REQUEST packet from node %d\n", msg->saddr); timesync_t * temp_ts_ptr = get_timesync_ptr(s, msg->saddr); if(temp_ts_ptr == NULL) { DEBUG("RATS: Discarding MSG_PERIOD_REQUEST\n"); break; } uint16_t *sampling_period = (uint16_t *)sys_malloc(sizeof(uint16_t)); if(sampling_period != NULL) { *sampling_period = temp_ts_ptr->sampling_period; DEBUG("RATS: Sending MSG_PERIOD_REPLY packet (period=%d) to node %d\n", *sampling_period, msg->saddr); post_net(s->pid, s->pid, MSG_PERIOD_REPLY, sizeof(uint16_t), sampling_period, SOS_MSG_RELEASE, msg->saddr); } break; } case MSG_PERIOD_REPLY: { uint16_t transmission_period; DEBUG("RATS: Received MSG_PERIOD_REPLY packet from node %d\n", msg->saddr); memcpy(&transmission_period, &msg->data[0], sizeof(transmission_period)); s->validation_timer_counter = s->transmit_timer_counter + 4; s->validation_timer_retransmissions = TOTAL_VALIDATION_RETRANSMISSIONS; if((transmission_period < s->validation_period) || (s->validation_node_id == ker_id() ) ) { DEBUG("RATS: Changing VALIDATION period (new_period=%d new_node=%d)\n", transmission_period, msg->saddr); s->validation_period = transmission_period; s->validation_node_id = msg->saddr; } break; } case MSG_PANIC: { //Transmit MSG_TIMESTAMP, restart timer, recalculate value for transmit_timer_counter sys_timer_stop(TRANSMIT_TIMER); sys_timer_stop(VALIDATION_TIMER); #ifdef UART_DEBUG uint16_t *data = (uint16_t *)sys_malloc(sizeof(uint16_t)); *data = msg->saddr; post_uart(s->pid, s->pid, UART_PANIC, sizeof(uint16_t), data, SOS_MSG_RELEASE, UART_ADDRESS); #endif //UART_DEBUG post_net(s->pid, s->pid, MSG_TIMESTAMP, sizeof(ts_packet_t), &s->ts_packet, 0, BCAST_ADDRESS); s->transmit_timer_counter = (uint16_t)(s->ts_packet.transmission_period / MIN_SAMPLING_PERIOD); s->validation_timer_counter = s->transmit_timer_counter + 4; s->validation_timer_retransmissions = TOTAL_VALIDATION_RETRANSMISSIONS; sys_timer_start(TRANSMIT_TIMER, INITIAL_TRANSMISSION_PERIOD*1024, TIMER_REPEAT); sys_timer_start(VALIDATION_TIMER, INITIAL_TRANSMISSION_PERIOD*1024, TIMER_REPEAT); break; } case MSG_INVALIDATE_ENTRY: { DEBUG("RATS: Received invalidation message from node %d\n", msg->saddr); timesync_t * temp_ts_ptr = get_timesync_ptr(s, msg->saddr); if(temp_ts_ptr == NULL) { DEBUG("RATS: Discarding MSG_INVALIDATE_ENTRY\n"); break; } DEBUG("RATS: Invalidation entry for node %d\n", msg->saddr); temp_ts_ptr->packet_count = 0; temp_ts_ptr->a = 0; temp_ts_ptr->b = 0; temp_ts_ptr->sampling_period = INITIAL_TRANSMISSION_PERIOD; temp_ts_ptr->window_size = (uint8_t)BUFFER_SIZE; temp_ts_ptr->panic_timer_counter = 5; //(s->ts_list->sampling_period / INITIAL_TRANSMISSION_PERIOD) + 4; temp_ts_ptr->panic_timer_retransmissions = PANIC_TIMER_RETRANSMISSIONS; memset(temp_ts_ptr->timestamps, 0, BUFFER_SIZE*sizeof(uint32_t)); memset(temp_ts_ptr->my_time, 0, BUFFER_SIZE*sizeof(uint32_t)); //Notify node to start procedure from beginning post_net(s->pid, s->pid, MSG_RATS_SERVER_START, 0, NULL, 0, msg->saddr); break; } case MSG_FINAL: { sys_timer_stop(TRANSMIT_TIMER); sys_timer_stop(VALIDATION_TIMER); #ifdef USE_PANIC_PACKETS sys_timer_stop(PANIC_TIMER); #endif //USE_PANIC_PACKETS return SOS_OK; } default: return -EINVAL; } /** * Return SOS_OK for those handlers that have successfully been handled. */ return SOS_OK; }
static int8_t uart_mod_msg_handler(void *state, Message *msg) { app_state_t *s = (app_state_t*)state; switch (msg->type){ case MSG_INIT: { s->pid = msg->did; uart_mod_bufcnt = 0; uart_mod_bufoverflow = 0; uart_mod_buf = (uint8_t *)sys_malloc(BUFSIZE); DEBUG("Uart Start\n"); uart_mod_init(); ker_timer_init(KER_UART_PID, UART_TID, SLOW_TIMER_ONE_SHOT); sys_led(LED_YELLOW_ON); break; } case MSG_FINAL: { sys_timer_stop(UART_TID); DEBUG("Uart Stop\n"); break; } case MSG_TIMER_TIMEOUT: { /* Timer fired, should sent out the message to the uart0 now * */ HAS_CRITICAL_SECTION; uint8_t *tmpbuf; uint8_t tmpbufcnt; ENTER_CRITICAL_SECTION(); tmpbufcnt = uart_mod_bufcnt; tmpbuf = (uint8_t *)sys_malloc(tmpbufcnt); memcpy(tmpbuf, uart_mod_buf, tmpbufcnt); sys_post(DFLT_APP_ID1, MSG_RFID_RESPONSE, tmpbufcnt, tmpbuf, SOS_MSG_RELEASE); uart_mod_bufcnt = 0; uart_mod_bufoverflow = 0; LEAVE_CRITICAL_SECTION(); sys_led(LED_YELLOW_TOGGLE); break; } case MSG_RFID_COMMAND: { uint8_t i, msg_len; msg_len = msg->len; for (i = 0; i < msg_len; i++) { USART1_send(*((msg->data)+i)); } break; } default: return -EINVAL; } return SOS_OK; }
static int8_t rfidreader_msg_handler(void *state, Message *msg) { app_state_t *s = (app_state_t*)state; switch (msg->type){ case MSG_INIT: { s->pid = msg->did; s->state = 0; DEBUG("Rfidreader Start\n"); s->counter = 0; break; } case MSG_FINAL: { DEBUG("Rfidreader Stop\n"); break; } case MSG_RFID_TAG: { sys_led(LED_RED_TOGGLE); uint8_t *payload; payload = sys_msg_take_data(msg); //rfid = sys_malloc(3*sizeof(uint8_t)); id = (uint8_t)*payload; rssi = msg->rssi; code = id ; code = code << 8; code = code | rssi; //if (rfid !=NULL) //{ // rfid[0]=sys_id(); // rfid[1]=msg->rssi; // memcpy(rfid+2, payload, 1); // uint8_t time = (uint8_t)ker_rand(); sys_timer_start(RAND_TID, 1024/20, TIMER_REPEAT); //} sys_free(payload); break; } case MSG_TIMER_TIMEOUT: { //if (rfid !=NULL) //{ //sys_post_net(DFLT_APP_ID0, MSG_RFID_RESPONSE, 3, (void*)rfid, SOS_MSG_RELEASE | SOS_MSG_RELIABLE, 0x01); //} if(counter >= 16) { sys_led(LED_YELLOW_OFF); counter--; } else { if(GETBIT(code, counter) ==1) { sys_led(LED_YELLOW_OFF); } else { sys_led(LED_YELLOW_ON); } counter --; if(counter == -1) { counter = 17; sys_timer_stop(RAND_TID); sys_led(LED_YELLOW_ON); } } break; } default: return -EINVAL; } return SOS_OK; }
static int8_t temp_test_msg_handler(void *state, Message *msg) { app_state_t *s = (app_state_t *) state; switch ( msg->type ) { case MSG_INIT: s->state = TEMP_TEST_APP_INIT; s->pid = msg->did; sys_timer_start(TEMP_TEST_APP_TID, TEMP_TEST_APP_INTERVAL, TIMER_REPEAT); if(sys_sensor_enable(TEMP_SID) != SOS_OK) { LED_DBG(LED_RED_ON); sys_timer_stop(TEMP_TEST_APP_TID); } break; case MSG_FINAL: sys_sensor_disable( TEMP_SID); sys_timer_stop(TEMP_TEST_APP_TID); break; case MSG_TIMER_TIMEOUT: { LED_DBG(LED_YELLOW_TOGGLE); switch (s->state) { case TEMP_TEST_APP_INIT: // do any necessary init here s->state = TEMP_TEST_APP_IDLE; break; case TEMP_TEST_APP_IDLE: s->state = TEMP_TEST_APP_TEMP; break; case TEMP_TEST_APP_TEMP: s->state = TEMP_TEST_APP_TEMP_BUSY; sys_sensor_get_data( TEMP_SID); break; case TEMP_TEST_APP_TEMP_BUSY: break; default: LED_DBG(LED_RED_TOGGLE); s->state = TEMP_TEST_APP_INIT; break; } } break; case MSG_DATA_READY: { uint8_t *data_msg; LED_DBG(LED_GREEN_TOGGLE); data_msg = sys_malloc ( sizeof(MsgParam)); if ( data_msg ) { LED_DBG(LED_RED_TOGGLE); memcpy((void*)data_msg, (void*)msg->data, sizeof(MsgParam)); sys_post_uart ( s->pid, MSG_DATA_READY, sizeof(MsgParam), data_msg, SOS_MSG_RELEASE, BCAST_ADDRESS); } switch(s->state) { case TEMP_TEST_APP_TEMP_BUSY: s->state = TEMP_TEST_APP_TEMP; break; } } break; default: return -EINVAL; break; } return SOS_OK; }