Ноя 01

AVR упрощаем TWI (I2C)

Давно уже написал, а выложить все как-то влом было. Но если вдруг, кому потребуется, простенькая библиотечка для работы с Two-Wire Interface (TWI, он же I2C) на AVR вообще и ATMega328p (та самая, которая в arduino nano v3 стоит) в частности.

Пользоваться проще некуда, подглядеть в libtwi.h всегда можно.

Скачать на гитхабе github.com/bevice/libtwi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "main.h"
#include "libtwi.h"
#include <util/delay.h>
void setup() {
    twi_init();
    DDRB |= _BV(PB5); // включим PB5 на выход, на Arduino Nano там светодиодик
 
}
 
#define DATA_SIZE 10
static uint8_t data[DATA_SIZE] ={0};
 
void twi_cb(uint8_t status){
    if(status!= TWI_STATUS_ERROR) // если все прочиталось - перевернем светодиод
        DDRB ^= _BV(PB5);
}
 
int main() {
    setup();
 
    while (1) {
        // для 24CXX при записи передается адрес и следом данные.
        uint8_t buff[] = {0x10,1,2,3,4,5}; 
        // передаем buff в железку с адресом  0xA0, 
        // как закончим передавать - дергаем twi_cb
        twi_transmit_data(0xA0, sizeof(buff), buff, &twi_cb);
 
        _delay_ms(1000);
 
        // читаем  DATA_SIZE байт из железки 
        // с адресом 0xA0 начиная с регистра 0x10
        // как в буффер data, как дочитаем
        //  - попадем в коллбек twi_cb с соответствующим статусом
    twi_receive_data_adr8(0xA0, 0x10, DATA_SIZE, data, &twi_cb);
 
    _delay_ms(1000);
    }
}
Июл 08

Такие дела..


Сижу отлаживаю железку на китайской arduino-nano-v3, тыкаю анализатором на RX ногу, а там пусто, иголки одни. Хотя AVR-ка точно с уарта читает и отвечает как надо.
А на самом деле-то не должна, полтора вольта за логический 0 это вообще как?

Июн 08

Asterisk, Lua и MySQL. Добавляем номер в черный список

Табличка немного отличается от предыдущего поста, поле number уникальное.

Пишем макрос:

extensions['macro-ban'] = {
        s = function()
                cid = channel.CALLERID("num"):get()
                query = "INSERT INTO blacklist (number, expires) VALUES ('" .. cid .. "', date_add(NOW(), INTERVAL 1 DAY)) on duplicate key update expires = date_add(NOW() INTERVAL 1 DAY);"
                local con = assert (env:connect(DB_NAME,DB_USER,DB_PASSWORD))
                assert (con:execute(query))
                con:close()
        end
};

Добалвяем макрос в features.conf:

[applicationmap]
ban => *5,peer/callee,macro(ban)

и не забываем включить в __DYNAMIC_FEATURES в диалплане:

extensions = {
    ["incoming"] = {
        ["DID"] = function()
            channel.__DYNAMIC_FEATURES = "ban"
            app.dial("SIP/100")
        end;
    }
}

Теперь ответивший нажатием *5 может добавить номер звонящего в черный список.

Июн 06

Asterisk, LUA и MySQL. Черный Список.

С помощью LUA делается элементарно:

В MySQL делаем табличку blacklist:

CREATE TABLE blacklist (
  NUMBER VARCHAR(20) NOT NULL,
  expires datetime DEFAULT NULL
)

Подключаем к LUA библиотеку luaSQL и luasql.mysql для работы с базой данных

 
-- расскажем, где искать
package.cpath = package.cpath .. ";/usr/lib/i386-linux-gnu/lua/5.1/?.so" 
-- и подключем
local luasql = require "luasql.mysql"
local mysql = assert (luasql.mysql())
 
-- данные для подключения к базе MySQL
local DB_HOST = "localhost"
local DB_NAME = "db_name"
local DB_USER = "db_user"
local DB_PASSWORD = "db_passwod"
 
-- и пишем функцию проверки: 
function is_banned(cid_number)
        local con = assert (env:connect(DB_NAME,DB_USER,DB_PASSWORD))
        local cur = assert (con:execute("SELECT * FROM blacklist where '".. cid_number.."' like number and (expires>now() or expires is NULL);"))
        c = cur:numrows()
        cur:close()
        con:close()
        return c>0
end
 
 
-- а дальше и начинаем использовать:
 
extensions = {
    ["incoming"] = {
        ["DID"] = function() 
            if is_banned(channel.CALLERID["number"]:get()) then
                -- Номер в черном списке, что-то с ним делаем
                app.answer()
                app.wait(1)
                app.hangup()
            end;
        end;
    }
}

Конечно, для полноценного использования нужно добавить индексы в базу и по-хорошему еще разрулить ситуацию, когда база данных недоступна.
А чуть позже мы добавим бан номера по кнопке оператора.

Июн 05

Asterisk и Lua. Очень быстрый старт

Астериск из коробки может исползовать язык программирования LUA для написания диалплана. И это прекрасно! В диалплане можно подключить любую установленную lua-библиотеку и получить доступ к базе данных (SQLite, MySQL, PostgreSQL), работать с сетью, читать-записывать файлики. Причем, делается это все довольно просто.
Зная любой язык программирования и вооружившись справочником по синтаксису LUA, а так же прочитав пару абзацев ниже можно без проблем начать использовать всю мощь этой связки.
Continue reading

Май 03

DHCP client без default GW

Чтобы dhclient получал default route только с одного интерфейса, делаем хук в
/etc/dhcp/dhclient-enter-hooks.d
такого содержания:

#!/bin/sh
INTERFACE_DEFAULT_ROUTE="eth0"
case "$reason" in
    BOUND|RENEW|REBIND|REBOOT|TIMEOUT)
    if [ ${interface} != $INTERFACE_DEFAULT_ROUTE ]; then
        unset new_routers
    fi
      ;;
esac

после чего основной шлюз будет ловиться только у интерфейса INTERFACE_DEFAULT_ROUTE
и не надо костыльно править client.conf как все советуют.

Апр 27

AVR CMake

Clion & AVRВот уже несколько лет пользуюсь CMake-ом, чтобы собирать проекты под AVR. Сподвиг на этом конечно же вышедший осенью 2014 Jetbrains CLion, который как оказалось идеально подходит для написания кода под Atmel AVR. Короче, рекомендую.
Возможно, для корректной работы нужно будет установить переменную среды AVR_FIND_ROOT_PATH — на папку с avr (содержащую lib и include), а так же папка с avr-gcc, avr-g++, avr-objcopy, avr-size должны находиться в PATH. Ну или доработать напильником generic-gcc-avr.cmake

В общем, шаблон тут: https://github.com/bevice/avr_cmake_template
Continue reading

Мар 28

Прячем виртуальный хост в малиновый пирог

МагияПро OpenVPN написано уже довольно дофига. И даже мной. Но вот возникла необходимость сделать ВЖУХ.


Итак:
Сервер на Raspberry-pi, eth0 в мост с tap1
Клиент на libvirt хост, VPN поднимает хост, отдает мостом (br1 tap1) гостю. Гость прозрачно сидит в локальной сети, про VPN не знает.
Можно отключить гостю virbr0, тогда он еще и в интернет ходить будет через впн. Такая вот петрушка.
Имеем — без малинки сервера нет, но малинка сама по себе не знает откуда он берется, изучать её на в другом месте или при выключенном VPN-клиенте бессмыслительно. Еще логи в /dev/null переправить и предусмотреть аварийное выключение VPN клиента.
А еще порт понестандартнее и ваще огонь.
Конфиги чуть внизу.
Continue reading