Июл 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

Апр 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

Июн 15

UART размер экрана

Для общения через UART с железками (avr, stm32 и прочими) в основном использую GNU screen:

$ screen /dev/tty.ubserial 9600

А вот что-то дернуло, раскрасить вывод микроконтроллера и раскрасил (не мудрено, печатаем что-то вроде \033[31m и вперед, ну только цвета меняем). А потом поехало: захотелось печатать в разных местах экрана (\033[y;xH), а вот как напечатать в центре? Надо же знать размер экрана, а он у меня (да и у всех) каждый раз разный.
Долго возился, выяснил, что screen отдавать размер окна (\033[18t) не умеет. Зато DCS передает напрямую терминалу из которого запущен: вот и нашелся грязный хак: оборачиваем запрос размера в ESC-P последовательность, и вот уже знаем размер экрана.
Печатаем хитрую строку:

\033P\033[18t033\

и получаем ответ:

\[8;31;163t

31 строка, 163 колонки, а 8 — это номер CSI-репорта. Он всегда такой.

вот тут большой список похоже что вообще всех ESC-последовательностей которые терминалы поддерживают: ttssh2.osdn.jp

P.S.
Ну а бонусом — таким же способом можно поставить заголовок окна который screen ставить умеет только через жопу.

\033P\033]0;New Window Title\a\033\\
Дек 13

responseText ошибки при AJAX-запросе

За формирование страницы ошибки отвечает функция technical_500_response из django.views.debug,
программисты джанги пошли странным путем, жестко задав (без возможности настройки): если запрос AJAX — ответ будет текстом, в остальных случаях HTML.
Все бы ничего, но raise Http404(), например, плевать на этот механизм хотела, и все равно выбрасывает HTML, если выводить ошибку в консоль — сущий ад.
Изменить поведение можно например так:
Добавить Middleware которая, в случае ошибки уберет из request соответствующий заголовок,
дальше джанга отработает по своему алгоритму и вернет красивый HTML.
Криво конечно, т.к. пропадает возможность узнать был Ajax или не было, но не нужно патчить Django

1
2
3
4
class DisableAjaxException(object):
    @staticmethod
    def process_exception(req, exception):
        req.META['HTTP_X_REQUESTED_WITH'] = None

Ну и остается напомнить, порядок Middleware в settings.py важен