INCLUDE rtcu.inc
#DEFINE TAG_COUNT 8
#DEFINE ST_DISCON 0
#DEFINE ST_FOUND 1
#DEFINE ST_CON 2
#DEFINE ITAG_SERVICE_UUID "0000ffe0-0000-1000-8000-00805f9b34fb"
#DEFINE ITAG_NOTIFY_UUID "0000ffe1-0000-1000-8000-00805f9b34fb"
#DEFINE ALERT_SERVICE_UUID "00001802-0000-1000-8000-00805f9b34fb"
#DEFINE ALERT_LEVEL_UUID "00002a06-0000-1000-8000-00805f9b34fb"
STRUCT_BLOCK iTag_data;
address : STRING;
alert_s : INT;
alert_c : INT;
status : INT;
END_STRUCT_BLOCK;
VAR_INPUT
END_VAR;
VAR_OUTPUT
END_VAR;
VAR
devInfo : btDeviceInfo;
tags : ARRAY [1..TAG_COUNT] OF iTag_data;
tagLock : MUTEX;
END_VAR;
FUNCTION getError : STRING;
VAR_INPUT
v : INT;
END_VAR;
IF v > _BT_OK THEN
getError := "";
ELSE
CASE v OF
1: getError := "OK";
0: getError := "Not supported";
-1: getError := "Not open";
-2: getError := "Alreay open";
-3: getError := "Not present";
-4: getError := "Not found";
-5: getError := "Adapter not found";
-6: getError := "Invalid adapter";
-7: getError := "No more resources";
-8: getError := "Invalid argument";
-9: getError := "No data available";
-10: getError := "Already paired";
-11: getError := "Pair";
-12: getError := "Busy";
-13: getError := "Wrong State";
-14: getError := "Connection failed";
-15: getError := "Operation not available";
-16: getError := "Op not permitted";
-17: getError := "Timeout";
-18: getError := "Auth";
-19: getError := "Not connected";
-99: getError := "Generic error";
ELSE
getError := strFormat(format:="Unknown error: \1", v1:=v);
END_CASE;
END_IF;
END_FUNCTION;
FUNCTION DeviceFound;
VAR_INPUT
dev : STRING;
END_VAR;
VAR
i : INT;
j : INT;
found : BOOL := FALSE;
END_VAR;
devInfo(dev := dev);
IF devInfo.status <> _BT_OK THEN
DebugFmt(message:="devInfo() failed: \1 "+getError(v:=devInfo.status)+", " + dev, v1:=devInfo.status);
END_IF;
IF devInfo.name = "" THEN
RETURN;
END_IF;
DebugFmt(message:=" " + devInfo.name+" , Class: \4, type: \3, connected: \1, tx power: \2",
v2:=devInfo.tx_power, v4:=devInfo.clss, v3:=devInfo.addr_type, v1:=INT(devInfo.connected));
DebugFmt(message:=" status: \1, paired: \2, trusted: \3, RSSI: \4", v1:=devInfo.status,
v2:=INT(devInfo.paired), v3:=INT(devInfo.trusted), v4:=devInfo.RSSI);
DebugFmt(message:=" Profiles: \1", v1:=devInfo.profiles);
FOR i:= 1 TO 16 DO
IF devInfo.uuid[i] <> "" THEN
DebugFmt(message:=" [\1]: " + devInfo.uuid[i], v1:=i);
END_IF;
IF devInfo.UUID[i] = ITAG_SERVICE_UUID THEN
DebugMsg(message:=" Found iTAG device");
mxLock(mx:=tagLock);
FOR j := 1 TO TAG_COUNT DO
IF tags[j].status = ST_DISCON THEN
tags[j].status := ST_FOUND;
tags[j].address := dev;
tags[j].alert_s := -1;
tags[j].alert_c := -1;
DebugFmt(message:=" Stored iTag in entry \1", v1:=j);
EXIT;
END_IF;
END_FOR;
mxUnlock(mx:=tagLock);
END_IF;
END_FOR;
END_FUNCTION;
FUNCTION DeviceLost;
VAR_INPUT
dev : STRING;
END_VAR;
VAR
j : INT;
END_VAR;
DebugMsg(message:="Lost device "+dev);
mxLock(mx:=tagLock);
FOR j := 1 TO TAG_COUNT DO
IF tags[j].status > ST_DISCON AND (tags[j].address = dev) THEN
tags[j].status := ST_DISCON;
DebugFmt(message:="Removed iTag from entry \1", v1:=j);
END_IF;
END_FOR;
mxUnlock(mx:=tagLock);
END_FUNCTION;
THREAD_BLOCK thBtEvent
VAR
rc : INT;
i : INT;
address : STRING;
ch : SINT;
port : SINT;
service : INT;
chara : INT;
size : INT;
level : SINT := 0;
data : ARRAY [1..10] OF SINT;
END_VAR;
WHILE TRUE DO
rc := btWaitEvent(timeout:=10000, dev := address);
IF rc <> _BT_ERR_TIMEOUT THEN
DebugFmt(message:="event \1: "+address, v1:=rc);
CASE rc OF
_BT_EVENT_INCOMING:
rc := btHandleSerialPortIncomingConnection(ch := ch, port := port);
DebugFmt(message:="btHandleSerialPortIncomingConnection(\2) : \1, \3", v1:=rc, v2:=ch, v3:=port);
_BT_EVENT_DEV_FOUND:
DebugFmt(message:="Found "+address);
DeviceFound(dev := address);
_BT_EVENT_DEV_LOST:
DebugFmt(message:="Lost "+address);
DeviceLost(dev := address);
_BT_EVENT_PAIR_REQ:
DebugFmt(message:="Requested confirm for "+address);
rc := btSendPairResponse(accept:=FALSE);
DebugFmt(message:="btSendPairResponse: \1", v1:=rc);
_BT_EVENT_NOTIFY:
size := SIZEOF(data);
rc := btleHandleNotification(service := service, char := chara, size := size, data:=ADDR(data));
DebugFmt(message:="btleHandleNotification: \1, service \2, char \3, sz: \4", v1:=rc, v2:=service,
v3:=chara, v4:=size);
IF size > 0 THEN
FOR i := 1 TO TAG_COUNT DO
IF tags[i].status = 2 THEN
level := 2;
rc := btleWriteVal(dev:=tags[i].address, service:=tags[i].alert_s, char :=tags[i].alert_c,
data :=ADDR(level) , size := 1);
IF rc <> _BT_OK THEN
DebugFmt(message:="btleWriteVal: \1", v1:=rc);
END_IF;
Sleep (delay:=250);
level := 0;
rc := btleWriteVal(dev:=tags[i].address, service:=tags[i].alert_s, char :=tags[i].alert_c,
data :=ADDR(level) , size := 1);
DebugFmt(message:="btleWriteVal: \1", v1:=rc);
IF rc = _BT_ERR_NOT_CONNECTED THEN
rc := btleDisconnect(dev := tags[i].address);
DebugFmt(message:="btleDisconnect: \1 ", v1:=rc);
rc := btDeviceRemove(dev := tags[i].address);
DebugFmt(message:="btDeviceRemove: \1 ", v1:=rc);
END_IF;
Sleep(delay:=500);
END_IF;
END_FOR;
END_IF;
END_CASE;
rc := btEventDone();
DebugFmt(message:="btEventDone: \1 "+getError(v:=rc), v1:=rc);
END_IF;
END_WHILE;
END_THREAD_BLOCK;
PROGRAM iTag;
VAR
rc : INT;
thEvent : thBtEvent;
i : INT;
service : INT;
s : INT;
s_rc : INT;
sUUID : STRING;
primary : BOOL;
flags : DINT;
ch : INT;
c : INT;
c_rc : INT;
cUUID : STRING;
END_VAR;
tagLock := mxInit();
rc := btPower();
DebugFmt(message:="btPower: \1 "+getError(v:=rc)+"", v1:=rc);
thEvent();
rc := btDeviceRemove();
DebugFmt(message:="btDeviceRemove: \1 ", v1:=rc);
rc := btScanStart(transport := 2);
DebugFmt(message:="btScanStart: \1 "+getError(v:=rc), v1:=rc);
BEGIN
DebugFmt(message:="Devices:");
FOR i := 1 TO TAG_COUNT DO
mxLock(mx:=tagLock);
DebugFmt(message:="Dev \1: status \2", v1:=i, v2:=tags[i].status);
IF tags[i].status = ST_FOUND THEN
rc := btleConnect (dev:=tags[i].address);
DebugFmt(message:="btleConnect: \1", v1:=rc);
IF rc = _BT_OK THEN
s := 1;
REPEAT
s_rc := btleServiceGet(dev:=tags[i].address, idx:=s, service:=service, primary:=primary, UUID:=sUUID);
IF s_rc = _BT_OK THEN
DebugFmt(message:=" Service: \1, primary: \2, UUID: "+sUUID, v1:=service, v2:=INT(primary));
c := 1;
REPEAT
c_rc := btleCharGet(dev:=tags[i].address, idx:=c, service:=service, char:=ch, UUID:=cUUID, flags := flags);
IF c_rc = _BT_OK THEN
DebugFmt(message:=" Service: \1, Char: \2, flags: \4, UUID: "+cUUID, v1:=service, v2:=ch, v4:=flags);
IF sUUID = ALERT_SERVICE_UUID AND cUUID = ALERT_LEVEL_UUID THEN
tags[i].alert_s := service;
tags[i].alert_c := ch;
END_IF;
IF sUUID = ITAG_SERVICE_UUID AND cUUID = ITAG_NOTIFY_UUID THEN
rc := btleNotifyStart(dev := tags[i].address, service := service, char := ch);
DebugFmt(message:="btleNotifyStart "+tags[i].address+": \1", v1:=rc);
END_IF;
ELSE
DebugFmt(message:=" btleCharGet "+tags[i].address+": \1", v1:=c_rc);
END_IF;
c := c + 1;
UNTIL c_rc <> _BT_OK END_REPEAT;
ELSE
DebugFmt(message:=" btleServiceGet "+tags[i].address+": \1", v1:=s_rc);
END_IF;
s := s + 1;
UNTIL s_rc <> _BT_OK END_REPEAT;
tags[i].status := ST_CON;
END_IF;
END_IF;
mxUnlock(mx:=tagLock);
END_FOR;
DebugFmt(message:="");
Sleep(delay:=5000);
END;
END_PROGRAM;
|