// Set senderid, packetcounter and CRC into the partly filled packet, encrypt it using the given AES key number and send it. void send_packet(uint8_t aes_key_nr, uint8_t packet_len) { pkg_header_set_senderid(device_id); inc_packetcounter(); pkg_header_set_packetcounter(packetcounter); // set CRC32 pkg_header_set_crc32(crc32(bufx + 4, packet_len - 4)); // load AES key (0 is first AES key) if (aes_key_nr >= aes_key_count) { aes_key_nr = aes_key_count - 1; } e2p_basestation_get_aeskey(aes_key_nr, aes_key); // show info decode_data(packet_len); // encrypt and send __PACKETSIZEBYTES = packet_len; rfm12_send_bufx(); }
// process message "brightness" void process_brightness(MessageTypeEnum messagetype) { // "Set" or "SetGet" -> modify dimmer state and abort any running animation if ((messagetype == MESSAGETYPE_SET) || (messagetype == MESSAGETYPE_SETGET)) { start_brightness = end_brightness = msg_dimmer_brightness_get_brightness(); UART_PUTF("Requested Brightness: %u%%;", start_brightness); animation_length = 0; animation_mode = 0; animation_position = 0; setPWMDutyCyclePercent(start_brightness); /* TODO: Write to EEPROM (?) // write back switch state to EEPROM switch_state[i] = req_state; switch_timeout[i] = req_timeout; eeprom_write_word((uint16_t*)EEPROM_POS_SWITCH_STATE + i * 2, u16); */ } // remember some values before the packet buffer is destroyed uint32_t acksenderid = pkg_header_get_senderid(); uint32_t ackpacketcounter = pkg_header_get_packetcounter(); inc_packetcounter(); // "Set" -> send "Ack" if (messagetype == MESSAGETYPE_SET) { pkg_header_init_dimmer_brightness_ack(); UART_PUTS("Sending Ack\r\n"); } // "Get" or "SetGet" -> send "AckStatus" else { pkg_header_init_dimmer_brightness_ackstatus(); // set message data msg_dimmer_brightness_set_brightness(start_brightness); UART_PUTS("Sending AckStatus\r\n"); } // set common fields pkg_header_set_senderid(device_id); pkg_header_set_packetcounter(packetcounter); pkg_headerext_common_set_acksenderid(acksenderid); pkg_headerext_common_set_ackpacketcounter(ackpacketcounter); pkg_headerext_common_set_error(false); // FIXME: Move code for the Ack to a function and also return an Ack when errors occur before! pkg_header_calc_crc32(); rfm12_send_bufx(); }
void send_prepared_message(void) { inc_packetcounter(); pkg_header_set_senderid(device_id); pkg_header_set_packetcounter(packetcounter); rfm12_send_bufx(); rfm12_tick(); // send packet, and then WAIT SOME TIME BEFORE GOING TO SLEEP (otherwise packet would not be sent) led_blink(200, 0, 1); }
void send_version_status(void) { inc_packetcounter(); UART_PUTF4("Sending Version: v%u.%u.%u (%08lx)\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_HASH); // Set packet content pkg_header_init_generic_version_status(); pkg_header_set_senderid(device_id); pkg_header_set_packetcounter(packetcounter); msg_generic_version_set_major(VERSION_MAJOR); msg_generic_version_set_minor(VERSION_MINOR); msg_generic_version_set_patch(VERSION_PATCH); msg_generic_version_set_hash(VERSION_HASH); pkg_header_calc_crc32(); rfm12_send_bufx(); }
void send_dimmer_status(void) { UART_PUTS("Sending Dimmer Status:\r\n"); inc_packetcounter(); uint8_t bri = (uint8_t)current_brightness; // Set packet content pkg_header_init_dimmer_brightness_status(); pkg_header_set_senderid(device_id); pkg_header_set_packetcounter(packetcounter); msg_dimmer_brightness_set_brightness(bri); pkg_header_calc_crc32(); UART_PUTF("CRC32 is %lx (added as first 4 bytes)\r\n", getBuf32(0)); UART_PUTF("Brightness: %u%%\r\n", bri); rfm12_send_bufx(); }
// Search for a request to repeat (with timeout reached) and write the data to the send buffer bufx. // Return a pointer to the request if successful, 0 if no request to repeat was found. // Automatically decrease timeout counters for all waiting requests in the queue, // delete a request if it is repeated the last time and cleanup the queue and repeat_buffer accordingly. // This function has to be called once a second, because the timeout values represent the amount of seconds. // // TODO (optimization): Change the behaviour so that a new packet can be sent out of the queue without a delay (currently, we have ~0.5s delay in average). // So check the queue for "timeout 0" packets more often, but don't reduce the timeout in this case. request_t * find_request_to_repeat(uint32_t packet_counter) { uint8_t i; uint8_t slot; request_t * res = 0; for (i = 0; i < REQUEST_QUEUE_RECEIVERS; i++) { if (request_queue[i][0] != SLOT_UNUSED) { // count down timeout from first element per queue slot = request_queue[i][1]; if (request_buffer[slot].timeout > 0) { request_buffer[slot].timeout--; } // set bufx to the request to retry, if timeout is reached if ((request_buffer[slot].timeout == 0) && (res == 0)) { res = &request_buffer[slot]; // Init header memset(&bufx[0], 0, sizeof(bufx)); pkg_header_set_senderid(0); // FIXME: Use DeviceID instead?! pkg_header_set_packetcounter(packet_counter); // set message type pkg_header_set_messagetype(request_buffer[slot].message_type); // set header extension (incl. receiver_id) + data memcpy(bufx + 9, request_buffer[slot].data, request_buffer[slot].data_bytes); // header size = 9 bytes // remember packet counter request_buffer[slot].packet_counter = packet_counter; request_buffer[slot].retry_count++; if (request_buffer[slot].retry_count > REQUEST_RETRY_COUNT) { // delete request from queue request_buffer[slot].message_type = MESSAGETYPE_UNUSED; uint8_t x; for (x = 1; x < REQUEST_QUEUE_PACKETS; x++) { request_queue[i][x] = request_queue[i][x + 1]; } request_queue[i][REQUEST_QUEUE_PACKETS] = SLOT_UNUSED; // delete request queue completely (if no requests are in the queue) if (request_queue[i][1] == SLOT_UNUSED) { request_queue[i][0] = SLOT_UNUSED; } } else { request_buffer[slot].timeout = (request_buffer[slot].retry_count - 1) * REQUEST_ADDITIONAL_TIMEOUT_S + REQUEST_INITIAL_TIMEOUT_S; } } } //UART_PUTS("\r\n"); } return res; }