diff --git a/.gitignore b/.gitignore index b8b7ed8..5abeef8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,3 @@ build/ prebuilds/ node_modules/ -test/ diff --git a/.npmignore b/.npmignore index deeb660..e65cd5c 100644 --- a/.npmignore +++ b/.npmignore @@ -1,5 +1,4 @@ test/ -.travis.yml -appveyor.yml +.github/ .npmignore .gitignore diff --git a/binding.gyp b/binding.gyp index 0573666..6c363c1 100644 --- a/binding.gyp +++ b/binding.gyp @@ -2,7 +2,6 @@ "targets": [{ "target_name": "node_snap7", "include_dirs": [ - " */ -var events = require('events'); +const EventEmitter = require('events').EventEmitter; +const inherits = require('util').inherits; module.exports = snap7 = require('../binding'); +inherits(snap7.S7Server, EventEmitter); + snap7.S7Client.prototype.DBRead = async function (dbNumber, start, size) { return this.ReadArea(this.S7AreaDB, dbNumber, start, size, this.S7WLByte); } @@ -54,6 +57,3 @@ snap7.S7Client.prototype.CTRead = async function (start, size) { snap7.S7Client.prototype.CTWrite = async function (start, size, buf) { return this.WriteArea(this.S7AreaCT, 0, start, size, this.S7WLCounter, buf); } - -snap7.S7Server.super_ = events.EventEmitter; -Object.setPrototypeOf(snap7.S7Server.prototype, events.EventEmitter.prototype); diff --git a/src/node_snap7_client.cpp b/src/node_snap7_client.cpp index 099ab92..2a8c391 100644 --- a/src/node_snap7_client.cpp +++ b/src/node_snap7_client.cpp @@ -243,10 +243,12 @@ Napi::Value S7Client::ConnectTo(const Napi::CallbackInfo &info) { if (info.Length() < 3) { Napi::TypeError::New(env, "Wrong number of arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } if (!info[0].IsString() || !info[1].IsNumber() || !info[2].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } std::string* remAddress = new std::string(info[0].As().Utf8Value()); @@ -263,6 +265,7 @@ Napi::Value S7Client::SetConnectionParams(const Napi::CallbackInfo &info) { if (!info[0].IsString() || !info[1].IsNumber() || !info[2].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } std::string remAddress = info[0].As().Utf8Value(); @@ -282,6 +285,7 @@ Napi::Value S7Client::SetConnectionType(const Napi::CallbackInfo &info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } word type = info[0].As().Uint32Value();; @@ -302,6 +306,7 @@ Napi::Value S7Client::GetParam(const Napi::CallbackInfo &info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int pData; @@ -322,6 +327,7 @@ Napi::Value S7Client::SetParam(const Napi::CallbackInfo &info) { if (!(info[0].IsNumber() || info[1].IsNumber())) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int pData = info[1].As().Int32Value(); @@ -674,13 +680,17 @@ void IOWorker::OnOK() { Napi::Value S7Client::ReadArea(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); - if (info.Length() < 5) + if (info.Length() < 5) { Napi::TypeError::New(env, "Wrong number of Arguments").ThrowAsJavaScriptException(); + return env.Undefined(); + } if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber() || - !info[4].IsNumber()) + !info[4].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); + } int amount = info[3].As().Int32Value(); int byteCount = GetByteCountFromWordLen(info[4].As().Int32Value()); @@ -701,13 +711,17 @@ Napi::Value S7Client::ReadArea(const Napi::CallbackInfo &info) { Napi::Value S7Client::WriteArea(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); - if (info.Length() < 6) + if (info.Length() < 6) { Napi::TypeError::New(env, "Wrong number of Arguments").ThrowAsJavaScriptException(); + return env.Undefined(); + } if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber() || - !info[4].IsNumber() || !info[5].IsBuffer()) + !info[4].IsNumber() || !info[5].IsBuffer()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); + } IOWorker* worker = new IOWorker(env, this, DataIOFunction::WRITEAREA , info[5].As>().Data() @@ -726,26 +740,31 @@ Napi::Value S7Client::ReadMultiVars(const Napi::CallbackInfo &info) { if (info.Length() < 1) { Napi::TypeError::New(env, "Wrong number of arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } if (!info[0].IsArray()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } const Napi::Array data_arr = info[0].As(); uint32_t len = data_arr.Length(); if (len == 0) { Napi::TypeError::New(env, "Array needs at least 1 item").ThrowAsJavaScriptException(); + return env.Undefined(); } else if (len > MaxVars) { std::stringstream err; err << "Array exceeds max variables (" << MaxVars << ") that can be transferred with ReadMultiVars()"; Napi::TypeError::New(env, err.str()).ThrowAsJavaScriptException(); + return env.Undefined(); } for (uint32_t i = 0; i < len; i++) { if (!data_arr[i].IsObject()) { Napi::TypeError::New(env, "Wrong argument structure").ThrowAsJavaScriptException(); + return env.Undefined(); } else { Napi::Object data_obj = data_arr[i].As(); if (!data_obj.Has("Area") || @@ -753,14 +772,17 @@ Napi::Value S7Client::ReadMultiVars(const Napi::CallbackInfo &info) { !data_obj.Has("Start") || !data_obj.Has("Amount")) { Napi::TypeError::New(env, "Wrong argument structure").ThrowAsJavaScriptException(); + return env.Undefined(); } else if (!data_obj.Get("Area").IsNumber() || !data_obj.Get("WordLen").IsNumber() || !data_obj.Get("Start").IsNumber() || !data_obj.Get("Amount").IsNumber()) { Napi::TypeError::New(env, "Wrong argument structure").ThrowAsJavaScriptException(); + return env.Undefined(); } else if (data_obj.Get("Area").As().Int32Value() == S7AreaDB) { if (!data_obj.Has("DBNumber")) { Napi::TypeError::New(env, "Wrong argument structure").ThrowAsJavaScriptException(); + return env.Undefined(); } } else { data_obj.Set("DBNumber", Napi::Number::New(env, 0)); @@ -834,26 +856,31 @@ Napi::Value S7Client::WriteMultiVars(const Napi::CallbackInfo &info) { if (info.Length() < 1) { Napi::TypeError::New(env, "Wrong number of arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } if (!info[0].IsArray()) { Napi::TypeError::New(info.Env(), "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } const Napi::Array data_arr = info[0].As(); uint32_t len = data_arr.Length(); if (len == 0) { Napi::TypeError::New(env, "Array needs at least 1 item").ThrowAsJavaScriptException(); + return env.Undefined(); } else if (len > MaxVars) { std::stringstream err; err << "Array exceeds max variables (" << MaxVars << ") that can be transferred with WriteMultiVars()"; Napi::TypeError::New(env, err.str()).ThrowAsJavaScriptException(); + return env.Undefined(); } for (uint32_t i = 0; i < len; i++) { if (!data_arr[i].IsObject()) { Napi::TypeError::New(env, "Wrong argument structure").ThrowAsJavaScriptException(); + return env.Undefined(); } else { Napi::Object data_obj = data_arr[i].As(); if (!data_obj.Has("Area") || @@ -862,15 +889,18 @@ Napi::Value S7Client::WriteMultiVars(const Napi::CallbackInfo &info) { !data_obj.Has("Amount") || !data_obj.Has("Data")) { Napi::TypeError::New(env, "Wrong argument structure").ThrowAsJavaScriptException(); + return env.Undefined(); } else if (!data_obj.Get("Area").IsNumber() || !data_obj.Get("WordLen").IsNumber() || !data_obj.Get("Start").IsNumber() || !data_obj.Get("Amount").IsNumber() || !data_obj.Get("Data").IsBuffer()) { Napi::TypeError::New(env, "Wrong argument structure").ThrowAsJavaScriptException(); + return env.Undefined(); } else if (data_obj.Get("Area").As().Int32Value() == S7AreaDB) { if (!data_obj.Has("DBNumber")) { Napi::TypeError::New(env, "Wrong argument structure").ThrowAsJavaScriptException(); + return env.Undefined(); } } else { data_obj.Set("DBNumber", Napi::Number::New(env, 0)); @@ -933,6 +963,7 @@ Napi::Value S7Client::GetAgBlockInfo(const Napi::CallbackInfo &info) { if (!info[0].IsNumber() || !info[1].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } PS7BlockInfo BlockInfo = new TS7BlockInfo; @@ -948,6 +979,7 @@ Napi::Value S7Client::GetPgBlockInfo(const Napi::CallbackInfo &info) { if (!info[0].IsBuffer()) { Napi::TypeError::New(env, "Argument should be a Buffer").ThrowAsJavaScriptException(); + return env.Undefined(); } PS7BlockInfo BlockInfo = new TS7BlockInfo; @@ -994,6 +1026,7 @@ Napi::Value S7Client::ListBlocksOfType(const Napi::CallbackInfo &info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int BlockNum = sizeof(TS7BlocksOfType) / sizeof(PS7BlocksOfType); @@ -1025,6 +1058,7 @@ Napi::Value S7Client::Upload(const Napi::CallbackInfo &info) { if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int size = info[2].As().Int32Value(); @@ -1042,6 +1076,7 @@ Napi::Value S7Client::FullUpload(const Napi::CallbackInfo &info) { if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int size = info[2].As().Int32Value(); @@ -1059,6 +1094,7 @@ Napi::Value S7Client::Download(const Napi::CallbackInfo &info) { if (!info[0].IsNumber() || info[1].IsBuffer()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } Napi::Buffer buffer = info[1].As>(); @@ -1076,6 +1112,7 @@ Napi::Value S7Client::Delete(const Napi::CallbackInfo &info) { if (!info[0].IsNumber() || !info[1].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } IOWorker* worker = new IOWorker(env, this, DataIOFunction::DELETEBLOCK @@ -1091,6 +1128,7 @@ Napi::Value S7Client::DBGet(const Napi::CallbackInfo &info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int size = 65536; @@ -1107,6 +1145,7 @@ Napi::Value S7Client::DBFill(const Napi::CallbackInfo &info) { if (!info[0].IsNumber() || !(info[1].IsNumber() || info[1].IsString())) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int fill; @@ -1141,6 +1180,7 @@ Napi::Value S7Client::SetPlcDateTime(const Napi::CallbackInfo &info) { if (!(info[0].IsObject() || info[0].IsDate())) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } tm *DateTime = new tm; @@ -1249,6 +1289,7 @@ Napi::Value S7Client::ReadSZL(const Napi::CallbackInfo &info) { if (!(info[0].IsNumber() || info[1].IsNumber())) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } PS7SZL SZL = new TS7SZL; @@ -1317,6 +1358,7 @@ Napi::Value S7Client::CopyRamToRom(const Napi::CallbackInfo &info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } IOWorker* worker = new IOWorker(env, this, DataIOFunction::COPYRAMTOROM @@ -1331,6 +1373,7 @@ Napi::Value S7Client::Compress(const Napi::CallbackInfo &info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } IOWorker* worker = new IOWorker(env, this, DataIOFunction::COMPRESS @@ -1372,6 +1415,7 @@ Napi::Value S7Client::SetSessionPassword(const Napi::CallbackInfo &info) { if (!info[0].IsString()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } std::string *password = new std::string(info[0].As().Utf8Value()); @@ -1453,6 +1497,7 @@ Napi::Value S7Client::ErrorText(const Napi::CallbackInfo &info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } return Napi::String::New(env, diff --git a/src/node_snap7_server.cpp b/src/node_snap7_server.cpp index ef43ae6..fa8bde0 100644 --- a/src/node_snap7_server.cpp +++ b/src/node_snap7_server.cpp @@ -7,27 +7,6 @@ namespace node_snap7 { -static std::mutex mutex_rw; -static std::mutex mutex_event; - -static struct rw_event_baton_t { - int Sender; - int Operation; - TS7Tag Tag; - void *pUsrData; -} rw_event_baton_g; - -void S7API EventCallBack(void *usrPtr, PSrvEvent PEvent, int Size) { - -} - -int S7API RWAreaCallBack(void *usrPtr, int Sender, int Operation, PS7Tag PTag - , void *pUsrData -) { - - return 0; -} - Napi::Object S7Server::Init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); @@ -274,14 +253,142 @@ Napi::Object S7Server::Init(Napi::Env env, Napi::Object exports) { return exports; } +void S7Server::EventCallBack(void *usrPtr, PSrvEvent PEvent, int Size){ + TSFN* tsfn = static_cast(usrPtr); + tsfn->Acquire(); + tsfn->BlockingCall(PEvent); + tsfn->Release(); +} + +int S7Server::RWAreaCallBack(void *usrPtr, int Sender, int Operation, PS7Tag PTag + , void *pUsrData +){ + TSFNRW* tsfnrw = static_cast(usrPtr); + PRWEvent RWEvent = new TRWEvent(); + RWEvent->Sender = Sender; + RWEvent->Operation = Operation; + RWEvent->PTag = PTag; + RWEvent->pUsrData = pUsrData; + + tsfnrw->Acquire(); + tsfnrw->BlockingCall(RWEvent); + mutex_rw.lock(); + tsfnrw->Release(); + + return 0; +} + +Napi::Value S7Server::RWBufferCallback(const Napi::CallbackInfo& info) { + +} + +void CallJsEvent(Napi::Env env, + Napi::Function callback, + Context* context, + DataTypeEvent* data) { + if (env != nullptr) { + if (callback != nullptr) { + in_addr sin; + sin.s_addr = data->EvtSender; + double time = static_cast(data->EvtTime * 1000); + + Napi::Object event_obj = Napi::Object::New(env); + event_obj.Set("EvtTime", Napi::Date::New(env, time)); + event_obj.Set("EvtSender", Napi::String::New(env, inet_ntoa(sin))); + event_obj.Set("EvtCode", Napi::Number::New(env, data->EvtCode)); + event_obj.Set("EvtRetCode", Napi::Number::New(env, data->EvtRetCode)); + event_obj.Set("EvtParam1", Napi::Number::New(env, data->EvtParam1)); + event_obj.Set("EvtParam2", Napi::Number::New(env, data->EvtParam2)); + event_obj.Set("EvtParam3", Napi::Number::New(env, data->EvtParam3)); + event_obj.Set("EvtParam4", Napi::Number::New(env, data->EvtParam4)); + callback.Call(context->Value(), {Napi::String::New(env, "event"), event_obj}); + } + } +} + +void CallJsRW(Napi::Env env, Napi::Function callback, Context* context, DataTypeRW* data) { + if (env != nullptr) { + if (callback != nullptr) { + in_addr sin; + sin.s_addr = data->Sender; + + Napi::Object rw_tag_obj = Napi::Object::New(env); + rw_tag_obj.Set("Area", Napi::Number::New(env, data->PTag->Area)); + rw_tag_obj.Set("DBNumber", Napi::Number::New(env, data->PTag->DBNumber)); + rw_tag_obj.Set("Start", Napi::Number::New(env, data->PTag->Start)); + rw_tag_obj.Set("Size", Napi::Number::New(env, data->PTag->Size)); + rw_tag_obj.Set("WordLen", Napi::Number::New(env, data->PTag->WordLen)); + + int byteCount, size; + byteCount = S7Server::GetByteCountFromWordLen(data->PTag->WordLen); + size = byteCount * data->PTag->Size; + + Napi::Buffer buffer; + if (data->Operation == OperationWrite) { + buffer = Napi::Buffer::NewOrCopy(env, static_cast(data->pUsrData), size); + + } else { + buffer = Napi::Buffer::New(env, size); + } + + callback.Call(context->Value(), { + Napi::String::New(env, "readWrite"), + Napi::String::New(env, inet_ntoa(sin)), + Napi::Number::New(env, data->Operation), + rw_tag_obj, + buffer, + //Napi::Function::New(env, RWBufferCallback) + }); + } + } +} + S7Server::S7Server(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + lastError = 0; snap7Server = new TS7Server(); - snap7Server->SetEventsCallback(&EventCallBack, NULL); + Napi::Function Emit = info.This().As().Get("emit").As(); + Napi::Reference* context = new Napi::Reference(Napi::Persistent(info.This())); + + tsfn = TSFN::New( + env, // Environment + Emit, // JS function from caller + "TsfnEvent", // Resource name + 0, // Max queue size (0 = unlimited). + 1, // Initial thread count + context, + [](Napi::Env, + void* finalizeData, + Napi::Reference* ctx) { + delete ctx; + } + ); + + tsfnrw = TSFNRW::New( + env, // Environment + Emit, // JS function from caller + "TsfnEventRW", // Resource name + 0, // Max queue size (0 = unlimited). + 1, // Initial thread count + context, + [](Napi::Env, + void* finalizeData, + Napi::Reference* ctx) { + delete ctx; + } + ); + + tsfn.Unref(env); + tsfnrw.Unref(env); + + snap7Server->SetEventsCallback(&EventCallBack, &tsfn); } S7Server::~S7Server() { + tsfn.Abort(); + tsfnrw.Abort(); snap7Server->Stop(); delete snap7Server; } @@ -356,10 +463,12 @@ Napi::Value S7Server::StartTo(const Napi::CallbackInfo& info) { if (info.Length() < 1) { Napi::TypeError::New(env, "Wrong number of arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } if (!info[0].IsString()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } std::string* address = new std::string(info[0].As().Utf8Value()); @@ -384,13 +493,14 @@ Napi::Value S7Server::SetResourceless(const Napi::CallbackInfo& info) { if (!info[0].IsBoolean()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } bool resourceless = info[0].ToBoolean().Value(); int ret; if (resourceless) { - ret = snap7Server->SetRWAreaCallback(&RWAreaCallBack, NULL); + ret = snap7Server->SetRWAreaCallback(&RWAreaCallBack, tsfnrw); } else { ret = snap7Server->SetRWAreaCallback(NULL, NULL); } @@ -404,6 +514,7 @@ Napi::Value S7Server::GetParam(const Napi::CallbackInfo& info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int pData; @@ -419,6 +530,7 @@ Napi::Value S7Server::SetParam(const Napi::CallbackInfo& info) { if (!(info[0].IsNumber() || info[1].IsNumber())) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int pData = info[1].ToNumber().Int32Value(); @@ -441,6 +553,7 @@ Napi::Value S7Server::SetEventsMask(const Napi::CallbackInfo& info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } snap7Server->SetEventsMask(info[0].ToNumber().Uint32Value()); @@ -453,16 +566,18 @@ Napi::Value S7Server::RegisterArea(const Napi::CallbackInfo& info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int index; - char *pBuffer; size_t len; + char *pBuffer; int area = info[0].ToNumber().Int32Value(); if (area == srvAreaDB) { if (!info[1].IsNumber() || !info[2].IsBuffer()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } index = info[1].ToNumber().Int32Value(); @@ -470,6 +585,7 @@ Napi::Value S7Server::RegisterArea(const Napi::CallbackInfo& info) { pBuffer = info[2].As>().Data(); } else if (!info[1].IsBuffer()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } else { index = 0; len = info[1].As>().Length(); @@ -478,6 +594,7 @@ Napi::Value S7Server::RegisterArea(const Napi::CallbackInfo& info) { if (len > 0xFFFF) { Napi::RangeError::New(env, "Max area buffer size is 65535").ThrowAsJavaScriptException(); + return env.Undefined(); } word size = static_cast(len); @@ -502,6 +619,7 @@ Napi::Value S7Server::UnregisterArea(const Napi::CallbackInfo& info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int index = 0; @@ -510,6 +628,7 @@ Napi::Value S7Server::UnregisterArea(const Napi::CallbackInfo& info) { if (area == srvAreaDB) { if (!info[1].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } index = info[1].ToNumber().Int32Value(); @@ -531,11 +650,13 @@ Napi::Value S7Server::SetArea(const Napi::CallbackInfo& info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int area = info[0].ToNumber().Int32Value(); if (!area2buffer.count(area)) { Napi::Error::New(env, "Unknown area").ThrowAsJavaScriptException(); + return env.Undefined(); } int index; @@ -545,11 +666,13 @@ Napi::Value S7Server::SetArea(const Napi::CallbackInfo& info) { if (area == srvAreaDB) { if (!info[1].IsNumber() || !info[2].IsBuffer()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } index = info[1].ToNumber().Int32Value(); if (!area2buffer[area].count(index)) { Napi::Error::New(env, "DB index not found").ThrowAsJavaScriptException(); + return env.Undefined(); } len =info[2].As>().Length();; @@ -564,11 +687,13 @@ Napi::Value S7Server::SetArea(const Napi::CallbackInfo& info) { pBuffer = info[2].As>().Data(); } else { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } } if (len != area2buffer[area][index].size) { Napi::Error::New(env, "Wrong buffer length").ThrowAsJavaScriptException(); + return env.Undefined(); } snap7Server->LockArea(area, index); @@ -587,6 +712,7 @@ Napi::Value S7Server::GetArea(const Napi::CallbackInfo& info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int index = 0; @@ -594,16 +720,19 @@ Napi::Value S7Server::GetArea(const Napi::CallbackInfo& info) { if (!area2buffer.count(area)) { Napi::Error::New(env, "Unknown area").ThrowAsJavaScriptException(); + return env.Undefined(); } if (area == srvAreaDB) { if (!info[1].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } index = info[1].ToNumber().Int32Value(); if (!area2buffer[area].count(index)) { Napi::Error::New(env, "DB index not found").ThrowAsJavaScriptException(); + return env.Undefined(); } } @@ -623,6 +752,7 @@ Napi::Value S7Server::LockArea(const Napi::CallbackInfo& info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int index = 0; @@ -631,6 +761,7 @@ Napi::Value S7Server::LockArea(const Napi::CallbackInfo& info) { if (area == srvAreaDB) { if (!info[1].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } index = info[1].ToNumber().Int32Value(); @@ -647,6 +778,7 @@ Napi::Value S7Server::UnlockArea(const Napi::CallbackInfo& info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int index = 0; @@ -655,6 +787,7 @@ Napi::Value S7Server::UnlockArea(const Napi::CallbackInfo& info) { if (area == srvAreaDB) { if (!info[1].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } index = info[1].ToNumber().Int32Value(); @@ -706,6 +839,7 @@ Napi::Value S7Server::SetCpuStatus(const Napi::CallbackInfo& info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } int ret = snap7Server->SetCpuStatus(info[0].ToNumber().Int32Value()); @@ -719,6 +853,7 @@ Napi::Value S7Server::ErrorText(const Napi::CallbackInfo& info) { if (!info[0].IsNumber()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } return Napi::String::New(env, @@ -731,6 +866,7 @@ Napi::Value S7Server::EventText(const Napi::CallbackInfo& info) { if (!info[0].IsObject()) { Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Undefined(); } Napi::Object event_obj = info[0].ToObject(); @@ -739,6 +875,7 @@ Napi::Value S7Server::EventText(const Napi::CallbackInfo& info) { !event_obj.Has("EvtParam1") || !event_obj.Has("EvtParam2") || !event_obj.Has("EvtParam3") || !event_obj.Has("EvtParam4")) { Napi::TypeError::New(env, "Wrong argument structure").ThrowAsJavaScriptException(); + return env.Undefined(); } if (!event_obj.Get("EvtTime").IsDate() || @@ -750,6 +887,7 @@ Napi::Value S7Server::EventText(const Napi::CallbackInfo& info) { !event_obj.Get("EvtParam3").IsNumber() || !event_obj.Get("EvtParam4").IsNumber()) { Napi::TypeError::New(env, "Wrong argument types").ThrowAsJavaScriptException(); + return env.Undefined(); } Napi::String remAddress = event_obj.Get("EvtSender").ToString(); diff --git a/src/node_snap7_server.h b/src/node_snap7_server.h index c6980c7..1742bed 100644 --- a/src/node_snap7_server.h +++ b/src/node_snap7_server.h @@ -23,6 +23,23 @@ typedef struct { word size; }TBufferInfo; +typedef struct{ + int Sender; + int Operation; + PS7Tag PTag; + void *pUsrData; +}TRWEvent, *PRWEvent; + +using Context = Napi::Reference; +using DataTypeEvent = TSrvEvent; +using DataTypeRW = TRWEvent; +void CallJsEvent(Napi::Env env, Napi::Function callback, Context* context, DataTypeEvent* data); +void CallJsRW(Napi::Env env, Napi::Function callback, Context* context, DataTypeRW* data); +using TSFN = Napi::TypedThreadSafeFunction; +using TSFNRW = Napi::TypedThreadSafeFunction; +using FinalizerDataType = void; +static std::mutex mutex_rw; + class S7Server : public Napi::ObjectWrap { public: static Napi::Object Init(Napi::Env env, Napi::Object exports); @@ -56,11 +73,16 @@ class S7Server : public Napi::ObjectWrap { std::mutex mutex; TS7Server *snap7Server; - std::map > area2buffer; + std::map> area2buffer; int lastError; private: - Napi::ThreadSafeFunction tsfn; + static void EventCallBack(void *usrPtr, PSrvEvent PEvent, int Size); + static int RWAreaCallBack(void *usrPtr, int Sender, int Operation, PS7Tag PTag + , void *pUsrData); + static Napi::Value RWBufferCallback(const Napi::CallbackInfo &info); + TSFN tsfn; + TSFNRW tsfnrw; }; class IOWorkerServer : public Napi::AsyncWorker {