Skip to content

Commit

Permalink
EPROM download works now
Browse files Browse the repository at this point in the history
This allows also to extract arm/disarm pin from eprom so it does not
have to be hardcoded in the code.
  • Loading branch information
irekzielinski committed Jun 12, 2016
1 parent cd4f701 commit 7ce33e4
Show file tree
Hide file tree
Showing 7 changed files with 449 additions and 125 deletions.
2 changes: 1 addition & 1 deletion Libraries/PMax/MemoryMap.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once
#include <string.h>
//content is populated only once, on download, so it's OK to use dynamic memory allocation even on embeded devices
#define MAX_PAGES_CNT 15
#define MAX_PAGES_CNT 27
#define MAX_PAGE_SIZE 0x100
class MemoryMap
{
Expand Down
365 changes: 299 additions & 66 deletions Libraries/PMax/pmax.cpp

Large diffs are not rendered by default.

56 changes: 54 additions & 2 deletions Libraries/PMax/pmax.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@
#define PACKET_TIMEOUT_DEFINED 2000
#define MAX_ZONE_COUNT 31

//This Pin is a temporary pin for powerlink (this app). Does not have to match any of user or installer codes.
//If your pin is 1234, you need to return 0x1234 (this is strange, as 0x makes it hex, but the only way it works).
#define POWERLINK_PIN 0x3622;

class PowerMaxAlarm;

enum PmaxCommand
{
Pmax_ACK,
Pmax_PING,
Pmax_GETEVENTLOG,
Pmax_DISARM,
Pmax_ARMHOME,
Expand Down Expand Up @@ -142,6 +147,46 @@ struct PmQueueItem
const char* options;
};

struct PmConfig
{
bool parsedOK;

char installerPin[5];
char masterInstallerPin[5];
char powerLinkPin[5];
char userPins[48][5];

//telephone numbers to call:
char phone[4][15]; //15: max 14 digits + NULL

char serialNumber[15];
char eprom[17];
char software[17];

//panel max capabilities (not actual count used):
unsigned char maxZoneCnt;
unsigned char maxCustomCnt;
unsigned char maxUserCnt;
unsigned char maxPartitionCnt;
unsigned char maxSirenCnt;
unsigned char maxKeypad1Cnt;
unsigned char maxKeypad2Cnt;
unsigned char maxKeyfobCnt;

PmConfig()
{
Init();
}

void Init()
{
memset(this, 0, sizeof(PmConfig));
}

void DumpToJson(IOutput* outputStream);
int GetMasterPinAsHex() const;
};

class PowerMaxAlarm
{
//Flags with[*] are one-shot notifications of last event
Expand Down Expand Up @@ -169,6 +214,9 @@ class PowerMaxAlarm

FixedSizeQueue<PmQueueItem, MAX_SEND_QUEUE_DEPTH> m_sendQueue;

//config downloaded from PM, parsed using ProcessSettings
PmConfig m_cfg;

bool m_bEnrolCompleted;
bool m_bDownloadMode;
int m_iPanelType;
Expand All @@ -181,8 +229,13 @@ class PowerMaxAlarm
MemoryMap m_mapExtended;

PlinkCommand m_lastSentCommand;
unsigned long m_ulLastPing;
public:

#ifdef _MSC_VER
void IZIZTODO_testMap();
#endif

void Init();
void SendNextCommand();
void clearQueue(){ m_sendQueue.clear(); }
Expand All @@ -198,7 +251,7 @@ class PowerMaxAlarm
void DumpToJson(IOutput* outputStream);

private:
static void addPin(unsigned char* bufferToSend, int pos = 4);
void addPin(unsigned char* bufferToSend, int pos = 4, bool useMasterCode = false);

bool isFlagSet(unsigned char id) const { return (flags & 1<<id) != 0; }
bool isAlarmEvent() const{ return isFlagSet(7); }
Expand Down Expand Up @@ -264,7 +317,6 @@ int os_serialPortWrite(const void* dataToWrite, int bytesToWrite);
bool os_serialPortClose();
void os_usleep(int microseconds);

int os_cfg_getUserCode();
int os_cfg_getZoneCnt();
const char* os_cfg_getZoneName(int idx);
int os_cfg_getPacketTimeout();
Expand Down
87 changes: 52 additions & 35 deletions PowerMaxEsp8266/PowerMaxEsp8266.ino
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ IPAddress PM_LAN_BROADCAST_IP(224, 192, 32, 12);
const char * const cfg_zones[] = { "system", "front door", "hall", "living room", "kitchen",
"study", "upstairs", "conservatory", "garage", "back door", "garage2"};

//Specify Pin for your PowerMax alarm
//If your pin is 1234, you need to return 0x1234 (this is strange, as 0x makes it hex, but the only way it works)
#define ALARM_USER_PIN 0x1234; //IZIZTODO

//Specify your WIFI settings:
#define WIFI_SSID "IreksNetUnit8"
#define WIFI_PASS "??"
Expand Down Expand Up @@ -85,7 +81,7 @@ void handleRoot() {
val -= minutes*60;

char szTmp[PRINTF_BUF];
sprintf(szTmp, "hello from esp8266: Uptime: %02d:%02d:%02d.%02d", (int)days, (int)hours, (int)minutes, (int)val);
sprintf(szTmp, "hello from esp8266: Uptime: %02d:%02d:%02d.%02d, free heap: %u", (int)days, (int)hours, (int)minutes, (int)val, ESP.getFreeHeap());
server.send(200, "text/plain", szTmp);
}

Expand Down Expand Up @@ -223,10 +219,27 @@ void runDirectRelayLoop()
while(telnetClient.connected())
{
bool wait = true;
if(Serial.available())

//we want to read/write in bulk as it's much faster than read one byte -> write one byte (this is known to create problems with PowerMax)
unsigned char buffer[256];
int readCnt = 0;
while(readCnt < 256)
{
telnetClient.write( Serial.read() );
wait = false;
if(Serial.available())
{
buffer[readCnt] = Serial.read();
readCnt++;
wait = false;
}
else
{
break;
}
}

if(readCnt > 0)
{
telnetClient.write_P( (char*)buffer, readCnt );
}

if(telnetClient.available())
Expand All @@ -237,7 +250,7 @@ void runDirectRelayLoop()

if(wait)
{
delay(100);
delay(10);
}
}
}
Expand Down Expand Up @@ -275,8 +288,8 @@ void handleTelnetRequests(PowerMaxAlarm* pm) {
pm->sendCommand(Pmax_RESTORE);
}
else if ( c == 'v' ) {
DEBUG(LOG_NOTICE,"getting versions string");
//IZIZTODO pm->sendCommand(Pmax_GETVERSION);
DEBUG(LOG_NOTICE,"Exit Download mode");
pm->sendCommand(Pmax_DL_EXIT);
}
else if ( c == 'r' ) {
DEBUG(LOG_NOTICE,"Request Status Update");
Expand All @@ -290,6 +303,10 @@ void handleTelnetRequests(PowerMaxAlarm* pm) {
DEBUG(LOG_NOTICE,"Exiting...");
telnetClient.stop();
}
else if( c == 'C' ) {
DEBUG(LOG_NOTICE,"Reseting...");
ESP.reset();
}
else if ( c == 'p' ) {
telnetDbgLevel = LOG_DEBUG;
DEBUG(LOG_NOTICE,"Debug Logs enabled type 'P' (capital) to disable");
Expand All @@ -298,10 +315,14 @@ void handleTelnetRequests(PowerMaxAlarm* pm) {
telnetDbgLevel = LOG_NO_FILTER;
DEBUG(LOG_NO_FILTER,"Debug Logs disabled");
}
else if ( c == 'H' ) {
DEBUG(LOG_NO_FILTER,"Free Heap: %u", ESP.getFreeHeap());
}
else if ( c == '?' )
{
DEBUG(LOG_NO_FILTER,"Allowed commands:");
DEBUG(LOG_NO_FILTER,"\t c - exit");
DEBUG(LOG_NO_FILTER,"\t C - reset device");
DEBUG(LOG_NO_FILTER,"\t p - output debug messages");
DEBUG(LOG_NO_FILTER,"\t P - stop outputing debug messages");
#ifdef PM_ALLOW_CONTROL
Expand All @@ -311,10 +332,13 @@ void handleTelnetRequests(PowerMaxAlarm* pm) {
DEBUG(LOG_NO_FILTER,"\t D - Direct mode (relay all bytes from client to PMC and back with no processing, close connection to exit");
#endif
DEBUG(LOG_NO_FILTER,"\t g - Get Event Log");
DEBUG(LOG_NO_FILTER,"\t t - Re-Enroll");
DEBUG(LOG_NO_FILTER,"\t v - Get Version String");
DEBUG(LOG_NO_FILTER,"\t t - Restore Comms");
DEBUG(LOG_NO_FILTER,"\t v - Exit download mode");
DEBUG(LOG_NO_FILTER,"\t r - Request Status Update");
DEBUG(LOG_NO_FILTER,"\t j - Dump Application Status to JSON");
DEBUG(LOG_NO_FILTER,"\t H - Get free heap");


}
}
}
Expand Down Expand Up @@ -417,23 +441,16 @@ void loop(void){

server.handleClient();

if(serialHandler(&pm) == false)
static unsigned long lastMsg = 0;
if(serialHandler(&pm) == true)
{
if(pm.getEnrolledZoneCnt() == 0)
{
//pm.Init() should enroll, but sometimes this fails, this is another attempt to do it if Init() fails. delay is added not to do it too frequently in case of problems
delay(1000);
DEBUG(LOG_WARNING,"No enroll information, trying to re-enroll");
pm.sendCommand(Pmax_RESTORE);
}
lastMsg = millis();
}
else if(pm.getSecondsFromLastComm() > 120)

if(millis() - lastMsg > 300 || millis() < lastMsg)
{
//this should not happen (no comms), to re-establish we re-enroll
delay(1000);
DEBUG(LOG_WARNING,"Communication failure - trying to re-enroll");
pm.sendCommand(Pmax_RESTORE);
}
pm.SendNextCommand();
}

#ifdef PM_ENABLE_TELNET_ACCESS
handleNewTelnetClients();
Expand Down Expand Up @@ -508,13 +525,18 @@ int os_serialPortRead(void* readBuff, int bytesToRead)
int dwTotalRead = 0;
while(bytesToRead > 0)
{
if(Serial.available() == false)
for(int ix=0; ix<10; ix++)
{
delay(50);
if(Serial.available() == false)
if(Serial.available())
{
break;
}
delay(5);
}

if(Serial.available() == false)
{
break;
}

*((char*)readBuff) = Serial.read();
Expand Down Expand Up @@ -546,11 +568,6 @@ void os_strncat_s(char* dst, int dst_size, const char* src)
strncat(dst, src, dst_size);
}

int os_cfg_getUserCode()
{
return ALARM_USER_PIN;
}

int os_cfg_getZoneCnt()
{
return sizeof(cfg_zones)/sizeof(cfg_zones[0]);
Expand Down
53 changes: 43 additions & 10 deletions PowerMaxWin/PowerMax.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,12 @@ void KeyPressHandling(PowerMaxAlarm* pm) {
pm->sendCommand(Pmax_GETEVENTLOG);
}
else if ( c == 't' ) {
DEBUG(LOG_NOTICE,"try re-enroll");
DEBUG(LOG_NOTICE,"Restore Comms");
pm->sendCommand(Pmax_RESTORE);
}
else if ( c == 'v' ) {
DEBUG(LOG_NOTICE,"getting versions string");
pm->sendCommand(Pmax_DL_START);
//pm->sendCommand(Pmax_GETVERSION); //IZIZTODO
}
else if ( c == 'V' ) {
DEBUG(LOG_NOTICE,"Exit Download mode");
pm->sendCommand(Pmax_DL_EXIT);
//pm->sendCommand(Pmax_GETVERSION); //IZIZTODO
}
else if ( c == 'r' ) {
DEBUG(LOG_NOTICE,"Request Status Update");
Expand All @@ -110,16 +105,54 @@ void KeyPressHandling(PowerMaxAlarm* pm) {
DEBUG(LOG_NO_FILTER,"\t d - Disarm");
DEBUG(LOG_NO_FILTER,"\t a - Arm Away");
DEBUG(LOG_NO_FILTER,"\t g - Get Event Log");
DEBUG(LOG_NO_FILTER,"\t t - Re-Enroll");
DEBUG(LOG_NO_FILTER,"\t v - Get Version String");
DEBUG(LOG_NO_FILTER,"\t t - Restore comms");
DEBUG(LOG_NO_FILTER,"\t v - Exit download mode");
DEBUG(LOG_NO_FILTER,"\t r - Request Status Update");
DEBUG(LOG_NO_FILTER,"\t j - Dump Application Status to JSON");
}
}
}

void saveMapToFile(const char* name, MemoryMap* map)
{
HANDLE hDump = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
for(int ix=0; ix<MAX_PAGES_CNT; ix++)
{
unsigned char page[MAX_PAGE_SIZE] = {0};
if(map->Exist(ix))
{

map->Read(ix,0,MAX_PAGE_SIZE, page);
}

DWORD dw;
WriteFile(hDump, page, MAX_PAGE_SIZE,&dw, NULL);
}
CloseHandle(hDump);
}

void loadMapToFile(const char* name, MemoryMap* map)
{
HANDLE hDump = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
for(int ix=0; ix<MAX_PAGES_CNT; ix++)
{
DWORD dw;
unsigned char page[MAX_PAGE_SIZE] = {0};
ReadFile(hDump, page, MAX_PAGE_SIZE, &dw, NULL);
map->Write(ix,0,MAX_PAGE_SIZE, page);
}
CloseHandle(hDump);
}


int _tmain(int argc, _TCHAR* argv[])
{
/*{
PowerMaxAlarm pm;
pm.IZIZTODO_testMap();
}
return 0;*/

if(os_serialPortInit("COM3") == false)
{
return 1;
Expand All @@ -140,7 +173,7 @@ int _tmain(int argc, _TCHAR* argv[])
dwLastMsg = GetTickCount();
}

if(GetTickCount() - dwLastMsg > 1000)
if(GetTickCount() - dwLastMsg > 300)
{
pm.SendNextCommand();
}
Expand Down
5 changes: 0 additions & 5 deletions PowerMaxWin/pmax_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,6 @@ void os_strncat_s(char* dst, int dst_size, const char* src)
}

////////////////////////
int os_cfg_getUserCode()
{
return 1234; //if your pin is 1234, you need to return 0x1234 (this is strange, as 0x makes it hex, but the only way it works)
}

const char * const cfg_zones[] = {"zone1", "zone2", "zone3", "zone4", "zone5",
"zone6", "zone7", "zone8", "zone9", "zone10",
"zone11","zone12","zone13","zone14", "zone15"};
Expand Down
Loading

0 comments on commit 7ce33e4

Please sign in to comment.