void init(char* remote, int REMOTE_PORT){ if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1){ perror("Error creating socket"); exit(1); } set_local_port(0); set_remote(remote,REMOTE_PORT); if (bind(s, (struct sockaddr*)&addr_local, sizeof(addr_local))==-1){ perror("Failed to bind"); exit(1); } fds[0].fd = s; fds[0].events = POLLIN; msg m; send_message(&m); }
void LGNetwork::loop() { if(currentMode == LGNETWORK_DISCOVER) { #ifdef USE_NETWORK_SERVER if(pending_is_empty()){ cmd_enter(); cmd_get_one_unassociated_device(); cmd_exit(); } else { // We can operate on the pending device, by assigning it an address int8_t next_address = (int8_t)get_next_free_address(); if(next_address >= 0 && next_address < 100) { // We found a valid address // Send it the association packet dhcp_packet_t p; p.packet.base_address = LGNetwork::myUUID; p.packet.short_address = next_address; // Point ourselves to our target. cmd_enter(); cmd_set_target_long_address(next_client.address); cmd_exit(); sleep(3000); // Packet header LGSerial::slow_put("SYN"); // Send the packet body for(int i=0; i < sizeof(dhcp_packet_t); i++) { LGSerial::slow_put(p.bytes[i]); } bool response = scan_for_header("SAK", 10000); if(response) { // Now commit it to EEPROM if(next_client.identifier == 's') LGDB::write_device_table_entry(next_address, 1); else LGDB::write_device_table_entry(next_address, 0); for(uint8_t i=0; i < 7; i++) { LGDB::write_schedule_table_entry(next_address, i, 0); } // Send final ack sleep(1000); LGSerial::slow_put("ACK"); } // We clear it since we're done pending_clear(); } } #endif #if USE_NETWORK_CLIENT if(LGSerial::available()) { bool matches = scan_for_header("SYN", 1000); if(matches) { // Receive packet char *ptr = (char*)&(LGNetwork::baseUUID); for(uint8_t i=0; i < sizeof(LGNetwork::baseUUID); i++) { char c = LGSerial::get();; *(ptr++) = c; } LGNetwork::myShortAddr = LGSerial::get(); // Reply to the server cmd_enter(); cmd_set_long_address_to_basestation(); cmd_set_short_address(LGNetwork::myShortAddr); cmd_dissociate(); cmd_exit(); // Give it time to associate sleep(3000); // SYN-ACK LGSerial::slow_put_pgm( PSTR("SAK") ); // Hopefully the server saw us matches = scan_for_header("ACK", 3000); if(matches) { // Persist to eeprom LGDB::write_address(LGNetwork::myShortAddr); LGDB::write_basestation_address(LGNetwork::baseUUID); currentMode = LGNETWORK_DISCOVER_READY; } else { cmd_enter(); cmd_set_short_address(-1); cmd_exit(); } } } #endif } else { // LGNETWORK_OPERATE #ifdef USE_NETWORK_SERVER // See if anybody's up uint8_t hour = GetHour(); if(GetAmPm()) hour += 12; // Convert to 24 hour time uint8_t minute = GetMinute(); uint16_t theTime = hour*60 + minute; uint8_t day = GetDay(); // LGSerial::put("Time is "); // LGSerial::print(hour); // LGSerial::print(minute); // LGSerial::print(theTime); uint8_t motion_sensor_idx = 0xFF; if(LGSerial::available()) { // We got a byte motion_sensor_idx = LGSerial::get(); } for(uint8_t i=0; i < sizeof(lgdb_device_table); i++) { if(LGDB::read_device_table_entry(i) != 0) { continue; } uint16_t device_on = 60*LGDB::read_hour(i, day, true) + LGDB::read_minute(i, day, true); // Read ontime uint16_t device_off = 60*LGDB::read_hour(i, day, false) + LGDB::read_minute(i, day, false); uint8_t autodevice = LGDB::read_sensor_table_entry(i, day); // LGSerial::put("Device "); // LGSerial::print(i); // LGSerial::put("On "); // LGSerial::print(device_on); // LGSerial::put("Off "); // LGSerial::print(device_off); // Events: Turn Off, Turn On, Respond to Auto if(device_off == theTime) { // Turn off // LGSerial::put("OFF "); // LGSerial::print(i); set_remote(i, SYSTEM_OFF); } else if(device_on == theTime) { if(autodevice == 0xFF) { // Turn on // LGSerial::put("ON "); // LGSerial::print(i); set_remote(i, SYSTEM_ON); } else { // LGSerial::put("AUTO "); // LGSerial::print(i); set_remote(i, SYSTEM_AUTO_OFF); } } else if(theTime >= device_on && theTime < device_off) { if(autodevice != 0xFF) { // LGSerial::print("Auto"); // LGSerial::put("Entry "); // LGSerial::print(LGDB::read_schedule_table_entry(autodevice, day)); if(motion_sensor_idx == autodevice) { // LGSerial::print("We got a sensor reading"); // We got a byte from the sensor set_remote(i, SYSTEM_AUTO_ON); LGDB::write_schedule_table_entry(autodevice, day, theTime); // Remember the time } else if( (LGDB::read_schedule_table_entry(autodevice, day) + 5) < theTime ) { // It's been an hour // LGSerial::print("It's been an hour"); set_remote(i, SYSTEM_AUTO_OFF); } } } } // } // int8_t next_to_program = get_next_target_address(); // LGSerial::put("Next: "); // LGSerial::print(next_to_program); // if(next_to_program >= 0) { // uint16_t data = LGDB::read_device_table_entry(next_to_program); // command_packet_t p; // p.packet.short_address = next_to_program; // p.packet.system_mode = SYSTEM_ON; // // Header // LGSerial::slow_put_pgm( PSTR("CMD") ); // // Body // for(uint8_t i=0; i < sizeof(command_packet_t); i++) { // LGSerial::slow_put(p.bytes[i]); // } // // Remember our success // last_commanded_device_address = next_to_program; // } #endif } }