void udp_receive(void) { #ifdef UTILS_WERKTI_MORE // Update werkti udp in werkti_udp_in += buffer_in_length; #endif // UTILS_WERKTI_MORE debug_string_p(PSTR("UDP: received\r\n")); uint16_t port; void (*callback)(uint8_t *data, uint16_t length); // Get the port port = ((uint16_t)buffer_in[UDP_PTR_PORT_DST_H]) << 8; port |= buffer_in[UDP_PTR_PORT_DST_L]; debug_string_p(PSTR("UDP: Port: ")); debug_number(port); debug_newline(); // Check if a listener is registered for this port debug_string_p(PSTR("UDP: Search service...")); callback = port_service_get(port_services, NET_UDP_SERVICES_LIST_SIZE, port); debug_string_p(PSTR("done\r\n")); if (callback) { debug_string_p(PSTR("UDP: Found callback function\r\n")); uint16_t length = ((uint16_t)buffer_in[IP_PTR_LENGTH_H]) << 8; length |= buffer_in[IP_PTR_LENGTH_L]; length -= IP_LEN_HEADER + UDP_LEN_HEADER; debug_string_p(PSTR("UDP: Calling callback function\r\n")); callback(&buffer_in[UDP_PTR_DATA], length); // Execute callback debug_string_p(PSTR("UDP: Callback function returned\r\n")); } debug_string_p(PSTR("UDP: handled\r\n")); }
void www_server_register_path(const char *path, void (*callback)(uint8_t type, uint8_t *data)) { // path_service_set(path, callback); uint8_t i; for (i = 0; i < EXT_WWW_SERVER_SERVICES_LIST_SIZE; i++) { if (path_services[i].path == 0) { path_services[i].path = path; path_services[i].callback = callback; return; } } debug_string_p(PSTR("Path service list full\r\n")); }
void www_server_unregister_path(const char *path) { // path_service_remove(path); uint8_t i; for (i = 0; i < EXT_WWW_SERVER_SERVICES_LIST_SIZE; i++) { if (path_services[i].path && path_matches_p(path, path_services[i].path)) { path_services[i].path = 0; path_services[i].callback = 0; return; } } debug_string_p(PSTR("Path to remove not found\r\n")); }
void handle_request(uint8_t *data, uint16_t length) { debug_string_p(PSTR("HTTP: ")); uint8_t type = 0; uint8_t path_start = 0; switch(data[0]) { case 'H': type = HTTP_METHOD_HEAD; path_start = 5; break; case 'G': type = HTTP_METHOD_GET; path_start = 4; break; case 'D': type = HTTP_METHOD_DELETE; path_start = 7; break; case 'P': switch(data[1]) { case 'O': type = HTTP_METHOD_POST; path_start = 5; break; case 'U': type = HTTP_METHOD_PUT; path_start = 4; break; default: type = 0; } break; } // Fetch path only if we have a type if (type) { uint8_t path_length = 0; uint8_t *path = &data[path_start]; while (*path++ > 0x20) { path_length++; } // Make space after path 0x00 (for path matching) data[path_start + path_length] = 0x00; // Debug path debug_string_n((char *)data, path_start + path_length); } // Get callback for type/path combination // path_services_get(&data[path_start]); uint8_t i; void (*callback)(uint8_t, uint8_t *); for (i = 0, callback = 0; i < EXT_WWW_SERVER_SERVICES_LIST_SIZE; i++) { if (path_services[i].path && path_matches(&data[path_start], path_services[i].path)) { callback = path_services[i].callback; break; } } // Prepare tcp reply rbuffer = tcp_prepare_reply(); rlength = 0; // Increase ack with length add_value_to_buffer(length, &buffer_out[TCP_PTR_ACK_NR], 4); // Set ACK flag tcp_add_flags(TCP_FLAG_ACK | TCP_FLAG_PUSH | TCP_FLAG_FIN); // Check if we can handle the request if (callback) { callback(type, data); } else { // Return 404, not found www_server_reply_header(HTTP_STATUS_404, HTTP_CONTENT_TYPE_PLAIN); www_server_reply_add_p(not_found); www_server_reply_send(); } debug_ok(); }