--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import sys
+reload(sys)
+sys.setdefaultencoding('utf-8')
+
+from ConfigParser import ConfigParser
+import paho.mqtt.client as paho
+from pymessaging.sms import SmsDeliver
+
+import sqlite3
+from sqlite3 import Error
+
+from tempfile import mkstemp
+from shutil import move
+
+conffile = sys.argv[1:2]
+
+config = ConfigParser()
+config.add_section('sms')
+# set defaults for anonymous auth
+config.set('sms', 'tmpfile', '/tmp/sms.db')
+config.read(conffile)
+
+sms_db = config.get('sms','tmpfile')
+
+try:
+ conn = sqlite3.connect(sms_db)
+
+ cur = conn.cursor()
+ cur.execute("select ref from sms_parts group by ref having max(datetime) is null or (julianday('now')-julianday(max(datetime)))>0.005;")
+ refs=cur.fetchall()
+ for ref in refs:
+ cur.execute("select text from sms_parts where ref=%s order by seq" % (ref))
+ full_text=''.join(rec[0] for rec in cur.fetchall()).replace("\"","")
+ f,path=mkstemp(suffix=".call")
+ f=open(path,"w")
+ f.write("Application: Dial\n")
+ f.write("Channel: Local/smsraw@DID_mobile\n")
+ f.write("Context: smsraw\n")
+ f.write("Setvar: SMS_FULL_TEXT=%s" % full_text)
+ f.close()
+ move(path,'/var/spool/asterisk/outgoing')
+ cur.execute("delete from sms_parts where ref=%s" % (ref))
+ conn.commit()
+
+except:
+ None
\ No newline at end of file
import json
+from os import getpid,uname
from pprint import pprint
+client_name='agi-'+uname()[1]+'-'+str(getpid())
+print client_name
+
conffile, topic = sys.argv[1:3]
config = ConfigParser()
# done
agi_exit(0)
-client = paho.Client('agi')
+client = paho.Client(client_name)
client.username_pw_set(mqtt_username, mqtt_password)
client.connect(mqtt_server, port=mqtt_port)
client.on_connect = on_connect
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#
+# Usage:
+# AGI(/etc/asterisk/agi/mqtt,/etc/asterisk/agi/mqtt.cfg,calls/missed)
+# or, to override the extension:
+# AGI(/etc/asterisk/agi/mqtt,/etc/asterisk/agi/mqtt.cfg,calls/missed,+43123456789)
+#
+
+import sys
+reload(sys)
+sys.setdefaultencoding('utf-8')
+
+from ConfigParser import ConfigParser
+import paho.mqtt.client as paho
+from pymessaging.sms import SmsDeliver
+
+import json
+
+from os import getpid,uname
+from pprint import pprint
+
+import sqlite3
+from sqlite3 import Error
+
+from os import remove,system
+
+client_name='agi-'+uname()[1]+'-'+str(getpid())
+
+conffile, topic, base64 = sys.argv[1:4]
+
+config = ConfigParser()
+config.add_section('mqtt')
+config.add_section('sms')
+# set defaults for anonymous auth
+config.set('mqtt', 'username', '')
+config.set('mqtt', 'password', '')
+config.set('mqtt', 'port', '1883')
+config.set('sms', 'tmpfile', '/tmp/sms.db')
+config.read(conffile)
+
+mqtt_server = config.get('mqtt', 'server')
+mqtt_port = config.getint('mqtt', 'port')
+mqtt_username = config.get('mqtt', 'username')
+mqtt_password = config.get('mqtt', 'password')
+sms_db = config.get('sms','tmpfile')
+
+try:
+ conn = sqlite3.connect(sms_db)
+except:
+ remove(sms_db)
+ conn = sqlite3.connect(sms_db)
+
+agi = []
+while 1:
+ line = sys.stdin.readline()
+ if not line or line == "\n":
+ break
+ agi.append(line)
+
+agi = dict([line.rstrip('\n').replace('agi_', '', 1).split(': ', 1) for line in agi])
+
+agi['base64'] = base64
+
+full_text=""
+try:
+ sms=SmsDeliver(base64.decode('base64').split('\r\n')[1])
+ if 'cnt' in sms.data:
+ sms_type='sms-multipart'
+ part_count=sms.data['cnt']
+ part_number=sms.data['seq']
+ ref=sms.data['ref']
+ agi['part-count']=part_count
+ agi['part-number']=part_number
+ agi['ref']=ref
+ else:
+ sms_type='sms'
+ agi['sms-type']=sms_type
+ sms_text=sms.data['text'].encode('utf-8')
+ agi['sms_text']=sms_text
+ if sms_type=='sms':
+ full_text=sms_text
+ else:
+ cur = conn.cursor()
+ cur.execute("create table if not exists sms_parts (ref integer,cnt integer,seq integer,datetime timestamp default current_timestamp,text varchar(255))")
+ cur.execute("insert into sms_parts(ref,cnt,seq,text) values(%s,%s,%s,\'%s\')" % (ref,part_count,part_number,sms_text))
+ cur.execute("select count(*),cnt from sms_parts where ref=%s" % (ref))
+ received,cnt=cur.fetchone()
+ if received==cnt:
+ cur.execute("select text from sms_parts where ref=%s order by seq" % (ref))
+ full_text=''.join(rec[0] for rec in cur.fetchall())
+# full_text=full_text.replace("\"","")
+ agi["full_text"]=full_text
+ cur.execute("delete from sms_parts where ref=%s" % (ref))
+ conn.commit()
+except:
+ raise
+
+if full_text:
+ print full_text
+ f1=open("/tmp/sms.log","w+")
+ f1.write(full_text.strip().encode('utf-8'))
+ f1.close()
+
+def agi_exit(rc, *args):
+ if rc != 0:
+ print "VERBOSE rc=%s %s" % (rc, args)
+ sys.exit(rc)
+
+def on_connect(mosq, rc, *args):
+ if rc != 0:
+ agi_exit(1, "Connection failed: %d" % rc)
+
+def on_publish(mosq, *args):
+ # done
+ agi_exit(0)
+
+client = paho.Client(client_name)
+client.username_pw_set(mqtt_username, mqtt_password)
+client.connect(mqtt_server, port=mqtt_port)
+client.on_connect = on_connect
+client.on_publish = on_publish
+
+client.publish(topic, payload=json.dumps(agi))
+client.loop()
+agi_exit(1, "Message publish timed out")
#!/usr/bin/lua
+json = require("json")
+
function getConfig(configname)
local uci=require("uci")
mqtt_passwd = cur.get(config,"mqtt","password")
if mqtt_host and not mqtt_id then
- mqtt_id="beaconmon"
+ socket = require("socket")
+ posix = require("posix")
+ hostname = socket.dns.gethostname()
+ pid = posix.getpid()
+ mqtt_id="beaconmon-"..hostname.."-"..pid
end
if mqtt_host and not mqtt_port then
end
function printLog(str)
- if logging=="on" then
+ if logging=="yes" then
capture("logger -t beaconmon "..str)
else
print(str)
function open_dump()
- run_command("/bin/kill `/usr/bin/pgrep hcidump`")
+ run_command("/bin/kill `/usr/bin/pgrep btmon`")
run_command("/bin/kill `/usr/bin/pgrep hcitool`")
- f = assert(io.popen ("/usr/bin/hcidump --raw"))
+ f = assert(io.popen ("/usr/bin/stdbuf -o0 /usr/bin/btmon"))
run_command("/usr/bin/hciconfig hci0 down")
run_command("/usr/bin/hciconfig hci0 up")
- f_null = assert(io.popen ("/usr/bin/hcitool lescan --duplicates"))
+ f_null = assert(io.popen ("/usr/bin/hcitool lescan --duplicates --passive"))
return f
end
function dump(o)
- if type(o) == 'table' then
- local s = '{ '
- for k,v in pairs(o) do
- if type(k) ~= 'number' then k = '"'..k..'"' end
- s = s .. '['..k..'] = ' .. dump(v) .. ','
--- s = s .. dump(v) .. ','
- end
- return s .. '} '
- else
- return tostring(o)
- end
+ return json.encode(o)
end
function trim(s)
end
function mqtt_pub(path,value)
- printLog("Pub "..path.." "..value)
- return mqtt_client:publish(path,value)
+ res=mqtt_client:publish(path,value)
+ printLog("Pub "..path.." "..value.." returned "..res);
+ return res
end
function process_packet(packet)
- local bytes={}
- local idx=1
- local len
local mac
- local flags
- local power
- local tx
- local type
- local paysublen
local uuid
- local major
- local minor
local details
+ local type
+ local name
+
+ mac = packet['Address']
+ uuid = packet['uuid']
+ type = packet['Type']
+ name = packet['Name (complete)']
+
+ if type=='iBeacon' then
+ details=uuid
+ elseif name then
+ if not(type) then
+ type="name"
+ end
+ details=name
+ else
+ if not type then
+ type='unknown'
+ end
+ details=mac
+ end
- if packet:len()>1 then
-
- while packet:len()>2 do
- bytes[idx]=trim(packet:sub(1,3))
- idx=idx+1
- packet=packet:sub(4)
- end
- len = idx-1
-
- if bytes[1]=='04' and bytes[2]=='3E' then
- -- BLE Beacon?
- type=""
- mac=bytes[13]..':'..bytes[12]..':'..bytes[11]..':'..bytes[10]..':'..bytes[9]..':'..bytes[8]
- flags=bytes[14]
- power=tonumber("0x"..bytes[len-1])-256
- tx=tonumber("0x"..bytes[len])-256
- local j = 15
- while j<len-2 do
- paysublen=tonumber('0x'..bytes[j])
- if bytes[j+1]=="FF" and bytes[j+2]=="4C" and bytes[j+3]=="00" and bytes[j+4]=="02" and bytes[j+5]=="15" then
- -- Standard UUID iBeacon
- type="ibeacon"
- local uuid1=bytes[j+6]..bytes[j+7]..bytes[j+8]..bytes[j+9]
- local uuid2=bytes[j+10]..bytes[j+11]
- local uuid3=bytes[j+12]..bytes[j+13]
- local uuid4=bytes[j+14]..bytes[j+15]
- local uuid5=bytes[j+16]..bytes[j+17]..bytes[j+18]..bytes[j+19]..bytes[j+20]..bytes[j+21]
- uuid=string.lower(uuid1..'-'..uuid2..'-'..uuid3..'-'..uuid4..'-'..uuid5)
- major=bytes[j+23]..bytes[j+22]
- minor=bytes[j+25]..bytes[j+24]
- end
- j=j+1+paysublen
- end
- if type=="ibeacon" then
- printLog(string.format("{type:'ibeacon',mac:'%s',uuid:'%s',major:'%s',minor:'%s',power:%d,tx:%d}",mac,uuid,major,minor,power,tx))
- details=uuid..'/'..major..'/'..minor
- else
- type='unknown'
- details=dump(bytes)
--- printLog(details)
- end
- if not (type=="unknown") then
- mqtt_path=string.gsub(mqtt_topic,"{(.-)}",
- function (name)
- if name=="type" then
- return mqtt_encode(type)
- elseif name=="details" then
- return mqtt_encode(details)
- else
- return '{'..name..'}'
- end
- end)
+ if not (type=="unknown") then
+ mqtt_path=string.gsub(mqtt_topic,"{(.-)}",
+ function (name)
+ if name=="type" then
+ return mqtt_encode(type)
+ elseif name=="details" then
+ return mqtt_encode(details)
+ else
+ return '{'..name..'}'
+ end
+ end)
- if not pcall(mqtt_pub,mqtt_path,tx) then
- printLog('Reconnecting MQTT...')
- mqtt_client:connect(mqtt_id)
- end
-
- end
+ if not pcall(mqtt_pub,mqtt_path,dump(packet)) then
+ printLog('Reconnecting MQTT...')
+ mqtt_client:connect(mqtt_id)
end
+
end
end
-function read_loop()
-
- packet = ""
-
- for line in inp:lines() do
-
- lchr=line:sub(1,1)
- line=trim(line)
-
- if lchr=="<" or lchr==">" then
- line = trim(line:sub(2))
- end
+function starts(String,Start)
+ return string.sub(String,1,string.len(Start))==Start
+end
- if not (lchr == " ") then
- process_packet(packet)
- packet = ""
- end
+function split(inputstr, sep)
+ if sep == nil then
+ sep = "%s"
+ end
+ local t={} ; i=1
+ for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
+ t[i] = str
+ i = i + 1
+ end
+ return t
+end
- llen=line:len()
+function read_loop()
- if llen<59 then
- packet = packet .. " " .. line
- process_packet(packet)
- packet=""
- else
- packet = packet .. " " .. line
- end
+ packet={}
+ inbound=false
+
+ while true do
+
+ str=inp:read("*l")
+
+ if str then
+
+ str=trim(str)
+
+ if inbound then
+ t = split(str,':')
+ if #t>=2 then
+ name=t[1]
+ value=trim(table.concat(t,':',2))
+ if name=="Address" then
+ value=split(value)[1]
+ end
+ packet[name]=value
+ elseif #t==1 and name then
+ if not(packet[name..'.list']) then
+ packet[name..'.list']={}
+ end
+ table.insert(packet[name..'.list'],(trim(t[1])))
+ end
+ end
+
+ if starts(str,'> HCI Event: LE Meta Event (0x3e)') then
+ inbound=true
+ name=nil
+ elseif starts(str,'RSSI:') then
+ inbound=false
+ process_packet(packet)
+ packet={}
+ end
+
+ end
end
end
+io.stdout:setvbuf('no')
+io.stdin:setvbuf('no')
+
getConfig(arg[1])
if mqtt_host then
- MQTT = require "paho.mqtt"
- mqtt_client = MQTT.client.create(mqtt_host, mqtt_port)
+ MQTT = require "mosquitto"
+ mqtt_client = MQTT.new(mqtt_id)
if mqtt_user then
- mqtt_client:auth(mqtt_user, mqtt_passwd)
+ mqtt_client:login_set(mqtt_user, mqtt_passwd)
end
- mqtt_client:connect(mqtt_id)
+ mqtt_client:connect(mqtt_host,mqtt_port)
end
inp = open_dump()
#!/bin/bash
+id=`hostname`-$$
+
if [ "$1" = "stop" ]
then
# сами остаемся слушать команды
-mosquitto_sub -v -h $mqhost -p $mqport -t "$mqcmd/#" -u $mquser -P $mqpassword | while read line
+mosquitto_sub -i mqtt-mpd-$id -v -h $mqhost -p $mqport -t "$mqcmd/#" -u $mquser -P $mqpassword | while read line
do
template="s!$mqcmd/!!"
esac
;;
currentnum)
- $mpccmd pause
$mpccmd play $arg
;;
repeat|random|single|consume)
. /opt/mqtt-mpd/mqmpd.cfg
+id=`hostname`-$$
+
host=$1
passwd=$2
while :
do
- $command idle
- if [ $? = 0 ]
- then
# current=`mpc -h $host -P $passwd current | sed 's/"/\"/g'`
# volume=`mpc -h $host -P $passwd volume | cut -d: -f2 | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'`
single=${str3[7]}
consume=${str3[9]}
else
- current='-'
- status='stopped'
- current_track_num='0'
- tracks_in_list='0'
- current_pos='-'
- track_length='-'
- str3=( ${array[0]})
- volume=`echo ${str3[1]} | sed 's/%//'`
- if [ "$volume" = "n/a" ]
+ if [ ${#array[@]} = 1 ]
then
+ current='-'
+ status='stopped'
+ current_track_num='0'
+ tracks_in_list='0'
+ current_pos='-'
+ track_length='-'
+ str3=( ${array[0]})
+ volume=`echo ${str3[1]} | sed 's/%//'`
+ if [ "$volume" = "n/a" ]
+ then
+ volume="0"
+ fi
+ repeat=${str3[3]}
+ random=${str3[5]}
+ single=${str3[7]}
+ consume=${str3[9]}
+ else
+ # not responding or error
+ current='-'
+ status='failed'
+ current_track_num='0'
+ tracks_in_list='0'
+ current_pos='-'
+ track_length='-'
volume="0"
- fi
- repeat=${str3[3]}
- random=${str3[5]}
- single=${str3[7]}
- consume=${str3[9]}
+ repeat="off"
+ random="off"
+ single="off"
+ consume="off"
+ fi
fi
+
+ sleep 0.2
+ mosquitto_pub -i mqtt-mpd-$id -h $mqhost -p $mqport -t $mqtopic/$host/nowplaying -m "$current" -u $mquser -P $mqpassword
+ mosquitto_pub -i mqtt-mpd-$id -h $mqhost -p $mqport -t $mqtopic/$host/volume -m "$volume" -u $mquser -P $mqpassword
+ mosquitto_pub -i mqtt-mpd-$id -h $mqhost -p $mqport -t $mqtopic/$host/status -m "$status" -u $mquser -P $mqpassword
+ mosquitto_pub -i mqtt-mpd-$id -h $mqhost -p $mqport -t $mqtopic/$host/currentnum -m "$current_track_num" -u $mquser -P $mqpassword
+ mosquitto_pub -i mqtt-mpd-$id -h $mqhost -p $mqport -t $mqtopic/$host/tracks -m "$tracks_in_list" -u $mquser -P $mqpassword
+ mosquitto_pub -i mqtt-mpd-$id -h $mqhost -p $mqport -t $mqtopic/$host/currentpos -m "$current_pos" -u $mquser -P $mqpassword
+ mosquitto_pub -i mqtt-mpd-$id -h $mqhost -p $mqport -t $mqtopic/$host/tracklen -m "$track_length" -u $mquser -P $mqpassword
+ mosquitto_pub -i mqtt-mpd-$id -h $mqhost -p $mqport -t $mqtopic/$host/repeat -m "$repeat" -u $mquser -P $mqpassword
+ mosquitto_pub -i mqtt-mpd-$id -h $mqhost -p $mqport -t $mqtopic/$host/random -m "$random" -u $mquser -P $mqpassword
+ mosquitto_pub -i mqtt-mpd-$id -h $mqhost -p $mqport -t $mqtopic/$host/single -m "$single" -u $mquser -P $mqpassword
+ mosquitto_pub -i mqtt-mpd-$id -h $mqhost -p $mqport -t $mqtopic/$host/consume -m "$consume" -u $mquser -P $mqpassword
- mosquitto_pub -h $mqhost -p $mqport -t $mqtopic/$host/nowplaying -m "$current" -u $mquser -P $mqpassword
- mosquitto_pub -h $mqhost -p $mqport -t $mqtopic/$host/volume -m "$volume" -u $mquser -P $mqpassword
- mosquitto_pub -h $mqhost -p $mqport -t $mqtopic/$host/status -m "$status" -u $mquser -P $mqpassword
- mosquitto_pub -h $mqhost -p $mqport -t $mqtopic/$host/currentnum -m "$current_track_num" -u $mquser -P $mqpassword
- mosquitto_pub -h $mqhost -p $mqport -t $mqtopic/$host/tracks -m "$tracks_in_list" -u $mquser -P $mqpassword
- mosquitto_pub -h $mqhost -p $mqport -t $mqtopic/$host/currentpos -m "$current_pos" -u $mquser -P $mqpassword
- mosquitto_pub -h $mqhost -p $mqport -t $mqtopic/$host/tracklen -m "$track_length" -u $mquser -P $mqpassword
- mosquitto_pub -h $mqhost -p $mqport -t $mqtopic/$host/repeat -m "$repeat" -u $mquser -P $mqpassword
- mosquitto_pub -h $mqhost -p $mqport -t $mqtopic/$host/random -m "$random" -u $mquser -P $mqpassword
- mosquitto_pub -h $mqhost -p $mqport -t $mqtopic/$host/single -m "$single" -u $mquser -P $mqpassword
- mosquitto_pub -h $mqhost -p $mqport -t $mqtopic/$host/consume -m "$consume" -u $mquser -P $mqpassword
-
- else
- sleep 30
- fi
+ $command idle
+ if [ $? != 0 ]
+ then
+ sleep 60
+ fi
+
done