static inline void clunet_data_received(const uint8_t src_address, const uint8_t dst_address, const uint8_t command, char* data, const uint8_t size) { if (on_data_received_sniff) (*on_data_received_sniff)(src_address, dst_address, command, data, size); if (src_address == CLUNET_DEVICE_ID) return; // Игнорируем сообщения от самого себя! if ((dst_address != CLUNET_DEVICE_ID) && (dst_address != CLUNET_BROADCAST_ADDRESS)) return; // Игнорируем сообщения не для нас // Команда перезагрузки. Перезагрузим по сторожевому таймеру if (command == CLUNET_COMMAND_REBOOT) { cli(); set_bit(WDTCR, WDE); while(1); } if ((clunetSendingState == CLUNET_SENDING_STATE_IDLE) || (clunetCurrentPrio <= CLUNET_PRIORITY_MESSAGE)) { /* Ответ на поиск устройств */ if (command == CLUNET_COMMAND_DISCOVERY) { #ifdef CLUNET_DEVICE_NAME char buf[] = CLUNET_DEVICE_NAME; uint8_t len = 0; while(buf[len]) len++; clunet_send(src_address, CLUNET_PRIORITY_MESSAGE, CLUNET_COMMAND_DISCOVERY_RESPONSE, buf, len); #else clunet_send(src_address, CLUNET_PRIORITY_MESSAGE, CLUNET_COMMAND_DISCOVERY_RESPONSE, 0, 0); #endif } /* Ответ на пинг */ else if (command == CLUNET_COMMAND_PING) clunet_send(src_address, CLUNET_PRIORITY_COMMAND, CLUNET_COMMAND_PING_REPLY, data, size); } if (on_data_received) (*on_data_received)(src_address, dst_address, command, data, size); }
void incoming_ring() // Выполняется при любом входящем звонке { LED_RED_ON; unsigned char mode = (mode_temp != 0) ? mode_temp : mode_current; // Текущий режим // Сообщение о звонке, указываем текущий режим clunet_send(CLUNET_BROADCAST_ADDRESS, CLUNET_PRIORITY_INFO, CLUNET_COMMAND_INTERCOM_RING, (char*)&mode, 1); if (mode != 3 && mode != 0xFF) intercom_bell(); while (clunet_ready_to_send()); // Ждём, пока будем готовы к передаче if (mode_temp) // Обнуляем временный режим { mode_temp = 0; save_mode(); } if (!LINE_POWER) // Аварийное откртие двери, если набрали и сразу сбросили { mode_temp = 0xFF; save_mode(); } if (mode) { switch (mode) { case 1: // Автоответчик, долго ждёт ответа, потом записывает answer_record(AUTOLONG_WAV, SAVED_FAKE_WAV, 0); break; case 2: // Автоответчик, сразу записывает answer_record(AUTOFAST_WAV, SAVED_WAV, 1); break; case 3: // Приветствует хозяина, открывает дверь answer_play_open(OPENME_WAV); break; case 4: // Приветствует гостя, открывает дверь answer_play_open(OPEN_WAV); break; case 5: // Долго ждёт ответа. Сообщение не пишет. answer_play(WAITLONG_WAV); break; case 9: // Здрасти, здрастите. Проходи, братишка, проходи. answer_play_open(MODE9_WAV); break; case 0xFF: // Аварийное откртие двери answer_play_open(EMERGENCY_OPEN_WAV); } MODE_NORMAL; _delay_ms(500); // На случай, если контакты снятия трубки не успели разомкнуться HANGUP; } while (LINE_POWER); // Ждём пока не пропадёт сигнал LED_RED_OFF; while (OFFHOOK); // И пользователь не положит трубку _delay_ms(100); // Защита от дребезга контактов }
void clunet_init() { sei(); CLUNET_SEND_INIT; CLUNET_READ_INIT; CLUNET_TIMER_INIT; CLUNET_INIT_INT; char reset_source = MCUCSR; clunet_send ( CLUNET_BROADCAST_ADDRESS, CLUNET_PRIORITY_MESSAGE, CLUNET_COMMAND_BOOT_COMPLETED, &reset_source, sizeof(reset_source) ); MCUCSR = 0; }
int answer_record(char* filename1, char* filename2, char use_beep) // Отвечает, записывает сообщение, { if (answer_play(filename1)) return 1; // Отвечаем, предлагаем оставить сообщение if (use_beep) beep(3000, 500); // Биип sprintf(buffer, "/%08lu.wav", record_num); // Формируем имя файла clunet_send(CLUNET_BROADCAST_ADDRESS, CLUNET_PRIORITY_INFO, CLUNET_COMMAND_INTERCOM_MESSAGE, (char*)&record_num, sizeof(record_num)); // Отправляем в сеть сообщение record_num++; eeprom_write_dword((void*)0, record_num); // Запоминаем кол-во записей if (rec_wav(buffer) == 0) // Пишем сообщение { int s = 0; long int totalSize = 0; while (s >= 0 && totalSize < 8000UL*RECORD_MAX_LENGTH) { s = sound_write(); totalSize += s; if (!LINE_POWER || OFFHOOK) // Сняли трубку, или сигнал исчез { sound_stop(); return 1; } } sound_stop(); } if (play_wav_pgm(filename2) == 0) // Если пациент дождался, благодарим { while (sound_read() >= 0) { if (!LINE_POWER || OFFHOOK) // Сняли трубку, или сигнал исчез { sound_stop(); return 1; } } sound_stop(); } return 0; }
void send_current_mode(unsigned char dest) { buffer[0] = mode_current; buffer[1] = mode_temp; clunet_send(dest, CLUNET_PRIORITY_INFO, CLUNET_COMMAND_INTERCOM_MODE_INFO, (char*)&buffer, 2); // Отправляем в сеть текущий режим }