PK BV/index.js(function (global, factory) { if (typeof define === "function" && define.amd) { define(["exports"], factory); } else if (typeof exports !== "undefined") { factory(exports); } else { var mod = { exports: {} }; factory(mod.exports); global.unknown = mod.exports; } })(this, function (_exports) { "use strict"; Object.defineProperty(_exports, "__esModule", { value: true }); _exports.default = void 0; !function (global) { "use strict"; var Op = Object.prototype; var hasOwn = Op.hasOwnProperty; var undefined; var $Symbol = typeof Symbol === "function" ? Symbol : {}; var iteratorSymbol = $Symbol.iterator || "@@iterator"; var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; var inModule = typeof module === "object"; var runtime = global.regeneratorRuntime; if (runtime) { if (inModule) { module.exports = runtime; } return; } runtime = global.regeneratorRuntime = inModule ? module.exports || {} : {}; function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; var generator = Object.create(protoGenerator.prototype); var context = new Context(tryLocsList || []); generator._invoke = makeInvokeMethod(innerFn, self, context); return generator; } runtime.wrap = wrap; function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } var GenStateSuspendedStart = "suspendedStart"; var GenStateSuspendedYield = "suspendedYield"; var GenStateExecuting = "executing"; var GenStateCompleted = "completed"; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; IteratorPrototype[iteratorSymbol] = function () { return this; }; var getProto = Object.getPrototypeOf; var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { IteratorPrototype = NativeIteratorPrototype; } var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; GeneratorFunctionPrototype.constructor = GeneratorFunction; GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction"; function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { prototype[method] = function (arg) { return this._invoke(method, arg); }; }); } runtime.isGeneratorFunction = function (genFun) { var ctor = typeof genFun === "function" && genFun.constructor; return ctor ? ctor === GeneratorFunction || (ctor.displayName || ctor.name) === "GeneratorFunction" : false; }; runtime.mark = function (genFun) { if (Object.setPrototypeOf) { Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); } else { genFun.__proto__ = GeneratorFunctionPrototype; if (!(toStringTagSymbol in genFun)) { genFun[toStringTagSymbol] = "GeneratorFunction"; } } genFun.prototype = Object.create(Gp); return genFun; }; runtime.awrap = function (arg) { return { __await: arg }; }; function AsyncIterator(generator) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if (record.type === "throw") { reject(record.arg); } else { var result = record.arg; var value = result.value; if (value && typeof value === "object" && hasOwn.call(value, "__await")) { return Promise.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }); } return Promise.resolve(value).then(function (unwrapped) { result.value = unwrapped; resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } } var previousPromise; function enqueue(method, arg) { function callInvokeWithMethodAndArg() { return new Promise(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } this._invoke = enqueue; } defineIteratorMethods(AsyncIterator.prototype); AsyncIterator.prototype[asyncIteratorSymbol] = function () { return this; }; runtime.AsyncIterator = AsyncIterator; runtime.async = function (innerFn, outerFn, self, tryLocsList) { var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList)); return runtime.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }; function makeInvokeMethod(innerFn, self, context) { var state = GenStateSuspendedStart; return function invoke(method, arg) { if (state === GenStateExecuting) { throw new Error("Generator is already running"); } if (state === GenStateCompleted) { if (method === "throw") { throw arg; } return doneResult(); } context.method = method; context.arg = arg; while (true) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if (context.method === "next") { context.sent = context._sent = context.arg; } else if (context.method === "throw") { if (state === GenStateSuspendedStart) { state = GenStateCompleted; throw context.arg; } context.dispatchException(context.arg); } else if (context.method === "return") { context.abrupt("return", context.arg); } state = GenStateExecuting; var record = tryCatch(innerFn, self, context); if (record.type === "normal") { state = context.done ? GenStateCompleted : GenStateSuspendedYield; if (record.arg === ContinueSentinel) { continue; } return { value: record.arg, done: context.done }; } else if (record.type === "throw") { state = GenStateCompleted; context.method = "throw"; context.arg = record.arg; } } }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (method === undefined) { context.delegate = null; if (context.method === "throw") { if (delegate.iterator.return) { context.method = "return"; context.arg = undefined; maybeInvokeDelegate(delegate, context); if (context.method === "throw") { return ContinueSentinel; } } context.method = "throw"; context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if (record.type === "throw") { context.method = "throw"; context.arg = record.arg; context.delegate = null; return ContinueSentinel; } var info = record.arg; if (!info) { context.method = "throw"; context.arg = new TypeError("iterator result is not an object"); context.delegate = null; return ContinueSentinel; } if (info.done) { context[delegate.resultName] = info.value; context.next = delegate.nextLoc; if (context.method !== "return") { context.method = "next"; context.arg = undefined; } } else { return info; } context.delegate = null; return ContinueSentinel; } defineIteratorMethods(Gp); Gp[toStringTagSymbol] = "Generator"; Gp[iteratorSymbol] = function () { return this; }; Gp.toString = function () { return "[object Generator]"; }; function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; if (1 in locs) { entry.catchLoc = locs[1]; } if (2 in locs) { entry.finallyLoc = locs[2]; entry.afterLoc = locs[3]; } this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal"; delete record.arg; entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }]; tryLocsList.forEach(pushTryEntry, this); this.reset(true); } runtime.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } keys.reverse(); return function next() { while (keys.length) { var key = keys.pop(); if (key in object) { next.value = key; next.done = false; return next; } } next.done = true; return next; }; }; function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) { return iteratorMethod.call(iterable); } if (typeof iterable.next === "function") { return iterable; } if (!isNaN(iterable.length)) { var i = -1, next = function next() { while (++i < iterable.length) { if (hasOwn.call(iterable, i)) { next.value = iterable[i]; next.done = false; return next; } } next.value = undefined; next.done = true; return next; }; return next.next = next; } } return { next: doneResult }; } runtime.values = values; function doneResult() { return { value: undefined, done: true }; } Context.prototype = { constructor: Context, reset: function (skipTempReset) { this.prev = 0; this.next = 0; this.sent = this._sent = undefined; this.done = false; this.delegate = null; this.method = "next"; this.arg = undefined; this.tryEntries.forEach(resetTryEntry); if (!skipTempReset) { for (var name in this) { if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) { this[name] = undefined; } } } }, stop: function () { this.done = true; var rootEntry = this.tryEntries[0]; var rootRecord = rootEntry.completion; if (rootRecord.type === "throw") { throw rootRecord.arg; } return this.rval; }, dispatchException: function (exception) { if (this.done) { throw exception; } var context = this; function handle(loc, caught) { record.type = "throw"; record.arg = exception; context.next = loc; if (caught) { context.method = "next"; context.arg = undefined; } return !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; var record = entry.completion; if (entry.tryLoc === "root") { return handle("end"); } if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"); var hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } else if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else if (hasCatch) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } } else if (hasFinally) { if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else { throw new Error("try statement without catch or finally"); } } } }, abrupt: function (type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { finallyEntry = null; } var record = finallyEntry ? finallyEntry.completion : {}; record.type = type; record.arg = arg; if (finallyEntry) { this.method = "next"; this.next = finallyEntry.finallyLoc; return ContinueSentinel; } return this.complete(record); }, complete: function (record, afterLoc) { if (record.type === "throw") { throw record.arg; } if (record.type === "break" || record.type === "continue") { this.next = record.arg; } else if (record.type === "return") { this.rval = this.arg = record.arg; this.method = "return"; this.next = "end"; } else if (record.type === "normal" && afterLoc) { this.next = afterLoc; } return ContinueSentinel; }, finish: function (finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) { this.complete(entry.completion, entry.afterLoc); resetTryEntry(entry); return ContinueSentinel; } } }, "catch": function (tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if (record.type === "throw") { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function (iterable, resultName, nextLoc) { this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }; if (this.method === "next") { this.arg = undefined; } return ContinueSentinel; } }; }(function () { return this || typeof self === "object" && self; }() || Function("return this")()); const disableBlocks = { debug: [], upload: [] }; const mustLoginBlocks = []; const triggerBlocksStatus = async (mode, app) => {}; class ExtImpl {} const extTranslationMap = { "zh": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "de": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "es": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "fr": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "id": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "ja": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "ja-jph": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "ko": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "pl": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "uk": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "zh-hant": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "nl": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "it": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "hr": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "ru": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "pt": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "fi": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "tr": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "tk": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" }, "en": { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" } }; const codeSnippets = { arduinoc: {} }; const extGenerators = [{ lang: 'arduinoc', template: `// generated by mBlock5 for // codes make you happy //( include //) #include //( lib //) //({ this.$ALL_VARIABLES.length==0?'':this.$ALL_VARIABLES.map(v=>"float "+v+" = 0;").join('\\n') }//) //( declare //) void _delay(float seconds) { long endTime = millis() + seconds * 1000; while(millis() < endTime) _loop(); } //( void setup() { //( setup //) //( code //) } //) void _loop() { //( _loop //) } void loop() { _loop(); }`, splitor: { frame: { left: "//(", right: "//)" }, expression: { left: "/*{", right: "}*/" } }, reducers: [{ name: 'include', reduce: codes => { let codes1 = []; for (let code of codes) { let codeStr = ''; if (typeof code === 'string') { codeStr = code; } else if (typeof code === 'function') { codeStr = code(); } if (codes1.indexOf(codeStr) === -1) { codes1.push(codeStr); } } if (codes1.length === 0) { return undefined; } return codes1.map(code => { return '#include ' + code; }).join('\n') + '\n'; } }] }]; const extSources = { arduino: [{ filename: "src/Dhcp.cpp", code: "// DHCP Library v0.3 - April 25, 2009\n// Author: Jordan Terrell - blog.jordanterrell.com\n\n#include \n#include \"Ethernet.h\"\n#include \"Dhcp.h\"\n#include \"w5100.h\"\n\nint DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)\n{\n\t_dhcpLeaseTime=0;\n\t_dhcpT1=0;\n\t_dhcpT2=0;\n\t_timeout = timeout;\n\t_responseTimeout = responseTimeout;\n\n\t// zero out _dhcpMacAddr\n\tmemset(_dhcpMacAddr, 0, 6);\n\treset_DHCP_lease();\n\n\tmemcpy((void*)_dhcpMacAddr, (void*)mac, 6);\n\t_dhcp_state = STATE_DHCP_START;\n\treturn request_DHCP_lease();\n}\n\nvoid DhcpClass::reset_DHCP_lease()\n{\n\t// zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp\n\tmemset(_dhcpLocalIp, 0, 20);\n}\n\n\t//return:0 on error, 1 if request is sent and response is received\nint DhcpClass::request_DHCP_lease()\n{\n\tuint8_t messageType = 0;\n\n\t// Pick an initial transaction ID\n\t_dhcpTransactionId = random(1UL, 2000UL);\n\t_dhcpInitialTransactionId = _dhcpTransactionId;\n\n\t_dhcpUdpSocket.stop();\n\tif (_dhcpUdpSocket.begin(DHCP_CLIENT_PORT) == 0) {\n\t\t// Couldn't get a socket\n\t\treturn 0;\n\t}\n\n\tpresend_DHCP();\n\n\tint result = 0;\n\n\tunsigned long startTime = millis();\n\n\twhile (_dhcp_state != STATE_DHCP_LEASED) {\n\t\tif (_dhcp_state == STATE_DHCP_START) {\n\t\t\t_dhcpTransactionId++;\n\t\t\tsend_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000));\n\t\t\t_dhcp_state = STATE_DHCP_DISCOVER;\n\t\t} else if (_dhcp_state == STATE_DHCP_REREQUEST) {\n\t\t\t_dhcpTransactionId++;\n\t\t\tsend_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000));\n\t\t\t_dhcp_state = STATE_DHCP_REQUEST;\n\t\t} else if (_dhcp_state == STATE_DHCP_DISCOVER) {\n\t\t\tuint32_t respId;\n\t\t\tmessageType = parseDHCPResponse(_responseTimeout, respId);\n\t\t\tif (messageType == DHCP_OFFER) {\n\t\t\t\t// We'll use the transaction ID that the offer came with,\n\t\t\t\t// rather than the one we were up to\n\t\t\t\t_dhcpTransactionId = respId;\n\t\t\t\tsend_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));\n\t\t\t\t_dhcp_state = STATE_DHCP_REQUEST;\n\t\t\t}\n\t\t} else if (_dhcp_state == STATE_DHCP_REQUEST) {\n\t\t\tuint32_t respId;\n\t\t\tmessageType = parseDHCPResponse(_responseTimeout, respId);\n\t\t\tif (messageType == DHCP_ACK) {\n\t\t\t\t_dhcp_state = STATE_DHCP_LEASED;\n\t\t\t\tresult = 1;\n\t\t\t\t//use default lease time if we didn't get it\n\t\t\t\tif (_dhcpLeaseTime == 0) {\n\t\t\t\t\t_dhcpLeaseTime = DEFAULT_LEASE;\n\t\t\t\t}\n\t\t\t\t// Calculate T1 & T2 if we didn't get it\n\t\t\t\tif (_dhcpT1 == 0) {\n\t\t\t\t\t// T1 should be 50% of _dhcpLeaseTime\n\t\t\t\t\t_dhcpT1 = _dhcpLeaseTime >> 1;\n\t\t\t\t}\n\t\t\t\tif (_dhcpT2 == 0) {\n\t\t\t\t\t// T2 should be 87.5% (7/8ths) of _dhcpLeaseTime\n\t\t\t\t\t_dhcpT2 = _dhcpLeaseTime - (_dhcpLeaseTime >> 3);\n\t\t\t\t}\n\t\t\t\t_renewInSec = _dhcpT1;\n\t\t\t\t_rebindInSec = _dhcpT2;\n\t\t\t} else if (messageType == DHCP_NAK) {\n\t\t\t\t_dhcp_state = STATE_DHCP_START;\n\t\t\t}\n\t\t}\n\n\t\tif (messageType == 255) {\n\t\t\tmessageType = 0;\n\t\t\t_dhcp_state = STATE_DHCP_START;\n\t\t}\n\n\t\tif (result != 1 && ((millis() - startTime) > _timeout))\n\t\t\tbreak;\n\t}\n\n\t// We're done with the socket now\n\t_dhcpUdpSocket.stop();\n\t_dhcpTransactionId++;\n\n\t_lastCheckLeaseMillis = millis();\n\treturn result;\n}\n\nvoid DhcpClass::presend_DHCP()\n{\n}\n\nvoid DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed)\n{\n\tuint8_t buffer[32];\n\tmemset(buffer, 0, 32);\n\tIPAddress dest_addr(255, 255, 255, 255); // Broadcast address\n\n\tif (_dhcpUdpSocket.beginPacket(dest_addr, DHCP_SERVER_PORT) == -1) {\n\t\t//Serial.printf(\"DHCP transmit error\\n\");\n\t\t// FIXME Need to return errors\n\t\treturn;\n\t}\n\n\tbuffer[0] = DHCP_BOOTREQUEST; // op\n\tbuffer[1] = DHCP_HTYPE10MB; // htype\n\tbuffer[2] = DHCP_HLENETHERNET; // hlen\n\tbuffer[3] = DHCP_HOPS; // hops\n\n\t// xid\n\tunsigned long xid = htonl(_dhcpTransactionId);\n\tmemcpy(buffer + 4, &(xid), 4);\n\n\t// 8, 9 - seconds elapsed\n\tbuffer[8] = ((secondsElapsed & 0xff00) >> 8);\n\tbuffer[9] = (secondsElapsed & 0x00ff);\n\n\t// flags\n\tunsigned short flags = htons(DHCP_FLAGSBROADCAST);\n\tmemcpy(buffer + 10, &(flags), 2);\n\n\t// ciaddr: already zeroed\n\t// yiaddr: already zeroed\n\t// siaddr: already zeroed\n\t// giaddr: already zeroed\n\n\t//put data in W5100 transmit buffer\n\t_dhcpUdpSocket.write(buffer, 28);\n\n\tmemset(buffer, 0, 32); // clear local buffer\n\n\tmemcpy(buffer, _dhcpMacAddr, 6); // chaddr\n\n\t//put data in W5100 transmit buffer\n\t_dhcpUdpSocket.write(buffer, 16);\n\n\tmemset(buffer, 0, 32); // clear local buffer\n\n\t// leave zeroed out for sname && file\n\t// put in W5100 transmit buffer x 6 (192 bytes)\n\n\tfor(int i = 0; i < 6; i++) {\n\t\t_dhcpUdpSocket.write(buffer, 32);\n\t}\n\n\t// OPT - Magic Cookie\n\tbuffer[0] = (uint8_t)((MAGIC_COOKIE >> 24)& 0xFF);\n\tbuffer[1] = (uint8_t)((MAGIC_COOKIE >> 16)& 0xFF);\n\tbuffer[2] = (uint8_t)((MAGIC_COOKIE >> 8)& 0xFF);\n\tbuffer[3] = (uint8_t)(MAGIC_COOKIE& 0xFF);\n\n\t// OPT - message type\n\tbuffer[4] = dhcpMessageType;\n\tbuffer[5] = 0x01;\n\tbuffer[6] = messageType; //DHCP_REQUEST;\n\n\t// OPT - client identifier\n\tbuffer[7] = dhcpClientIdentifier;\n\tbuffer[8] = 0x07;\n\tbuffer[9] = 0x01;\n\tmemcpy(buffer + 10, _dhcpMacAddr, 6);\n\n\t// OPT - host name\n\tbuffer[16] = hostName;\n\tbuffer[17] = strlen(HOST_NAME) + 6; // length of hostname + last 3 bytes of mac address\n\tstrcpy((char*)&(buffer[18]), HOST_NAME);\n\n\tprintByte((char*)&(buffer[24]), _dhcpMacAddr[3]);\n\tprintByte((char*)&(buffer[26]), _dhcpMacAddr[4]);\n\tprintByte((char*)&(buffer[28]), _dhcpMacAddr[5]);\n\n\t//put data in W5100 transmit buffer\n\t_dhcpUdpSocket.write(buffer, 30);\n\n\tif (messageType == DHCP_REQUEST) {\n\t\tbuffer[0] = dhcpRequestedIPaddr;\n\t\tbuffer[1] = 0x04;\n\t\tbuffer[2] = _dhcpLocalIp[0];\n\t\tbuffer[3] = _dhcpLocalIp[1];\n\t\tbuffer[4] = _dhcpLocalIp[2];\n\t\tbuffer[5] = _dhcpLocalIp[3];\n\n\t\tbuffer[6] = dhcpServerIdentifier;\n\t\tbuffer[7] = 0x04;\n\t\tbuffer[8] = _dhcpDhcpServerIp[0];\n\t\tbuffer[9] = _dhcpDhcpServerIp[1];\n\t\tbuffer[10] = _dhcpDhcpServerIp[2];\n\t\tbuffer[11] = _dhcpDhcpServerIp[3];\n\n\t\t//put data in W5100 transmit buffer\n\t\t_dhcpUdpSocket.write(buffer, 12);\n\t}\n\n\tbuffer[0] = dhcpParamRequest;\n\tbuffer[1] = 0x06;\n\tbuffer[2] = subnetMask;\n\tbuffer[3] = routersOnSubnet;\n\tbuffer[4] = dns;\n\tbuffer[5] = domainName;\n\tbuffer[6] = dhcpT1value;\n\tbuffer[7] = dhcpT2value;\n\tbuffer[8] = endOption;\n\n\t//put data in W5100 transmit buffer\n\t_dhcpUdpSocket.write(buffer, 9);\n\n\t_dhcpUdpSocket.endPacket();\n}\n\nuint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId)\n{\n\tuint8_t type = 0;\n\tuint8_t opt_len = 0;\n\n\tunsigned long startTime = millis();\n\n\twhile (_dhcpUdpSocket.parsePacket() <= 0) {\n\t\tif ((millis() - startTime) > responseTimeout) {\n\t\t\treturn 255;\n\t\t}\n\t\tdelay(50);\n\t}\n\t// start reading in the packet\n\tRIP_MSG_FIXED fixedMsg;\n\t_dhcpUdpSocket.read((uint8_t*)&fixedMsg, sizeof(RIP_MSG_FIXED));\n\n\tif (fixedMsg.op == DHCP_BOOTREPLY && _dhcpUdpSocket.remotePort() == DHCP_SERVER_PORT) {\n\t\ttransactionId = ntohl(fixedMsg.xid);\n\t\tif (memcmp(fixedMsg.chaddr, _dhcpMacAddr, 6) != 0 ||\n\t\t (transactionId < _dhcpInitialTransactionId) ||\n\t\t (transactionId > _dhcpTransactionId)) {\n\t\t\t// Need to read the rest of the packet here regardless\n\t\t\t_dhcpUdpSocket.flush(); // FIXME\n\t\t\treturn 0;\n\t\t}\n\n\t\tmemcpy(_dhcpLocalIp, fixedMsg.yiaddr, 4);\n\n\t\t// Skip to the option part\n\t\t_dhcpUdpSocket.read((uint8_t *)NULL, 240 - (int)sizeof(RIP_MSG_FIXED));\n\n\t\twhile (_dhcpUdpSocket.available() > 0) {\n\t\t\tswitch (_dhcpUdpSocket.read()) {\n\t\t\tcase endOption :\n\t\t\t\tbreak;\n\n\t\t\tcase padOption :\n\t\t\t\tbreak;\n\n\t\t\tcase dhcpMessageType :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\ttype = _dhcpUdpSocket.read();\n\t\t\t\tbreak;\n\n\t\t\tcase subnetMask :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t_dhcpUdpSocket.read(_dhcpSubnetMask, 4);\n\t\t\t\tbreak;\n\n\t\t\tcase routersOnSubnet :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t_dhcpUdpSocket.read(_dhcpGatewayIp, 4);\n\t\t\t\t_dhcpUdpSocket.read((uint8_t *)NULL, opt_len - 4);\n\t\t\t\tbreak;\n\n\t\t\tcase dns :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t_dhcpUdpSocket.read(_dhcpDnsServerIp, 4);\n\t\t\t\t_dhcpUdpSocket.read((uint8_t *)NULL, opt_len - 4);\n\t\t\t\tbreak;\n\n\t\t\tcase dhcpServerIdentifier :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\tif ( IPAddress(_dhcpDhcpServerIp) == IPAddress((uint32_t)0) ||\n\t\t\t\t IPAddress(_dhcpDhcpServerIp) == _dhcpUdpSocket.remoteIP() ) {\n\t\t\t\t\t_dhcpUdpSocket.read(_dhcpDhcpServerIp, sizeof(_dhcpDhcpServerIp));\n\t\t\t\t} else {\n\t\t\t\t\t// Skip over the rest of this option\n\t\t\t\t\t_dhcpUdpSocket.read((uint8_t *)NULL, opt_len);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase dhcpT1value :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t_dhcpUdpSocket.read((uint8_t*)&_dhcpT1, sizeof(_dhcpT1));\n\t\t\t\t_dhcpT1 = ntohl(_dhcpT1);\n\t\t\t\tbreak;\n\n\t\t\tcase dhcpT2value :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t_dhcpUdpSocket.read((uint8_t*)&_dhcpT2, sizeof(_dhcpT2));\n\t\t\t\t_dhcpT2 = ntohl(_dhcpT2);\n\t\t\t\tbreak;\n\n\t\t\tcase dhcpIPaddrLeaseTime :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t_dhcpUdpSocket.read((uint8_t*)&_dhcpLeaseTime, sizeof(_dhcpLeaseTime));\n\t\t\t\t_dhcpLeaseTime = ntohl(_dhcpLeaseTime);\n\t\t\t\t_renewInSec = _dhcpLeaseTime;\n\t\t\t\tbreak;\n\n\t\t\tdefault :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t// Skip over the rest of this option\n\t\t\t\t_dhcpUdpSocket.read((uint8_t *)NULL, opt_len);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Need to skip to end of the packet regardless here\n\t_dhcpUdpSocket.flush(); // FIXME\n\n\treturn type;\n}\n\n\n/*\n returns:\n 0/DHCP_CHECK_NONE: nothing happened\n 1/DHCP_CHECK_RENEW_FAIL: renew failed\n 2/DHCP_CHECK_RENEW_OK: renew success\n 3/DHCP_CHECK_REBIND_FAIL: rebind fail\n 4/DHCP_CHECK_REBIND_OK: rebind success\n*/\nint DhcpClass::checkLease()\n{\n\tint rc = DHCP_CHECK_NONE;\n\n\tunsigned long now = millis();\n\tunsigned long elapsed = now - _lastCheckLeaseMillis;\n\n\t// if more then one sec passed, reduce the counters accordingly\n\tif (elapsed >= 1000) {\n\t\t// set the new timestamps\n\t\t_lastCheckLeaseMillis = now - (elapsed % 1000);\n\t\telapsed = elapsed / 1000;\n\n\t\t// decrease the counters by elapsed seconds\n\t\t// we assume that the cycle time (elapsed) is fairly constant\n\t\t// if the remainder is less than cycle time * 2\n\t\t// do it early instead of late\n\t\tif (_renewInSec < elapsed * 2) {\n\t\t\t_renewInSec = 0;\n\t\t} else {\n\t\t\t_renewInSec -= elapsed;\n\t\t}\n\t\tif (_rebindInSec < elapsed * 2) {\n\t\t\t_rebindInSec = 0;\n\t\t} else {\n\t\t\t_rebindInSec -= elapsed;\n\t\t}\n\t}\n\n\t// if we have a lease but should renew, do it\n\tif (_renewInSec == 0 &&_dhcp_state == STATE_DHCP_LEASED) {\n\t\t_dhcp_state = STATE_DHCP_REREQUEST;\n\t\trc = 1 + request_DHCP_lease();\n\t}\n\n\t// if we have a lease or is renewing but should bind, do it\n\tif (_rebindInSec == 0 && (_dhcp_state == STATE_DHCP_LEASED ||\n\t _dhcp_state == STATE_DHCP_START)) {\n\t\t// this should basically restart completely\n\t\t_dhcp_state = STATE_DHCP_START;\n\t\treset_DHCP_lease();\n\t\trc = 3 + request_DHCP_lease();\n\t}\n\treturn rc;\n}\n\nIPAddress DhcpClass::getLocalIp()\n{\n\treturn IPAddress(_dhcpLocalIp);\n}\n\nIPAddress DhcpClass::getSubnetMask()\n{\n\treturn IPAddress(_dhcpSubnetMask);\n}\n\nIPAddress DhcpClass::getGatewayIp()\n{\n\treturn IPAddress(_dhcpGatewayIp);\n}\n\nIPAddress DhcpClass::getDhcpServerIp()\n{\n\treturn IPAddress(_dhcpDhcpServerIp);\n}\n\nIPAddress DhcpClass::getDnsServerIp()\n{\n\treturn IPAddress(_dhcpDnsServerIp);\n}\n\nvoid DhcpClass::printByte(char * buf, uint8_t n )\n{\n\tchar *str = &buf[1];\n\tbuf[0]='0';\n\tdo {\n\t\tunsigned long m = n;\n\t\tn /= 16;\n\t\tchar c = m - 16 * n;\n\t\t*str-- = c < 10 ? c + '0' : c + 'A' - 10;\n\t} while(n);\n}\n" }, { filename: "src/Dhcp.h", code: "// DHCP Library v0.3 - April 25, 2009\n// Author: Jordan Terrell - blog.jordanterrell.com\n\n#ifndef Dhcp_h\n#define Dhcp_h\n\n/* DHCP state machine. */\n#define STATE_DHCP_START\t0\n#define\tSTATE_DHCP_DISCOVER\t1\n#define\tSTATE_DHCP_REQUEST\t2\n#define\tSTATE_DHCP_LEASED\t3\n#define\tSTATE_DHCP_REREQUEST\t4\n#define\tSTATE_DHCP_RELEASE\t5\n\n#define DHCP_FLAGSBROADCAST\t0x8000\n\n/* UDP port numbers for DHCP */\n#define\tDHCP_SERVER_PORT\t67\t/* from server to client */\n#define DHCP_CLIENT_PORT\t68\t/* from client to server */\n\n/* DHCP message OP code */\n#define DHCP_BOOTREQUEST\t1\n#define DHCP_BOOTREPLY\t\t2\n\n/* DHCP message type */\n#define\tDHCP_DISCOVER\t\t1\n#define DHCP_OFFER\t\t2\n#define\tDHCP_REQUEST\t\t3\n#define\tDHCP_DECLINE\t\t4\n#define\tDHCP_ACK\t\t5\n#define DHCP_NAK\t\t6\n#define\tDHCP_RELEASE\t\t7\n#define DHCP_INFORM\t\t8\n\n#define DHCP_HTYPE10MB\t\t1\n#define DHCP_HTYPE100MB\t\t2\n\n#define DHCP_HLENETHERNET\t6\n#define DHCP_HOPS\t\t0\n#define DHCP_SECS\t\t0\n\n#define MAGIC_COOKIE\t\t0x63825363\n#define MAX_DHCP_OPT\t\t16\n\n#define HOST_NAME \"WIZnet\"\n#define DEFAULT_LEASE\t(900) //default lease time in seconds\n\n#define DHCP_CHECK_NONE (0)\n#define DHCP_CHECK_RENEW_FAIL (1)\n#define DHCP_CHECK_RENEW_OK (2)\n#define DHCP_CHECK_REBIND_FAIL (3)\n#define DHCP_CHECK_REBIND_OK (4)\n\nenum\n{\n\tpadOption\t\t=\t0,\n\tsubnetMask\t\t=\t1,\n\ttimerOffset\t\t=\t2,\n\troutersOnSubnet\t\t=\t3,\n\t/* timeServer\t\t=\t4,\n\tnameServer\t\t=\t5,*/\n\tdns\t\t\t=\t6,\n\t/*logServer\t\t=\t7,\n\tcookieServer\t\t=\t8,\n\tlprServer\t\t=\t9,\n\timpressServer\t\t=\t10,\n\tresourceLocationServer\t=\t11,*/\n\thostName\t\t=\t12,\n\t/*bootFileSize\t\t=\t13,\n\tmeritDumpFile\t\t=\t14,*/\n\tdomainName\t\t=\t15,\n\t/*swapServer\t\t=\t16,\n\trootPath\t\t=\t17,\n\textentionsPath\t\t=\t18,\n\tIPforwarding\t\t=\t19,\n\tnonLocalSourceRouting\t=\t20,\n\tpolicyFilter\t\t=\t21,\n\tmaxDgramReasmSize\t=\t22,\n\tdefaultIPTTL\t\t=\t23,\n\tpathMTUagingTimeout\t=\t24,\n\tpathMTUplateauTable\t=\t25,\n\tifMTU\t\t\t=\t26,\n\tallSubnetsLocal\t\t=\t27,\n\tbroadcastAddr\t\t=\t28,\n\tperformMaskDiscovery\t=\t29,\n\tmaskSupplier\t\t=\t30,\n\tperformRouterDiscovery\t=\t31,\n\trouterSolicitationAddr\t=\t32,\n\tstaticRoute\t\t=\t33,\n\ttrailerEncapsulation\t=\t34,\n\tarpCacheTimeout\t\t=\t35,\n\tethernetEncapsulation\t=\t36,\n\ttcpDefaultTTL\t\t=\t37,\n\ttcpKeepaliveInterval\t=\t38,\n\ttcpKeepaliveGarbage\t=\t39,\n\tnisDomainName\t\t=\t40,\n\tnisServers\t\t=\t41,\n\tntpServers\t\t=\t42,\n\tvendorSpecificInfo\t=\t43,\n\tnetBIOSnameServer\t=\t44,\n\tnetBIOSdgramDistServer\t=\t45,\n\tnetBIOSnodeType\t\t=\t46,\n\tnetBIOSscope\t\t=\t47,\n\txFontServer\t\t=\t48,\n\txDisplayManager\t\t=\t49,*/\n\tdhcpRequestedIPaddr\t=\t50,\n\tdhcpIPaddrLeaseTime\t=\t51,\n\t/*dhcpOptionOverload\t=\t52,*/\n\tdhcpMessageType\t\t=\t53,\n\tdhcpServerIdentifier\t=\t54,\n\tdhcpParamRequest\t=\t55,\n\t/*dhcpMsg\t\t\t=\t56,\n\tdhcpMaxMsgSize\t\t=\t57,*/\n\tdhcpT1value\t\t=\t58,\n\tdhcpT2value\t\t=\t59,\n\t/*dhcpClassIdentifier\t=\t60,*/\n\tdhcpClientIdentifier\t=\t61,\n\tendOption\t\t=\t255\n};\n\ntypedef struct _RIP_MSG_FIXED\n{\n\tuint8_t op;\n\tuint8_t htype;\n\tuint8_t hlen;\n\tuint8_t hops;\n\tuint32_t xid;\n\tuint16_t secs;\n\tuint16_t flags;\n\tuint8_t ciaddr[4];\n\tuint8_t yiaddr[4];\n\tuint8_t siaddr[4];\n\tuint8_t giaddr[4];\n\tuint8_t chaddr[6];\n} RIP_MSG_FIXED;\n\n#endif\n" }, { filename: "src/Dns.cpp", code: "// Arduino DNS client for WizNet5100-based Ethernet shield\n// (c) Copyright 2009-2010 MCQN Ltd.\n// Released under Apache License, version 2.0\n\n#include \n#include \"Ethernet.h\"\n#include \"Dns.h\"\n#include \"w5100.h\"\n\n\n#define SOCKET_NONE 255\n// Various flags and header field values for a DNS message\n#define UDP_HEADER_SIZE 8\n#define DNS_HEADER_SIZE 12\n#define TTL_SIZE 4\n#define QUERY_FLAG (0)\n#define RESPONSE_FLAG (1<<15)\n#define QUERY_RESPONSE_MASK (1<<15)\n#define OPCODE_STANDARD_QUERY (0)\n#define OPCODE_INVERSE_QUERY (1<<11)\n#define OPCODE_STATUS_REQUEST (2<<11)\n#define OPCODE_MASK (15<<11)\n#define AUTHORITATIVE_FLAG (1<<10)\n#define TRUNCATION_FLAG (1<<9)\n#define RECURSION_DESIRED_FLAG (1<<8)\n#define RECURSION_AVAILABLE_FLAG (1<<7)\n#define RESP_NO_ERROR (0)\n#define RESP_FORMAT_ERROR (1)\n#define RESP_SERVER_FAILURE (2)\n#define RESP_NAME_ERROR (3)\n#define RESP_NOT_IMPLEMENTED (4)\n#define RESP_REFUSED (5)\n#define RESP_MASK (15)\n#define TYPE_A (0x0001)\n#define CLASS_IN (0x0001)\n#define LABEL_COMPRESSION_MASK (0xC0)\n// Port number that DNS servers listen on\n#define DNS_PORT 53\n\n// Possible return codes from ProcessResponse\n#define SUCCESS 1\n#define TIMED_OUT -1\n#define INVALID_SERVER -2\n#define TRUNCATED -3\n#define INVALID_RESPONSE -4\n\nvoid DNSClient::begin(const IPAddress& aDNSServer)\n{\n\tiDNSServer = aDNSServer;\n\tiRequestId = 0;\n}\n\n\nint DNSClient::inet_aton(const char* address, IPAddress& result)\n{\n\tuint16_t acc = 0; // Accumulator\n\tuint8_t dots = 0;\n\n\twhile (*address) {\n\t\tchar c = *address++;\n\t\tif (c >= '0' && c <= '9') {\n\t\t\tacc = acc * 10 + (c - '0');\n\t\t\tif (acc > 255) {\n\t\t\t\t// Value out of [0..255] range\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t} else if (c == '.') {\n\t\t\tif (dots == 3) {\n\t\t\t\t// Too much dots (there must be 3 dots)\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tresult[dots++] = acc;\n\t\t\tacc = 0;\n\t\t} else {\n\t\t\t// Invalid char\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tif (dots != 3) {\n\t\t// Too few dots (there must be 3 dots)\n\t\treturn 0;\n\t}\n\tresult[3] = acc;\n\treturn 1;\n}\n\nint DNSClient::getHostByName(const char* aHostname, IPAddress& aResult, uint16_t timeout)\n{\n\tint ret = 0;\n\n\t// See if it's a numeric IP address\n\tif (inet_aton(aHostname, aResult)) {\n\t\t// It is, our work here is done\n\t\treturn 1;\n\t}\n\n\t// Check we've got a valid DNS server to use\n\tif (iDNSServer == INADDR_NONE) {\n\t\treturn INVALID_SERVER;\n\t}\n\t\n\t// Find a socket to use\n\tif (iUdp.begin(1024+(millis() & 0xF)) == 1) {\n\t\t// Try up to three times\n\t\tint retries = 0;\n\t\t// while ((retries < 3) && (ret <= 0)) {\n\t\t// Send DNS request\n\t\tret = iUdp.beginPacket(iDNSServer, DNS_PORT);\n\t\tif (ret != 0) {\n\t\t\t// Now output the request data\n\t\t\tret = BuildRequest(aHostname);\n\t\t\tif (ret != 0) {\n\t\t\t\t// And finally send the request\n\t\t\t\tret = iUdp.endPacket();\n\t\t\t\tif (ret != 0) {\n\t\t\t\t\t// Now wait for a response\n\t\t\t\t\tint wait_retries = 0;\n\t\t\t\t\tret = TIMED_OUT;\n\t\t\t\t\twhile ((wait_retries < 3) && (ret == TIMED_OUT)) {\n\t\t\t\t\t\tret = ProcessResponse(timeout, aResult);\n\t\t\t\t\t\twait_retries++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tretries++;\n\t\t//}\n\n\t\t// We're done with the socket now\n\t\tiUdp.stop();\n\t}\n\n\treturn ret;\n}\n\nuint16_t DNSClient::BuildRequest(const char* aName)\n{\n\t// Build header\n\t// 1 1 1 1 1 1\n\t// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// | ID |\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// |QR| Opcode |AA|TC|RD|RA| Z | RCODE |\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// | QDCOUNT |\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// | ANCOUNT |\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// | NSCOUNT |\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// | ARCOUNT |\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// As we only support one request at a time at present, we can simplify\n\t// some of this header\n\tiRequestId = millis(); // generate a random ID\n\tuint16_t twoByteBuffer;\n\n\t// FIXME We should also check that there's enough space available to write to, rather\n\t// FIXME than assume there's enough space (as the code does at present)\n\tiUdp.write((uint8_t*)&iRequestId, sizeof(iRequestId));\n\n\ttwoByteBuffer = htons(QUERY_FLAG | OPCODE_STANDARD_QUERY | RECURSION_DESIRED_FLAG);\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\n\ttwoByteBuffer = htons(1); // One question record\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\n\ttwoByteBuffer = 0; // Zero answer records\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\t// and zero additional records\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\n\t// Build question\n\tconst char* start =aName;\n\tconst char* end =start;\n\tuint8_t len;\n\t// Run through the name being requested\n\twhile (*end) {\n\t\t// Find out how long this section of the name is\n\t\tend = start;\n\t\twhile (*end && (*end != '.') ) {\n\t\t\tend++;\n\t\t}\n\n\t\tif (end-start > 0) {\n\t\t\t// Write out the size of this section\n\t\t\tlen = end-start;\n\t\t\tiUdp.write(&len, sizeof(len));\n\t\t\t// And then write out the section\n\t\t\tiUdp.write((uint8_t*)start, end-start);\n\t\t}\n\t\tstart = end+1;\n\t}\n\n\t// We've got to the end of the question name, so\n\t// terminate it with a zero-length section\n\tlen = 0;\n\tiUdp.write(&len, sizeof(len));\n\t// Finally the type and class of question\n\ttwoByteBuffer = htons(TYPE_A);\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\n\ttwoByteBuffer = htons(CLASS_IN); // Internet class of question\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\t// Success! Everything buffered okay\n\treturn 1;\n}\n\n\nuint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress)\n{\n\tuint32_t startTime = millis();\n\n\t// Wait for a response packet\n\twhile (iUdp.parsePacket() <= 0) {\n\t\tif ((millis() - startTime) > aTimeout) {\n\t\t\treturn TIMED_OUT;\n\t\t}\n\t\tdelay(50);\n\t}\n\n\t// We've had a reply!\n\t// Read the UDP header\n\t//uint8_t header[DNS_HEADER_SIZE]; // Enough space to reuse for the DNS header\n\tunion {\n\t\tuint8_t byte[DNS_HEADER_SIZE]; // Enough space to reuse for the DNS header\n\t\tuint16_t word[DNS_HEADER_SIZE/2];\n\t} header;\n\n\t// Check that it's a response from the right server and the right port\n\tif ( (iDNSServer != iUdp.remoteIP()) || (iUdp.remotePort() != DNS_PORT) ) {\n\t\t// It's not from who we expected\n\t\treturn INVALID_SERVER;\n\t}\n\n\t// Read through the rest of the response\n\tif (iUdp.available() < DNS_HEADER_SIZE) {\n\t\treturn TRUNCATED;\n\t}\n\tiUdp.read(header.byte, DNS_HEADER_SIZE);\n\n\tuint16_t header_flags = htons(header.word[1]);\n\t// Check that it's a response to this request\n\tif ((iRequestId != (header.word[0])) ||\n\t ((header_flags & QUERY_RESPONSE_MASK) != (uint16_t)RESPONSE_FLAG) ) {\n\t\t// Mark the entire packet as read\n\t\tiUdp.flush(); // FIXME\n\t\treturn INVALID_RESPONSE;\n\t}\n\t// Check for any errors in the response (or in our request)\n\t// although we don't do anything to get round these\n\tif ( (header_flags & TRUNCATION_FLAG) || (header_flags & RESP_MASK) ) {\n\t\t// Mark the entire packet as read\n\t\tiUdp.flush(); // FIXME\n\t\treturn -5; //INVALID_RESPONSE;\n\t}\n\n\t// And make sure we've got (at least) one answer\n\tuint16_t answerCount = htons(header.word[3]);\n\tif (answerCount == 0) {\n\t\t// Mark the entire packet as read\n\t\tiUdp.flush(); // FIXME\n\t\treturn -6; //INVALID_RESPONSE;\n\t}\n\n\t// Skip over any questions\n\tfor (uint16_t i=0; i < htons(header.word[2]); i++) {\n\t\t// Skip over the name\n\t\tuint8_t len;\n\t\tdo {\n\t\t\tiUdp.read(&len, sizeof(len));\n\t\t\tif (len > 0) {\n\t\t\t\t// Don't need to actually read the data out for the string, just\n\t\t\t\t// advance ptr to beyond it\n\t\t\t\tiUdp.read((uint8_t *)NULL, (size_t)len);\n\t\t\t}\n\t\t} while (len != 0);\n\n\t\t// Now jump over the type and class\n\t\tiUdp.read((uint8_t *)NULL, 4);\n\t}\n\n\t// Now we're up to the bit we're interested in, the answer\n\t// There might be more than one answer (although we'll just use the first\n\t// type A answer) and some authority and additional resource records but\n\t// we're going to ignore all of them.\n\n\tfor (uint16_t i=0; i < answerCount; i++) {\n\t\t// Skip the name\n\t\tuint8_t len;\n\t\tdo {\n\t\t\tiUdp.read(&len, sizeof(len));\n\t\t\tif ((len & LABEL_COMPRESSION_MASK) == 0) {\n\t\t\t\t// It's just a normal label\n\t\t\t\tif (len > 0) {\n\t\t\t\t\t// And it's got a length\n\t\t\t\t\t// Don't need to actually read the data out for the string,\n\t\t\t\t\t// just advance ptr to beyond it\n\t\t\t\t\tiUdp.read((uint8_t *)NULL, len);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// This is a pointer to a somewhere else in the message for the\n\t\t\t\t// rest of the name. We don't care about the name, and RFC1035\n\t\t\t\t// says that a name is either a sequence of labels ended with a\n\t\t\t\t// 0 length octet or a pointer or a sequence of labels ending in\n\t\t\t\t// a pointer. Either way, when we get here we're at the end of\n\t\t\t\t// the name\n\t\t\t\t// Skip over the pointer\n\t\t\t\tiUdp.read((uint8_t *)NULL, 1); // we don't care about the byte\n\t\t\t\t// And set len so that we drop out of the name loop\n\t\t\t\tlen = 0;\n\t\t\t}\n\t\t} while (len != 0);\n\n\t\t// Check the type and class\n\t\tuint16_t answerType;\n\t\tuint16_t answerClass;\n\t\tiUdp.read((uint8_t*)&answerType, sizeof(answerType));\n\t\tiUdp.read((uint8_t*)&answerClass, sizeof(answerClass));\n\n\t\t// Ignore the Time-To-Live as we don't do any caching\n\t\tiUdp.read((uint8_t *)NULL, TTL_SIZE); // don't care about the returned bytes\n\n\t\t// And read out the length of this answer\n\t\t// Don't need header_flags anymore, so we can reuse it here\n\t\tiUdp.read((uint8_t*)&header_flags, sizeof(header_flags));\n\n\t\tif ( (htons(answerType) == TYPE_A) && (htons(answerClass) == CLASS_IN) ) {\n\t\t\tif (htons(header_flags) != 4) {\n\t\t\t\t// It's a weird size\n\t\t\t\t// Mark the entire packet as read\n\t\t\t\tiUdp.flush(); // FIXME\n\t\t\t\treturn -9;//INVALID_RESPONSE;\n\t\t\t}\n\t\t\t// FIXME: seeems to lock up here on ESP8266, but why??\n\t\t\tiUdp.read(aAddress.raw_address(), 4);\n\t\t\treturn SUCCESS;\n\t\t} else {\n\t\t\t// This isn't an answer type we're after, move onto the next one\n\t\t\tiUdp.read((uint8_t *)NULL, htons(header_flags));\n\t\t}\n\t}\n\n\t// Mark the entire packet as read\n\tiUdp.flush(); // FIXME\n\n\t// If we get here then we haven't found an answer\n\treturn -10; //INVALID_RESPONSE;\n}\n\n" }, { filename: "src/Dns.h", code: "// Arduino DNS client for WizNet5100-based Ethernet shield\n// (c) Copyright 2009-2010 MCQN Ltd.\n// Released under Apache License, version 2.0\n\n#ifndef DNSClient_h\n#define DNSClient_h\n\n#include \"Ethernet.h\"\n\nclass DNSClient\n{\npublic:\n\tvoid begin(const IPAddress& aDNSServer);\n\n\t/** Convert a numeric IP address string into a four-byte IP address.\n\t @param aIPAddrString IP address to convert\n\t @param aResult IPAddress structure to store the returned IP address\n\t @result 1 if aIPAddrString was successfully converted to an IP address,\n\t else error code\n\t*/\n\tint inet_aton(const char *aIPAddrString, IPAddress& aResult);\n\n\t/** Resolve the given hostname to an IP address.\n\t @param aHostname Name to be resolved\n\t @param aResult IPAddress structure to store the returned IP address\n\t @result 1 if aIPAddrString was successfully converted to an IP address,\n\t else error code\n\t*/\n\tint getHostByName(const char* aHostname, IPAddress& aResult, uint16_t timeout=5000);\n\nprotected:\n\tuint16_t BuildRequest(const char* aName);\n\tuint16_t ProcessResponse(uint16_t aTimeout, IPAddress& aAddress);\n\n\tIPAddress iDNSServer;\n\tuint16_t iRequestId;\n\tEthernetUDP iUdp;\n};\n\n#endif\n" }, { filename: "src/Ethernet.cpp", code: "/* Copyright 2018 Paul Stoffregen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this\n * software and associated documentation files (the \"Software\"), to deal in the Software\n * without restriction, including without limitation the rights to use, copy, modify,\n * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \n#include \"Ethernet.h\"\n#include \"w5100.h\"\n#include \"Dhcp.h\"\n\nIPAddress EthernetClass::_dnsServerAddress;\nDhcpClass* EthernetClass::_dhcp = NULL;\n\nint EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)\n{\n\tstatic DhcpClass s_dhcp;\n\t_dhcp = &s_dhcp;\n\n\t// Initialise the basic info\n\tif (W5100.init() == 0) return 0;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.setMACAddress(mac);\n\tW5100.setIPAddress(IPAddress(0,0,0,0).raw_address());\n\tSPI.endTransaction();\n\n\t// Now try to get our config info from a DHCP server\n\tint ret = _dhcp->beginWithDHCP(mac, timeout, responseTimeout);\n\tif (ret == 1) {\n\t\t// We've successfully found a DHCP server and got our configuration\n\t\t// info, so set things accordingly\n\t\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\t\tW5100.setIPAddress(_dhcp->getLocalIp().raw_address());\n\t\tW5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());\n\t\tW5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());\n\t\tSPI.endTransaction();\n\t\t_dnsServerAddress = _dhcp->getDnsServerIp();\n\t\tsocketPortRand(micros());\n\t}\n\treturn ret;\n}\n\nvoid EthernetClass::begin(uint8_t *mac, IPAddress ip)\n{\n\t// Assume the DNS server will be the machine on the same network as the local IP\n\t// but with last octet being '1'\n\tIPAddress dns = ip;\n\tdns[3] = 1;\n\tbegin(mac, ip, dns);\n}\n\nvoid EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns)\n{\n\t// Assume the gateway will be the machine on the same network as the local IP\n\t// but with last octet being '1'\n\tIPAddress gateway = ip;\n\tgateway[3] = 1;\n\tbegin(mac, ip, dns, gateway);\n}\n\nvoid EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway)\n{\n\tIPAddress subnet(255, 255, 255, 0);\n\tbegin(mac, ip, dns, gateway, subnet);\n}\n\nvoid EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)\n{\n\tif (W5100.init() == 0) return;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.setMACAddress(mac);\n#if ARDUINO > 106 || TEENSYDUINO > 121\n\tW5100.setIPAddress(ip._address.bytes);\n\tW5100.setGatewayIp(gateway._address.bytes);\n\tW5100.setSubnetMask(subnet._address.bytes);\n#else\n\tW5100.setIPAddress(ip._address);\n\tW5100.setGatewayIp(gateway._address);\n\tW5100.setSubnetMask(subnet._address);\n#endif\n\tSPI.endTransaction();\n\t_dnsServerAddress = dns;\n}\n\nvoid EthernetClass::init(uint8_t sspin)\n{\n\tW5100.setSS(sspin);\n}\n\nEthernetLinkStatus EthernetClass::linkStatus()\n{\n\tswitch (W5100.getLinkStatus()) {\n\t\tcase UNKNOWN: return Unknown;\n\t\tcase LINK_ON: return LinkON;\n\t\tcase LINK_OFF: return LinkOFF;\n\t\tdefault: return Unknown;\n\t}\n}\n\nEthernetHardwareStatus EthernetClass::hardwareStatus()\n{\n\tswitch (W5100.getChip()) {\n\t\tcase 51: return EthernetW5100;\n\t\tcase 52: return EthernetW5200;\n\t\tcase 55: return EthernetW5500;\n\t\tdefault: return EthernetNoHardware;\n\t}\n}\n\nint EthernetClass::maintain()\n{\n\tint rc = DHCP_CHECK_NONE;\n\tif (_dhcp != NULL) {\n\t\t// we have a pointer to dhcp, use it\n\t\trc = _dhcp->checkLease();\n\t\tswitch (rc) {\n\t\tcase DHCP_CHECK_NONE:\n\t\t\t//nothing done\n\t\t\tbreak;\n\t\tcase DHCP_CHECK_RENEW_OK:\n\t\tcase DHCP_CHECK_REBIND_OK:\n\t\t\t//we might have got a new IP.\n\t\t\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\t\t\tW5100.setIPAddress(_dhcp->getLocalIp().raw_address());\n\t\t\tW5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());\n\t\t\tW5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());\n\t\t\tSPI.endTransaction();\n\t\t\t_dnsServerAddress = _dhcp->getDnsServerIp();\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t//this is actually an error, it will retry though\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn rc;\n}\n\n\nvoid EthernetClass::MACAddress(uint8_t *mac_address)\n{\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.getMACAddress(mac_address);\n\tSPI.endTransaction();\n}\n\nIPAddress EthernetClass::localIP()\n{\n\tIPAddress ret;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.getIPAddress(ret.raw_address());\n\tSPI.endTransaction();\n\treturn ret;\n}\n\nIPAddress EthernetClass::subnetMask()\n{\n\tIPAddress ret;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.getSubnetMask(ret.raw_address());\n\tSPI.endTransaction();\n\treturn ret;\n}\n\nIPAddress EthernetClass::gatewayIP()\n{\n\tIPAddress ret;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.getGatewayIp(ret.raw_address());\n\tSPI.endTransaction();\n\treturn ret;\n}\n\nvoid EthernetClass::setMACAddress(const uint8_t *mac_address)\n{\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.setMACAddress(mac_address);\n\tSPI.endTransaction();\n}\n\nvoid EthernetClass::setLocalIP(const IPAddress local_ip)\n{\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tIPAddress ip = local_ip;\n\tW5100.setIPAddress(ip.raw_address());\n\tSPI.endTransaction();\n}\n\nvoid EthernetClass::setSubnetMask(const IPAddress subnet)\n{\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tIPAddress ip = subnet;\n\tW5100.setSubnetMask(ip.raw_address());\n\tSPI.endTransaction();\n}\n\nvoid EthernetClass::setGatewayIP(const IPAddress gateway)\n{\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tIPAddress ip = gateway;\n\tW5100.setGatewayIp(ip.raw_address());\n\tSPI.endTransaction();\n}\n\nvoid EthernetClass::setRetransmissionTimeout(uint16_t milliseconds)\n{\n\tif (milliseconds > 6553) milliseconds = 6553;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.setRetransmissionTime(milliseconds * 10);\n\tSPI.endTransaction();\n}\n\nvoid EthernetClass::setRetransmissionCount(uint8_t num)\n{\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.setRetransmissionCount(num);\n\tSPI.endTransaction();\n}\n\n\n\n\n\n\n\n\n\n\nEthernetClass Ethernet;\n" }, { filename: "src/Ethernet.h", code: "/* Copyright 2018 Paul Stoffregen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this\n * software and associated documentation files (the \"Software\"), to deal in the Software\n * without restriction, including without limitation the rights to use, copy, modify,\n * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef ethernet_h_\n#define ethernet_h_\n\n// All symbols exposed to Arduino sketches are contained in this header file\n//\n// Older versions had much of this stuff in EthernetClient.h, EthernetServer.h,\n// and socket.h. Including headers in different order could cause trouble, so\n// these \"friend\" classes are now defined in the same header file. socket.h\n// was removed to avoid possible conflict with the C library header files.\n\n\n// Configure the maximum number of sockets to support. W5100 chips can have\n// up to 4 sockets. W5200 & W5500 can have up to 8 sockets. Several bytes\n// of RAM are used for each socket. Reducing the maximum can save RAM, but\n// you are limited to fewer simultaneous connections.\n#if defined(RAMEND) && defined(RAMSTART) && ((RAMEND - RAMSTART) <= 2048)\n#define MAX_SOCK_NUM 4\n#else\n#define MAX_SOCK_NUM 8\n#endif\n\n// By default, each socket uses 2K buffers inside the Wiznet chip. If\n// MAX_SOCK_NUM is set to fewer than the chip's maximum, uncommenting\n// this will use larger buffers within the Wiznet chip. Large buffers\n// can really help with UDP protocols like Artnet. In theory larger\n// buffers should allow faster TCP over high-latency links, but this\n// does not always seem to work in practice (maybe Wiznet bugs?)\n//#define ETHERNET_LARGE_BUFFERS\n\n\n#include \n#include \"Client.h\"\n#include \"Server.h\"\n#include \"Udp.h\"\n\nenum EthernetLinkStatus {\n\tUnknown,\n\tLinkON,\n\tLinkOFF\n};\n\nenum EthernetHardwareStatus {\n\tEthernetNoHardware,\n\tEthernetW5100,\n\tEthernetW5200,\n\tEthernetW5500\n};\n\nclass EthernetUDP;\nclass EthernetClient;\nclass EthernetServer;\nclass DhcpClass;\n\nclass EthernetClass {\nprivate:\n\tstatic IPAddress _dnsServerAddress;\n\tstatic DhcpClass* _dhcp;\npublic:\n\t// Initialise the Ethernet shield to use the provided MAC address and\n\t// gain the rest of the configuration through DHCP.\n\t// Returns 0 if the DHCP configuration failed, and 1 if it succeeded\n\tstatic int begin(uint8_t *mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);\n\tstatic int maintain();\n\tstatic EthernetLinkStatus linkStatus();\n\tstatic EthernetHardwareStatus hardwareStatus();\n\n\t// Manaul configuration\n\tstatic void begin(uint8_t *mac, IPAddress ip);\n\tstatic void begin(uint8_t *mac, IPAddress ip, IPAddress dns);\n\tstatic void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway);\n\tstatic void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);\n\tstatic void init(uint8_t sspin = 10);\n\n\tstatic void MACAddress(uint8_t *mac_address);\n\tstatic IPAddress localIP();\n\tstatic IPAddress subnetMask();\n\tstatic IPAddress gatewayIP();\n\tstatic IPAddress dnsServerIP() { return _dnsServerAddress; }\n\n\tvoid setMACAddress(const uint8_t *mac_address);\n\tvoid setLocalIP(const IPAddress local_ip);\n\tvoid setSubnetMask(const IPAddress subnet);\n\tvoid setGatewayIP(const IPAddress gateway);\n\tvoid setDnsServerIP(const IPAddress dns_server) { _dnsServerAddress = dns_server; }\n\tvoid setRetransmissionTimeout(uint16_t milliseconds);\n\tvoid setRetransmissionCount(uint8_t num);\n\n\tfriend class EthernetClient;\n\tfriend class EthernetServer;\n\tfriend class EthernetUDP;\nprivate:\n\t// Opens a socket(TCP or UDP or IP_RAW mode)\n\tstatic uint8_t socketBegin(uint8_t protocol, uint16_t port);\n\tstatic uint8_t socketBeginMulticast(uint8_t protocol, IPAddress ip,uint16_t port);\n\tstatic uint8_t socketStatus(uint8_t s);\n\t// Close socket\n\tstatic void socketClose(uint8_t s);\n\t// Establish TCP connection (Active connection)\n\tstatic void socketConnect(uint8_t s, uint8_t * addr, uint16_t port);\n\t// disconnect the connection\n\tstatic void socketDisconnect(uint8_t s);\n\t// Establish TCP connection (Passive connection)\n\tstatic uint8_t socketListen(uint8_t s);\n\t// Send data (TCP)\n\tstatic uint16_t socketSend(uint8_t s, const uint8_t * buf, uint16_t len);\n\tstatic uint16_t socketSendAvailable(uint8_t s);\n\t// Receive data (TCP)\n\tstatic int socketRecv(uint8_t s, uint8_t * buf, int16_t len);\n\tstatic uint16_t socketRecvAvailable(uint8_t s);\n\tstatic uint8_t socketPeek(uint8_t s);\n\t// sets up a UDP datagram, the data for which will be provided by one\n\t// or more calls to bufferData and then finally sent with sendUDP.\n\t// return true if the datagram was successfully set up, or false if there was an error\n\tstatic bool socketStartUDP(uint8_t s, uint8_t* addr, uint16_t port);\n\t// copy up to len bytes of data from buf into a UDP datagram to be\n\t// sent later by sendUDP. Allows datagrams to be built up from a series of bufferData calls.\n\t// return Number of bytes successfully buffered\n\tstatic uint16_t socketBufferData(uint8_t s, uint16_t offset, const uint8_t* buf, uint16_t len);\n\t// Send a UDP datagram built up from a sequence of startUDP followed by one or more\n\t// calls to bufferData.\n\t// return true if the datagram was successfully sent, or false if there was an error\n\tstatic bool socketSendUDP(uint8_t s);\n\t// Initialize the \"random\" source port number\n\tstatic void socketPortRand(uint16_t n);\n};\n\nextern EthernetClass Ethernet;\n\n\n#define UDP_TX_PACKET_MAX_SIZE 24\n\nclass EthernetUDP : public UDP {\nprivate:\n\tuint16_t _port; // local port to listen on\n\tIPAddress _remoteIP; // remote IP address for the incoming packet whilst it's being processed\n\tuint16_t _remotePort; // remote port for the incoming packet whilst it's being processed\n\tuint16_t _offset; // offset into the packet being sent\n\nprotected:\n\tuint8_t sockindex;\n\tuint16_t _remaining; // remaining bytes of incoming packet yet to be processed\n\npublic:\n\tEthernetUDP() : sockindex(MAX_SOCK_NUM) {} // Constructor\n\tvirtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use\n\tvirtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use\n\tvirtual void stop(); // Finish with the UDP socket\n\n\t// Sending UDP packets\n\n\t// Start building up a packet to send to the remote host specific in ip and port\n\t// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port\n\tvirtual int beginPacket(IPAddress ip, uint16_t port);\n\t// Start building up a packet to send to the remote host specific in host and port\n\t// Returns 1 if successful, 0 if there was a problem resolving the hostname or port\n\tvirtual int beginPacket(const char *host, uint16_t port);\n\t// Finish off this packet and send it\n\t// Returns 1 if the packet was sent successfully, 0 if there was an error\n\tvirtual int endPacket();\n\t// Write a single byte into the packet\n\tvirtual size_t write(uint8_t);\n\t// Write size bytes from buffer into the packet\n\tvirtual size_t write(const uint8_t *buffer, size_t size);\n\n\tusing Print::write;\n\n\t// Start processing the next available incoming packet\n\t// Returns the size of the packet in bytes, or 0 if no packets are available\n\tvirtual int parsePacket();\n\t// Number of bytes remaining in the current packet\n\tvirtual int available();\n\t// Read a single byte from the current packet\n\tvirtual int read();\n\t// Read up to len bytes from the current packet and place them into buffer\n\t// Returns the number of bytes read, or 0 if none are available\n\tvirtual int read(unsigned char* buffer, size_t len);\n\t// Read up to len characters from the current packet and place them into buffer\n\t// Returns the number of characters read, or 0 if none are available\n\tvirtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };\n\t// Return the next byte from the current packet without moving on to the next byte\n\tvirtual int peek();\n\tvirtual void flush(); // Finish reading the current packet\n\n\t// Return the IP address of the host who sent the current incoming packet\n\tvirtual IPAddress remoteIP() { return _remoteIP; };\n\t// Return the port of the host who sent the current incoming packet\n\tvirtual uint16_t remotePort() { return _remotePort; };\n\tvirtual uint16_t localPort() { return _port; }\n};\n\n\n\n\nclass EthernetClient : public Client {\npublic:\n\tEthernetClient() : sockindex(MAX_SOCK_NUM), _timeout(1000) { }\n\tEthernetClient(uint8_t s) : sockindex(s), _timeout(1000) { }\n\n\tuint8_t status();\n\tvirtual int connect(IPAddress ip, uint16_t port);\n\tvirtual int connect(const char *host, uint16_t port);\n\tvirtual int availableForWrite(void);\n\tvirtual size_t write(uint8_t);\n\tvirtual size_t write(const uint8_t *buf, size_t size);\n\tvirtual int available();\n\tvirtual int read();\n\tvirtual int read(uint8_t *buf, size_t size);\n\tvirtual int peek();\n\tvirtual void flush();\n\tvirtual void stop();\n\tvirtual uint8_t connected();\n\tvirtual operator bool() { return sockindex < MAX_SOCK_NUM; }\n\tvirtual bool operator==(const bool value) { return bool() == value; }\n\tvirtual bool operator!=(const bool value) { return bool() != value; }\n\tvirtual bool operator==(const EthernetClient&);\n\tvirtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); }\n\tuint8_t getSocketNumber() const { return sockindex; }\n\tvirtual uint16_t localPort();\n\tvirtual IPAddress remoteIP();\n\tvirtual uint16_t remotePort();\n\tvirtual void setConnectionTimeout(uint16_t timeout) { _timeout = timeout; }\n\n\tfriend class EthernetServer;\n\n\tusing Print::write;\n\nprivate:\n\tuint8_t sockindex; // MAX_SOCK_NUM means client not in use\n\tuint16_t _timeout;\n};\n\n\nclass EthernetServer : public Server {\nprivate:\n\tuint16_t _port;\npublic:\n\tEthernetServer(uint16_t port) : _port(port) { }\n\tEthernetClient available();\n\tEthernetClient accept();\n\tvirtual void begin();\n\tvirtual size_t write(uint8_t);\n\tvirtual size_t write(const uint8_t *buf, size_t size);\n\tvirtual operator bool();\n\tusing Print::write;\n\t//void statusreport();\n\n\t// TODO: make private when socket allocation moves to EthernetClass\n\tstatic uint16_t server_port[MAX_SOCK_NUM];\n};\n\n\nclass DhcpClass {\nprivate:\n\tuint32_t _dhcpInitialTransactionId;\n\tuint32_t _dhcpTransactionId;\n\tuint8_t _dhcpMacAddr[6];\n#ifdef __arm__\n\tuint8_t _dhcpLocalIp[4] __attribute__((aligned(4)));\n\tuint8_t _dhcpSubnetMask[4] __attribute__((aligned(4)));\n\tuint8_t _dhcpGatewayIp[4] __attribute__((aligned(4)));\n\tuint8_t _dhcpDhcpServerIp[4] __attribute__((aligned(4)));\n\tuint8_t _dhcpDnsServerIp[4] __attribute__((aligned(4)));\n#else\n\tuint8_t _dhcpLocalIp[4];\n\tuint8_t _dhcpSubnetMask[4];\n\tuint8_t _dhcpGatewayIp[4];\n\tuint8_t _dhcpDhcpServerIp[4];\n\tuint8_t _dhcpDnsServerIp[4];\n#endif\n\tuint32_t _dhcpLeaseTime;\n\tuint32_t _dhcpT1, _dhcpT2;\n\tuint32_t _renewInSec;\n\tuint32_t _rebindInSec;\n\tunsigned long _timeout;\n\tunsigned long _responseTimeout;\n\tunsigned long _lastCheckLeaseMillis;\n\tuint8_t _dhcp_state;\n\tEthernetUDP _dhcpUdpSocket;\n\n\tint request_DHCP_lease();\n\tvoid reset_DHCP_lease();\n\tvoid presend_DHCP();\n\tvoid send_DHCP_MESSAGE(uint8_t, uint16_t);\n\tvoid printByte(char *, uint8_t);\n\n\tuint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId);\npublic:\n\tIPAddress getLocalIp();\n\tIPAddress getSubnetMask();\n\tIPAddress getGatewayIp();\n\tIPAddress getDhcpServerIp();\n\tIPAddress getDnsServerIp();\n\n\tint beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);\n\tint checkLease();\n};\n\n\n\n\n\n#endif\n" }, { filename: "src/EthernetClient.cpp", code: "/* Copyright 2018 Paul Stoffregen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this\n * software and associated documentation files (the \"Software\"), to deal in the Software\n * without restriction, including without limitation the rights to use, copy, modify,\n * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \n#include \"Ethernet.h\"\n#include \"Dns.h\"\n#include \"w5100.h\"\n\nint EthernetClient::connect(const char * host, uint16_t port)\n{\n\tDNSClient dns; // Look up the host first\n\tIPAddress remote_addr;\n\n\tif (sockindex < MAX_SOCK_NUM) {\n\t\tif (Ethernet.socketStatus(sockindex) != SnSR::CLOSED) {\n\t\t\tEthernet.socketDisconnect(sockindex); // TODO: should we call stop()?\n\t\t}\n\t\tsockindex = MAX_SOCK_NUM;\n\t}\n\tdns.begin(Ethernet.dnsServerIP());\n\tif (!dns.getHostByName(host, remote_addr)) return 0; // TODO: use _timeout\n\treturn connect(remote_addr, port);\n}\n\nint EthernetClient::connect(IPAddress ip, uint16_t port)\n{\n\tif (sockindex < MAX_SOCK_NUM) {\n\t\tif (Ethernet.socketStatus(sockindex) != SnSR::CLOSED) {\n\t\t\tEthernet.socketDisconnect(sockindex); // TODO: should we call stop()?\n\t\t}\n\t\tsockindex = MAX_SOCK_NUM;\n\t}\n#if defined(ESP8266) || defined(ESP32)\n\tif (ip == IPAddress((uint32_t)0) || ip == IPAddress(0xFFFFFFFFul)) return 0;\n#else\n\tif (ip == IPAddress(0ul) || ip == IPAddress(0xFFFFFFFFul)) return 0;\n#endif\n\tsockindex = Ethernet.socketBegin(SnMR::TCP, 0);\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\tEthernet.socketConnect(sockindex, rawIPAddress(ip), port);\n\tuint32_t start = millis();\n\twhile (1) {\n\t\tuint8_t stat = Ethernet.socketStatus(sockindex);\n\t\tif (stat == SnSR::ESTABLISHED) return 1;\n\t\tif (stat == SnSR::CLOSE_WAIT) return 1;\n\t\tif (stat == SnSR::CLOSED) return 0;\n\t\tif (millis() - start > _timeout) break;\n\t\tdelay(1);\n\t}\n\tEthernet.socketClose(sockindex);\n\tsockindex = MAX_SOCK_NUM;\n\treturn 0;\n}\n\nint EthernetClient::availableForWrite(void)\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\treturn Ethernet.socketSendAvailable(sockindex);\n}\n\nsize_t EthernetClient::write(uint8_t b)\n{\n\treturn write(&b, 1);\n}\n\nsize_t EthernetClient::write(const uint8_t *buf, size_t size)\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\tif (Ethernet.socketSend(sockindex, buf, size)) return size;\n\tsetWriteError();\n\treturn 0;\n}\n\nint EthernetClient::available()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\treturn Ethernet.socketRecvAvailable(sockindex);\n\t// TODO: do the Wiznet chips automatically retransmit TCP ACK\n\t// packets if they are lost by the network? Someday this should\n\t// be checked by a man-in-the-middle test which discards certain\n\t// packets. If ACKs aren't resent, we would need to check for\n\t// returning 0 here and after a timeout do another Sock_RECV\n\t// command to cause the Wiznet chip to resend the ACK packet.\n}\n\nint EthernetClient::read(uint8_t *buf, size_t size)\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\treturn Ethernet.socketRecv(sockindex, buf, size);\n}\n\nint EthernetClient::peek()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return -1;\n\tif (!available()) return -1;\n\treturn Ethernet.socketPeek(sockindex);\n}\n\nint EthernetClient::read()\n{\n\tuint8_t b;\n\tif (Ethernet.socketRecv(sockindex, &b, 1) > 0) return b;\n\treturn -1;\n}\n\nvoid EthernetClient::flush()\n{\n\twhile (sockindex < MAX_SOCK_NUM) {\n\t\tuint8_t stat = Ethernet.socketStatus(sockindex);\n\t\tif (stat != SnSR::ESTABLISHED && stat != SnSR::CLOSE_WAIT) return;\n\t\tif (Ethernet.socketSendAvailable(sockindex) >= W5100.SSIZE) return;\n\t}\n}\n\nvoid EthernetClient::stop()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return;\n\n\t// attempt to close the connection gracefully (send a FIN to other side)\n\tEthernet.socketDisconnect(sockindex);\n\tunsigned long start = millis();\n\n\t// wait up to a second for the connection to close\n\tdo {\n\t\tif (Ethernet.socketStatus(sockindex) == SnSR::CLOSED) {\n\t\t\tsockindex = MAX_SOCK_NUM;\n\t\t\treturn; // exit the loop\n\t\t}\n\t\tdelay(1);\n\t} while (millis() - start < _timeout);\n\n\t// if it hasn't closed, close it forcefully\n\tEthernet.socketClose(sockindex);\n\tsockindex = MAX_SOCK_NUM;\n}\n\nuint8_t EthernetClient::connected()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\n\tuint8_t s = Ethernet.socketStatus(sockindex);\n\treturn !(s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::FIN_WAIT ||\n\t\t(s == SnSR::CLOSE_WAIT && !available()));\n}\n\nuint8_t EthernetClient::status()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return SnSR::CLOSED;\n\treturn Ethernet.socketStatus(sockindex);\n}\n\n// the next function allows us to use the client returned by\n// EthernetServer::available() as the condition in an if-statement.\nbool EthernetClient::operator==(const EthernetClient& rhs)\n{\n\tif (sockindex != rhs.sockindex) return false;\n\tif (sockindex >= MAX_SOCK_NUM) return false;\n\tif (rhs.sockindex >= MAX_SOCK_NUM) return false;\n\treturn true;\n}\n\n// https://github.com/per1234/EthernetMod\n// from: https://github.com/ntruchsess/Arduino-1/commit/937bce1a0bb2567f6d03b15df79525569377dabd\nuint16_t EthernetClient::localPort()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\tuint16_t port;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tport = W5100.readSnPORT(sockindex);\n\tSPI.endTransaction();\n\treturn port;\n}\n\n// https://github.com/per1234/EthernetMod\n// returns the remote IP address: http://forum.arduino.cc/index.php?topic=82416.0\nIPAddress EthernetClient::remoteIP()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return IPAddress((uint32_t)0);\n\tuint8_t remoteIParray[4];\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.readSnDIPR(sockindex, remoteIParray);\n\tSPI.endTransaction();\n\treturn IPAddress(remoteIParray);\n}\n\n// https://github.com/per1234/EthernetMod\n// from: https://github.com/ntruchsess/Arduino-1/commit/ca37de4ba4ecbdb941f14ac1fe7dd40f3008af75\nuint16_t EthernetClient::remotePort()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\tuint16_t port;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tport = W5100.readSnDPORT(sockindex);\n\tSPI.endTransaction();\n\treturn port;\n}\n\n\n" }, { filename: "src/EthernetClient.h", code: "// This file is in the public domain. No copyright is claimed.\n\n#include \"Ethernet.h\"\n" }, { filename: "src/EthernetServer.cpp", code: "/* Copyright 2018 Paul Stoffregen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this\n * software and associated documentation files (the \"Software\"), to deal in the Software\n * without restriction, including without limitation the rights to use, copy, modify,\n * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \n#include \"Ethernet.h\"\n#include \"w5100.h\"\n\nuint16_t EthernetServer::server_port[MAX_SOCK_NUM];\n\n\nvoid EthernetServer::begin()\n{\n\tuint8_t sockindex = Ethernet.socketBegin(SnMR::TCP, _port);\n\tif (sockindex < MAX_SOCK_NUM) {\n\t\tif (Ethernet.socketListen(sockindex)) {\n\t\t\tserver_port[sockindex] = _port;\n\t\t} else {\n\t\t\tEthernet.socketDisconnect(sockindex);\n\t\t}\n\t}\n}\n\nEthernetClient EthernetServer::available()\n{\n\tbool listening = false;\n\tuint8_t sockindex = MAX_SOCK_NUM;\n\tuint8_t chip, maxindex=MAX_SOCK_NUM;\n\n\tchip = W5100.getChip();\n\tif (!chip) return EthernetClient(MAX_SOCK_NUM);\n#if MAX_SOCK_NUM > 4\n\tif (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets\n#endif\n\tfor (uint8_t i=0; i < maxindex; i++) {\n\t\tif (server_port[i] == _port) {\n\t\t\tuint8_t stat = Ethernet.socketStatus(i);\n\t\t\tif (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT) {\n\t\t\t\tif (Ethernet.socketRecvAvailable(i) > 0) {\n\t\t\t\t\tsockindex = i;\n\t\t\t\t} else {\n\t\t\t\t\t// remote host closed connection, our end still open\n\t\t\t\t\tif (stat == SnSR::CLOSE_WAIT) {\n\t\t\t\t\t\tEthernet.socketDisconnect(i);\n\t\t\t\t\t\t// status becomes LAST_ACK for short time\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (stat == SnSR::LISTEN) {\n\t\t\t\tlistening = true;\n\t\t\t} else if (stat == SnSR::CLOSED) {\n\t\t\t\tserver_port[i] = 0;\n\t\t\t}\n\t\t}\n\t}\n\tif (!listening) begin();\n\treturn EthernetClient(sockindex);\n}\n\nEthernetClient EthernetServer::accept()\n{\n\tbool listening = false;\n\tuint8_t sockindex = MAX_SOCK_NUM;\n\tuint8_t chip, maxindex=MAX_SOCK_NUM;\n\n\tchip = W5100.getChip();\n\tif (!chip) return EthernetClient(MAX_SOCK_NUM);\n#if MAX_SOCK_NUM > 4\n\tif (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets\n#endif\n\tfor (uint8_t i=0; i < maxindex; i++) {\n\t\tif (server_port[i] == _port) {\n\t\t\tuint8_t stat = Ethernet.socketStatus(i);\n\t\t\tif (sockindex == MAX_SOCK_NUM &&\n\t\t\t (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT)) {\n\t\t\t\t// Return the connected client even if no data received.\n\t\t\t\t// Some protocols like FTP expect the server to send the\n\t\t\t\t// first data.\n\t\t\t\tsockindex = i;\n\t\t\t\tserver_port[i] = 0; // only return the client once\n\t\t\t} else if (stat == SnSR::LISTEN) {\n\t\t\t\tlistening = true;\n\t\t\t} else if (stat == SnSR::CLOSED) {\n\t\t\t\tserver_port[i] = 0;\n\t\t\t}\n\t\t}\n\t}\n\tif (!listening) begin();\n\treturn EthernetClient(sockindex);\n}\n\nEthernetServer::operator bool()\n{\n\tuint8_t maxindex=MAX_SOCK_NUM;\n#if MAX_SOCK_NUM > 4\n\tif (W5100.getChip() == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets\n#endif\n\tfor (uint8_t i=0; i < maxindex; i++) {\n\t\tif (server_port[i] == _port) {\n\t\t\tif (Ethernet.socketStatus(i) == SnSR::LISTEN) {\n\t\t\t\treturn true; // server is listening for incoming clients\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n\n#if 0\nvoid EthernetServer::statusreport()\n{\n\tSerial.printf(\"EthernetServer, port=%d\\n\", _port);\n\tfor (uint8_t i=0; i < MAX_SOCK_NUM; i++) {\n\t\tuint16_t port = server_port[i];\n\t\tuint8_t stat = Ethernet.socketStatus(i);\n\t\tconst char *name;\n\t\tswitch (stat) {\n\t\t\tcase 0x00: name = \"CLOSED\"; break;\n\t\t\tcase 0x13: name = \"INIT\"; break;\n\t\t\tcase 0x14: name = \"LISTEN\"; break;\n\t\t\tcase 0x15: name = \"SYNSENT\"; break;\n\t\t\tcase 0x16: name = \"SYNRECV\"; break;\n\t\t\tcase 0x17: name = \"ESTABLISHED\"; break;\n\t\t\tcase 0x18: name = \"FIN_WAIT\"; break;\n\t\t\tcase 0x1A: name = \"CLOSING\"; break;\n\t\t\tcase 0x1B: name = \"TIME_WAIT\"; break;\n\t\t\tcase 0x1C: name = \"CLOSE_WAIT\"; break;\n\t\t\tcase 0x1D: name = \"LAST_ACK\"; break;\n\t\t\tcase 0x22: name = \"UDP\"; break;\n\t\t\tcase 0x32: name = \"IPRAW\"; break;\n\t\t\tcase 0x42: name = \"MACRAW\"; break;\n\t\t\tcase 0x5F: name = \"PPPOE\"; break;\n\t\t\tdefault: name = \"???\";\n\t\t}\n\t\tint avail = Ethernet.socketRecvAvailable(i);\n\t\tSerial.printf(\" %d: port=%d, status=%s (0x%02X), avail=%d\\n\",\n\t\t\ti, port, name, stat, avail);\n\t}\n}\n#endif\n\nsize_t EthernetServer::write(uint8_t b)\n{\n\treturn write(&b, 1);\n}\n\nsize_t EthernetServer::write(const uint8_t *buffer, size_t size)\n{\n\tuint8_t chip, maxindex=MAX_SOCK_NUM;\n\n\tchip = W5100.getChip();\n\tif (!chip) return 0;\n#if MAX_SOCK_NUM > 4\n\tif (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets\n#endif\n\tavailable();\n\tfor (uint8_t i=0; i < maxindex; i++) {\n\t\tif (server_port[i] == _port) {\n\t\t\tif (Ethernet.socketStatus(i) == SnSR::ESTABLISHED) {\n\t\t\t\tEthernet.socketSend(i, buffer, size);\n\t\t\t}\n\t\t}\n\t}\n\treturn size;\n}\n" }, { filename: "src/EthernetServer.h", code: "// This file is in the public domain. No copyright is claimed.\n\n#include \"Ethernet.h\"\n" }, { filename: "src/SPI.cpp", code: "/*\n * Copyright (c) 2010 by Cristian Maglie \n * Copyright (c) 2014 by Paul Stoffregen (Transaction API)\n * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR)\n * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes)\n * SPI Master library for arduino.\n *\n * This file is free software; you can redistribute it and/or modify\n * it under the terms of either the GNU General Public License version 2\n * or the GNU Lesser General Public License version 2.1, both as\n * published by the Free Software Foundation.\n */\n\n#include \"SPI.h\"\n\nSPIClass SPI;\n\nuint8_t SPIClass::initialized = 0;\nuint8_t SPIClass::interruptMode = 0;\nuint8_t SPIClass::interruptMask = 0;\nuint8_t SPIClass::interruptSave = 0;\n#ifdef SPI_TRANSACTION_MISMATCH_LED\nuint8_t SPIClass::inTransactionFlag = 0;\n#endif\n\nvoid SPIClass::begin()\n{\n uint8_t sreg = SREG;\n noInterrupts(); // Protect from a scheduler and prevent transactionBegin\n if (!initialized) {\n // Set SS to high so a connected chip will be \"deselected\" by default\n uint8_t port = digitalPinToPort(SS);\n uint8_t bit = digitalPinToBitMask(SS);\n volatile uint8_t *reg = portModeRegister(port);\n\n // if the SS pin is not already configured as an output\n // then set it high (to enable the internal pull-up resistor)\n if(!(*reg & bit)){\n digitalWrite(SS, HIGH);\n }\n\n // When the SS pin is set as OUTPUT, it can be used as\n // a general purpose output port (it doesn't influence\n // SPI operations).\n pinMode(SS, OUTPUT);\n\n // Warning: if the SS pin ever becomes a LOW INPUT then SPI\n // automatically switches to Slave, so the data direction of\n // the SS pin MUST be kept as OUTPUT.\n SPCR |= _BV(MSTR);\n SPCR |= _BV(SPE);\n\n // Set direction register for SCK and MOSI pin.\n // MISO pin automatically overrides to INPUT.\n // By doing this AFTER enabling SPI, we avoid accidentally\n // clocking in a single bit since the lines go directly\n // from \"input\" to SPI control.\n // http://code.google.com/p/arduino/issues/detail?id=888\n pinMode(SCK, OUTPUT);\n pinMode(MOSI, OUTPUT);\n }\n initialized++; // reference count\n SREG = sreg;\n}\n\nvoid SPIClass::end() {\n uint8_t sreg = SREG;\n noInterrupts(); // Protect from a scheduler and prevent transactionBegin\n // Decrease the reference counter\n if (initialized)\n initialized--;\n // If there are no more references disable SPI\n if (!initialized) {\n SPCR &= ~_BV(SPE);\n interruptMode = 0;\n #ifdef SPI_TRANSACTION_MISMATCH_LED\n inTransactionFlag = 0;\n #endif\n }\n SREG = sreg;\n}\n\n// mapping of interrupt numbers to bits within SPI_AVR_EIMSK\n#if defined(__AVR_ATmega32U4__)\n #define SPI_INT0_MASK (1<\n * Copyright (c) 2014 by Paul Stoffregen (Transaction API)\n * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR)\n * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes)\n * SPI Master library for arduino.\n *\n * This file is free software; you can redistribute it and/or modify\n * it under the terms of either the GNU General Public License version 2\n * or the GNU Lesser General Public License version 2.1, both as\n * published by the Free Software Foundation.\n */\n\n#ifndef _SPI_H_INCLUDED\n#define _SPI_H_INCLUDED\n\n#include \n\n// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),\n// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)\n#define SPI_HAS_TRANSACTION 1\n\n// SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method\n#define SPI_HAS_NOTUSINGINTERRUPT 1\n\n// SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version.\n// This way when there is a bug fix you can check this define to alert users\n// of your code if it uses better version of this library.\n// This also implies everything that SPI_HAS_TRANSACTION as documented above is\n// available too.\n#define SPI_ATOMIC_VERSION 1\n\n// Uncomment this line to add detection of mismatched begin/end transactions.\n// A mismatch occurs if other libraries fail to use SPI.endTransaction() for\n// each SPI.beginTransaction(). Connect an LED to this pin. The LED will turn\n// on if any mismatch is ever detected.\n//#define SPI_TRANSACTION_MISMATCH_LED 5\n\n#ifndef LSBFIRST\n#define LSBFIRST 0\n#endif\n#ifndef MSBFIRST\n#define MSBFIRST 1\n#endif\n\n#define SPI_CLOCK_DIV4 0x00\n#define SPI_CLOCK_DIV16 0x01\n#define SPI_CLOCK_DIV64 0x02\n#define SPI_CLOCK_DIV128 0x03\n#define SPI_CLOCK_DIV2 0x04\n#define SPI_CLOCK_DIV8 0x05\n#define SPI_CLOCK_DIV32 0x06\n\n#define SPI_MODE0 0x00\n#define SPI_MODE1 0x04\n#define SPI_MODE2 0x08\n#define SPI_MODE3 0x0C\n\n#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR\n#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR\n#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR\n\n// define SPI_AVR_EIMSK for AVR boards with external interrupt pins\n#if defined(EIMSK)\n #define SPI_AVR_EIMSK EIMSK\n#elif defined(GICR)\n #define SPI_AVR_EIMSK GICR\n#elif defined(GIMSK)\n #define SPI_AVR_EIMSK GIMSK\n#endif\n\nclass SPISettings {\npublic:\n SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {\n if (__builtin_constant_p(clock)) {\n init_AlwaysInline(clock, bitOrder, dataMode);\n } else {\n init_MightInline(clock, bitOrder, dataMode);\n }\n }\n SPISettings() {\n init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);\n }\nprivate:\n void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {\n init_AlwaysInline(clock, bitOrder, dataMode);\n }\n void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)\n __attribute__((__always_inline__)) {\n // Clock settings are defined as follows. Note that this shows SPI2X\n // inverted, so the bits form increasing numbers. Also note that\n // fosc/64 appears twice\n // SPR1 SPR0 ~SPI2X Freq\n // 0 0 0 fosc/2\n // 0 0 1 fosc/4\n // 0 1 0 fosc/8\n // 0 1 1 fosc/16\n // 1 0 0 fosc/32\n // 1 0 1 fosc/64\n // 1 1 0 fosc/64\n // 1 1 1 fosc/128\n\n // We find the fastest clock that is less than or equal to the\n // given clock rate. The clock divider that results in clock_setting\n // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the\n // slowest (128 == 2 ^^ 7, so clock_div = 6).\n uint8_t clockDiv;\n\n // When the clock is known at compile time, use this if-then-else\n // cascade, which the compiler knows how to completely optimize\n // away. When clock is not known, use a loop instead, which generates\n // shorter code.\n if (__builtin_constant_p(clock)) {\n if (clock >= F_CPU / 2) {\n clockDiv = 0;\n } else if (clock >= F_CPU / 4) {\n clockDiv = 1;\n } else if (clock >= F_CPU / 8) {\n clockDiv = 2;\n } else if (clock >= F_CPU / 16) {\n clockDiv = 3;\n } else if (clock >= F_CPU / 32) {\n clockDiv = 4;\n } else if (clock >= F_CPU / 64) {\n clockDiv = 5;\n } else {\n clockDiv = 6;\n }\n } else {\n uint32_t clockSetting = F_CPU / 2;\n clockDiv = 0;\n while (clockDiv < 6 && clock < clockSetting) {\n clockSetting /= 2;\n clockDiv++;\n }\n }\n\n // Compensate for the duplicate fosc/64\n if (clockDiv == 6)\n clockDiv = 7;\n\n // Invert the SPI2X bit\n clockDiv ^= 0x1;\n\n // Pack into the SPISettings class\n spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) |\n (dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK);\n spsr = clockDiv & SPI_2XCLOCK_MASK;\n }\n uint8_t spcr;\n uint8_t spsr;\n friend class SPIClass;\n};\n\n\nclass SPIClass {\npublic:\n // Initialize the SPI library\n static void begin();\n\n // If SPI is used from within an interrupt, this function registers\n // that interrupt with the SPI library, so beginTransaction() can\n // prevent conflicts. The input interruptNumber is the number used\n // with attachInterrupt. If SPI is used from a different interrupt\n // (eg, a timer), interruptNumber should be 255.\n static void usingInterrupt(uint8_t interruptNumber);\n // And this does the opposite.\n static void notUsingInterrupt(uint8_t interruptNumber);\n // Note: the usingInterrupt and notUsingInterrupt functions should\n // not to be called from ISR context or inside a transaction.\n // For details see:\n // https://github.com/arduino/Arduino/pull/2381\n // https://github.com/arduino/Arduino/pull/2449\n\n // Before using SPI.transfer() or asserting chip select pins,\n // this function is used to gain exclusive access to the SPI bus\n // and configure the correct settings.\n inline static void beginTransaction(SPISettings settings) {\n if (interruptMode > 0) {\n uint8_t sreg = SREG;\n noInterrupts();\n\n #ifdef SPI_AVR_EIMSK\n if (interruptMode == 1) {\n interruptSave = SPI_AVR_EIMSK;\n SPI_AVR_EIMSK &= ~interruptMask;\n SREG = sreg;\n } else\n #endif\n {\n interruptSave = sreg;\n }\n }\n\n #ifdef SPI_TRANSACTION_MISMATCH_LED\n if (inTransactionFlag) {\n pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);\n digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);\n }\n inTransactionFlag = 1;\n #endif\n\n SPCR = settings.spcr;\n SPSR = settings.spsr;\n }\n\n // Write to the SPI bus (MOSI pin) and also receive (MISO pin)\n inline static uint8_t transfer(uint8_t data) {\n SPDR = data;\n /*\n * The following NOP introduces a small delay that can prevent the wait\n * loop form iterating when running at the maximum speed. This gives\n * about 10% more speed, even if it seems counter-intuitive. At lower\n * speeds it is unnoticed.\n */\n asm volatile(\"nop\");\n while (!(SPSR & _BV(SPIF))) ; // wait\n return SPDR;\n }\n inline static uint16_t transfer16(uint16_t data) {\n union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;\n in.val = data;\n if (!(SPCR & _BV(DORD))) {\n SPDR = in.msb;\n asm volatile(\"nop\"); // See transfer(uint8_t) function\n while (!(SPSR & _BV(SPIF))) ;\n out.msb = SPDR;\n SPDR = in.lsb;\n asm volatile(\"nop\");\n while (!(SPSR & _BV(SPIF))) ;\n out.lsb = SPDR;\n } else {\n SPDR = in.lsb;\n asm volatile(\"nop\");\n while (!(SPSR & _BV(SPIF))) ;\n out.lsb = SPDR;\n SPDR = in.msb;\n asm volatile(\"nop\");\n while (!(SPSR & _BV(SPIF))) ;\n out.msb = SPDR;\n }\n return out.val;\n }\n inline static void transfer(void *buf, size_t count) {\n if (count == 0) return;\n uint8_t *p = (uint8_t *)buf;\n SPDR = *p;\n while (--count > 0) {\n uint8_t out = *(p + 1);\n while (!(SPSR & _BV(SPIF))) ;\n uint8_t in = SPDR;\n SPDR = out;\n *p++ = in;\n }\n while (!(SPSR & _BV(SPIF))) ;\n *p = SPDR;\n }\n // After performing a group of transfers and releasing the chip select\n // signal, this function allows others to access the SPI bus\n inline static void endTransaction(void) {\n #ifdef SPI_TRANSACTION_MISMATCH_LED\n if (!inTransactionFlag) {\n pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);\n digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);\n }\n inTransactionFlag = 0;\n #endif\n\n if (interruptMode > 0) {\n #ifdef SPI_AVR_EIMSK\n uint8_t sreg = SREG;\n #endif\n noInterrupts();\n #ifdef SPI_AVR_EIMSK\n if (interruptMode == 1) {\n SPI_AVR_EIMSK = interruptSave;\n SREG = sreg;\n } else\n #endif\n {\n SREG = interruptSave;\n }\n }\n }\n\n // Disable the SPI bus\n static void end();\n\n // This function is deprecated. New applications should use\n // beginTransaction() to configure SPI settings.\n inline static void setBitOrder(uint8_t bitOrder) {\n if (bitOrder == LSBFIRST) SPCR |= _BV(DORD);\n else SPCR &= ~(_BV(DORD));\n }\n // This function is deprecated. New applications should use\n // beginTransaction() to configure SPI settings.\n inline static void setDataMode(uint8_t dataMode) {\n SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;\n }\n // This function is deprecated. New applications should use\n // beginTransaction() to configure SPI settings.\n inline static void setClockDivider(uint8_t clockDiv) {\n SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK);\n SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK);\n }\n // These undocumented functions should not be used. SPI.transfer()\n // polls the hardware flag which is automatically cleared as the\n // AVR responds to SPI's interrupt\n inline static void attachInterrupt() { SPCR |= _BV(SPIE); }\n inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); }\n\nprivate:\n static uint8_t initialized;\n static uint8_t interruptMode; // 0=none, 1=mask, 2=global\n static uint8_t interruptMask; // which interrupts to mask\n static uint8_t interruptSave; // temp storage, to restore state\n #ifdef SPI_TRANSACTION_MISMATCH_LED\n static uint8_t inTransactionFlag;\n #endif\n};\n\nextern SPIClass SPI;\n\n#endif\n" }, { filename: "src/w5100.cpp", code: "/*\n * Copyright 2018 Paul Stoffregen\n * Copyright (c) 2010 by Cristian Maglie \n *\n * This file is free software; you can redistribute it and/or modify\n * it under the terms of either the GNU General Public License version 2\n * or the GNU Lesser General Public License version 2.1, both as\n * published by the Free Software Foundation.\n */\n\n#include \n#include \"Ethernet.h\"\n#include \"w5100.h\"\n\n\n/***************************************************/\n/** Default SS pin setting **/\n/***************************************************/\n\n// If variant.h or other headers specifically define the\n// default SS pin for ethernet, use it.\n#if defined(PIN_SPI_SS_ETHERNET_LIB)\n#define SS_PIN_DEFAULT PIN_SPI_SS_ETHERNET_LIB\n\n// MKR boards default to pin 5 for MKR ETH\n// Pins 8-10 are MOSI/SCK/MISO on MRK, so don't use pin 10\n#elif defined(USE_ARDUINO_MKR_PIN_LAYOUT) || defined(ARDUINO_SAMD_MKRZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWAN1300)\n#define SS_PIN_DEFAULT 5\n\n// For boards using AVR, assume shields with SS on pin 10\n// will be used. This allows for Arduino Mega (where\n// SS is pin 53) and Arduino Leonardo (where SS is pin 17)\n// to work by default with Arduino Ethernet Shield R2 & R3.\n#elif defined(__AVR__)\n#define SS_PIN_DEFAULT 10\n\n// If variant.h or other headers define these names\n// use them if none of the other cases match\n#elif defined(PIN_SPI_SS)\n#define SS_PIN_DEFAULT PIN_SPI_SS\n#elif defined(CORE_SS0_PIN)\n#define SS_PIN_DEFAULT CORE_SS0_PIN\n\n// As a final fallback, use pin 10\n#else\n#define SS_PIN_DEFAULT 10\n#endif\n\n\n\n\n// W5100 controller instance\nuint8_t W5100Class::chip = 0;\nuint8_t W5100Class::CH_BASE_MSB;\nuint8_t W5100Class::ss_pin = SS_PIN_DEFAULT;\n#ifdef ETHERNET_LARGE_BUFFERS\nuint16_t W5100Class::SSIZE = 2048;\nuint16_t W5100Class::SMASK = 0x07FF;\n#endif\nW5100Class W5100;\n\n// pointers and bitmasks for optimized SS pin\n#if defined(__AVR__)\n volatile uint8_t * W5100Class::ss_pin_reg;\n uint8_t W5100Class::ss_pin_mask;\n#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)\n volatile uint8_t * W5100Class::ss_pin_reg;\n#elif defined(__MKL26Z64__)\n volatile uint8_t * W5100Class::ss_pin_reg;\n uint8_t W5100Class::ss_pin_mask;\n#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)\n volatile uint32_t * W5100Class::ss_pin_reg;\n uint32_t W5100Class::ss_pin_mask;\n#elif defined(__PIC32MX__)\n volatile uint32_t * W5100Class::ss_pin_reg;\n uint32_t W5100Class::ss_pin_mask;\n#elif defined(ARDUINO_ARCH_ESP8266)\n volatile uint32_t * W5100Class::ss_pin_reg;\n uint32_t W5100Class::ss_pin_mask;\n#elif defined(__SAMD21G18A__)\n volatile uint32_t * W5100Class::ss_pin_reg;\n uint32_t W5100Class::ss_pin_mask;\n#endif\n\n\nuint8_t W5100Class::init(void)\n{\n\tstatic bool initialized = false;\n\tuint8_t i;\n\n\tif (initialized) return 1;\n\n\t// Many Ethernet shields have a CAT811 or similar reset chip\n\t// connected to W5100 or W5200 chips. The W5200 will not work at\n\t// all, and may even drive its MISO pin, until given an active low\n\t// reset pulse! The CAT811 has a 240 ms typical pulse length, and\n\t// a 400 ms worst case maximum pulse length. MAX811 has a worst\n\t// case maximum 560 ms pulse length. This delay is meant to wait\n\t// until the reset pulse is ended. If your hardware has a shorter\n\t// reset time, this can be edited or removed.\n\tdelay(560);\n\t//Serial.println(\"w5100 init\");\n\n\tSPI.begin();\n\tinitSS();\n\tresetSS();\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\n\t// Attempt W5200 detection first, because W5200 does not properly\n\t// reset its SPI state when CS goes high (inactive). Communication\n\t// from detecting the other chips can leave the W5200 in a state\n\t// where it won't recover, unless given a reset pulse.\n\tif (isW5200()) {\n\t\tCH_BASE_MSB = 0x40;\n#ifdef ETHERNET_LARGE_BUFFERS\n#if MAX_SOCK_NUM <= 1\n\t\tSSIZE = 16384;\n#elif MAX_SOCK_NUM <= 2\n\t\tSSIZE = 8192;\n#elif MAX_SOCK_NUM <= 4\n\t\tSSIZE = 4096;\n#else\n\t\tSSIZE = 2048;\n#endif\n\t\tSMASK = SSIZE - 1;\n#endif\n\t\tfor (i=0; i> 10);\n\t\t\twriteSnTX_SIZE(i, SSIZE >> 10);\n\t\t}\n\t\tfor (; i<8; i++) {\n\t\t\twriteSnRX_SIZE(i, 0);\n\t\t\twriteSnTX_SIZE(i, 0);\n\t\t}\n\t// Try W5500 next. Wiznet finally seems to have implemented\n\t// SPI well with this chip. It appears to be very resilient,\n\t// so try it after the fragile W5200\n\t} else if (isW5500()) {\n\t\tCH_BASE_MSB = 0x10;\n#ifdef ETHERNET_LARGE_BUFFERS\n#if MAX_SOCK_NUM <= 1\n\t\tSSIZE = 16384;\n#elif MAX_SOCK_NUM <= 2\n\t\tSSIZE = 8192;\n#elif MAX_SOCK_NUM <= 4\n\t\tSSIZE = 4096;\n#else\n\t\tSSIZE = 2048;\n#endif\n\t\tSMASK = SSIZE - 1;\n\t\tfor (i=0; i> 10);\n\t\t\twriteSnTX_SIZE(i, SSIZE >> 10);\n\t\t}\n\t\tfor (; i<8; i++) {\n\t\t\twriteSnRX_SIZE(i, 0);\n\t\t\twriteSnTX_SIZE(i, 0);\n\t\t}\n#endif\n\t// Try W5100 last. This simple chip uses fixed 4 byte frames\n\t// for every 8 bit access. Terribly inefficient, but so simple\n\t// it recovers from \"hearing\" unsuccessful W5100 or W5200\n\t// communication. W5100 is also the only chip without a VERSIONR\n\t// register for identification, so we check this last.\n\t} else if (isW5100()) {\n\t\tCH_BASE_MSB = 0x04;\n#ifdef ETHERNET_LARGE_BUFFERS\n#if MAX_SOCK_NUM <= 1\n\t\tSSIZE = 8192;\n\t\twriteTMSR(0x03);\n\t\twriteRMSR(0x03);\n#elif MAX_SOCK_NUM <= 2\n\t\tSSIZE = 4096;\n\t\twriteTMSR(0x0A);\n\t\twriteRMSR(0x0A);\n#else\n\t\tSSIZE = 2048;\n\t\twriteTMSR(0x55);\n\t\twriteRMSR(0x55);\n#endif\n\t\tSMASK = SSIZE - 1;\n#else\n\t\twriteTMSR(0x55);\n\t\twriteRMSR(0x55);\n#endif\n\t// No hardware seems to be present. Or it could be a W5200\n\t// that's heard other SPI communication if its chip select\n\t// pin wasn't high when a SD card or other SPI chip was used.\n\t} else {\n\t\t//Serial.println(\"no chip :-(\");\n\t\tchip = 0;\n\t\tSPI.endTransaction();\n\t\treturn 0; // no known chip is responding :-(\n\t}\n\tSPI.endTransaction();\n\tinitialized = true;\n\treturn 1; // successful init\n}\n\n// Soft reset the Wiznet chip, by writing to its MR register reset bit\nuint8_t W5100Class::softReset(void)\n{\n\tuint16_t count=0;\n\n\t//Serial.println(\"Wiznet soft reset\");\n\t// write to reset bit\n\twriteMR(0x80);\n\t// then wait for soft reset to complete\n\tdo {\n\t\tuint8_t mr = readMR();\n\t\t//Serial.print(\"mr=\");\n\t\t//Serial.println(mr, HEX);\n\t\tif (mr == 0) return 1;\n\t\tdelay(1);\n\t} while (++count < 20);\n\treturn 0;\n}\n\nuint8_t W5100Class::isW5100(void)\n{\n\tchip = 51;\n\t//Serial.println(\"w5100.cpp: detect W5100 chip\");\n\tif (!softReset()) return 0;\n\twriteMR(0x10);\n\tif (readMR() != 0x10) return 0;\n\twriteMR(0x12);\n\tif (readMR() != 0x12) return 0;\n\twriteMR(0x00);\n\tif (readMR() != 0x00) return 0;\n\t//Serial.println(\"chip is W5100\");\n\treturn 1;\n}\n\nuint8_t W5100Class::isW5200(void)\n{\n\tchip = 52;\n\t//Serial.println(\"w5100.cpp: detect W5200 chip\");\n\tif (!softReset()) return 0;\n\twriteMR(0x08);\n\tif (readMR() != 0x08) return 0;\n\twriteMR(0x10);\n\tif (readMR() != 0x10) return 0;\n\twriteMR(0x00);\n\tif (readMR() != 0x00) return 0;\n\tint ver = readVERSIONR_W5200();\n\t//Serial.print(\"version=\");\n\t//Serial.println(ver);\n\tif (ver != 3) return 0;\n\t//Serial.println(\"chip is W5200\");\n\treturn 1;\n}\n\nuint8_t W5100Class::isW5500(void)\n{\n\tchip = 55;\n\t//Serial.println(\"w5100.cpp: detect W5500 chip\");\n\tif (!softReset()) return 0;\n\twriteMR(0x08);\n\tif (readMR() != 0x08) return 0;\n\twriteMR(0x10);\n\tif (readMR() != 0x10) return 0;\n\twriteMR(0x00);\n\tif (readMR() != 0x00) return 0;\n\tint ver = readVERSIONR_W5500();\n\t//Serial.print(\"version=\");\n\t//Serial.println(ver);\n\tif (ver != 4) return 0;\n\t//Serial.println(\"chip is W5500\");\n\treturn 1;\n}\n\nW5100Linkstatus W5100Class::getLinkStatus()\n{\n\tuint8_t phystatus;\n\n\tif (!init()) return UNKNOWN;\n\tswitch (chip) {\n\t case 52:\n\t\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\t\tphystatus = readPSTATUS_W5200();\n\t\tSPI.endTransaction();\n\t\tif (phystatus & 0x20) return LINK_ON;\n\t\treturn LINK_OFF;\n\t case 55:\n\t\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\t\tphystatus = readPHYCFGR_W5500();\n\t\tSPI.endTransaction();\n\t\tif (phystatus & 0x01) return LINK_ON;\n\t\treturn LINK_OFF;\n\t default:\n\t\treturn UNKNOWN;\n\t}\n}\n\nuint16_t W5100Class::write(uint16_t addr, const uint8_t *buf, uint16_t len)\n{\n\tuint8_t cmd[8];\n\n\tif (chip == 51) {\n\t\tfor (uint16_t i=0; i> 8);\n\t\t\tSPI.transfer(addr & 0xFF);\n\t\t\taddr++;\n\t\t\tSPI.transfer(buf[i]);\n\t\t\tresetSS();\n\t\t}\n\t} else if (chip == 52) {\n\t\tsetSS();\n\t\tcmd[0] = addr >> 8;\n\t\tcmd[1] = addr & 0xFF;\n\t\tcmd[2] = ((len >> 8) & 0x7F) | 0x80;\n\t\tcmd[3] = len & 0xFF;\n\t\tSPI.transfer(cmd, 4);\n#ifdef SPI_HAS_TRANSFER_BUF\n\t\tSPI.transfer(buf, NULL, len);\n#else\n\t\t// TODO: copy 8 bytes at a time to cmd[] and block transfer\n\t\tfor (uint16_t i=0; i < len; i++) {\n\t\t\tSPI.transfer(buf[i]);\n\t\t}\n#endif\n\t\tresetSS();\n\t} else { // chip == 55\n\t\tsetSS();\n\t\tif (addr < 0x100) {\n\t\t\t// common registers 00nn\n\t\t\tcmd[0] = 0;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\tcmd[2] = 0x04;\n\t\t} else if (addr < 0x8000) {\n\t\t\t// socket registers 10nn, 11nn, 12nn, 13nn, etc\n\t\t\tcmd[0] = 0;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\tcmd[2] = ((addr >> 3) & 0xE0) | 0x0C;\n\t\t} else if (addr < 0xC000) {\n\t\t\t// transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc\n\t\t\t// 10## #nnn nnnn nnnn\n\t\t\tcmd[0] = addr >> 8;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\t#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1\n\t\t\tcmd[2] = 0x14; // 16K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2\n\t\t\tcmd[2] = ((addr >> 8) & 0x20) | 0x14; // 8K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4\n\t\t\tcmd[2] = ((addr >> 7) & 0x60) | 0x14; // 4K buffers\n\t\t\t#else\n\t\t\tcmd[2] = ((addr >> 6) & 0xE0) | 0x14; // 2K buffers\n\t\t\t#endif\n\t\t} else {\n\t\t\t// receive buffers\n\t\t\tcmd[0] = addr >> 8;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\t#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1\n\t\t\tcmd[2] = 0x1C; // 16K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2\n\t\t\tcmd[2] = ((addr >> 8) & 0x20) | 0x1C; // 8K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4\n\t\t\tcmd[2] = ((addr >> 7) & 0x60) | 0x1C; // 4K buffers\n\t\t\t#else\n\t\t\tcmd[2] = ((addr >> 6) & 0xE0) | 0x1C; // 2K buffers\n\t\t\t#endif\n\t\t}\n\t\tif (len <= 5) {\n\t\t\tfor (uint8_t i=0; i < len; i++) {\n\t\t\t\tcmd[i + 3] = buf[i];\n\t\t\t}\n\t\t\tSPI.transfer(cmd, len + 3);\n\t\t} else {\n\t\t\tSPI.transfer(cmd, 3);\n#ifdef SPI_HAS_TRANSFER_BUF\n\t\t\tSPI.transfer(buf, NULL, len);\n#else\n\t\t\t// TODO: copy 8 bytes at a time to cmd[] and block transfer\n\t\t\tfor (uint16_t i=0; i < len; i++) {\n\t\t\t\tSPI.transfer(buf[i]);\n\t\t\t}\n#endif\n\t\t}\n\t\tresetSS();\n\t}\n\treturn len;\n}\n\nuint16_t W5100Class::read(uint16_t addr, uint8_t *buf, uint16_t len)\n{\n\tuint8_t cmd[4];\n\n\tif (chip == 51) {\n\t\tfor (uint16_t i=0; i < len; i++) {\n\t\t\tsetSS();\n\t\t\t#if 1\n\t\t\tSPI.transfer(0x0F);\n\t\t\tSPI.transfer(addr >> 8);\n\t\t\tSPI.transfer(addr & 0xFF);\n\t\t\taddr++;\n\t\t\tbuf[i] = SPI.transfer(0);\n\t\t\t#else\n\t\t\tcmd[0] = 0x0F;\n\t\t\tcmd[1] = addr >> 8;\n\t\t\tcmd[2] = addr & 0xFF;\n\t\t\tcmd[3] = 0;\n\t\t\tSPI.transfer(cmd, 4); // TODO: why doesn't this work?\n\t\t\tbuf[i] = cmd[3];\n\t\t\taddr++;\n\t\t\t#endif\n\t\t\tresetSS();\n\t\t}\n\t} else if (chip == 52) {\n\t\tsetSS();\n\t\tcmd[0] = addr >> 8;\n\t\tcmd[1] = addr & 0xFF;\n\t\tcmd[2] = (len >> 8) & 0x7F;\n\t\tcmd[3] = len & 0xFF;\n\t\tSPI.transfer(cmd, 4);\n\t\tmemset(buf, 0, len);\n\t\tSPI.transfer(buf, len);\n\t\tresetSS();\n\t} else { // chip == 55\n\t\tsetSS();\n\t\tif (addr < 0x100) {\n\t\t\t// common registers 00nn\n\t\t\tcmd[0] = 0;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\tcmd[2] = 0x00;\n\t\t} else if (addr < 0x8000) {\n\t\t\t// socket registers 10nn, 11nn, 12nn, 13nn, etc\n\t\t\tcmd[0] = 0;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\tcmd[2] = ((addr >> 3) & 0xE0) | 0x08;\n\t\t} else if (addr < 0xC000) {\n\t\t\t// transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc\n\t\t\t// 10## #nnn nnnn nnnn\n\t\t\tcmd[0] = addr >> 8;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\t#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1\n\t\t\tcmd[2] = 0x10; // 16K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2\n\t\t\tcmd[2] = ((addr >> 8) & 0x20) | 0x10; // 8K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4\n\t\t\tcmd[2] = ((addr >> 7) & 0x60) | 0x10; // 4K buffers\n\t\t\t#else\n\t\t\tcmd[2] = ((addr >> 6) & 0xE0) | 0x10; // 2K buffers\n\t\t\t#endif\n\t\t} else {\n\t\t\t// receive buffers\n\t\t\tcmd[0] = addr >> 8;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\t#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1\n\t\t\tcmd[2] = 0x18; // 16K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2\n\t\t\tcmd[2] = ((addr >> 8) & 0x20) | 0x18; // 8K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4\n\t\t\tcmd[2] = ((addr >> 7) & 0x60) | 0x18; // 4K buffers\n\t\t\t#else\n\t\t\tcmd[2] = ((addr >> 6) & 0xE0) | 0x18; // 2K buffers\n\t\t\t#endif\n\t\t}\n\t\tSPI.transfer(cmd, 3);\n\t\tmemset(buf, 0, len);\n\t\tSPI.transfer(buf, len);\n\t\tresetSS();\n\t}\n\treturn len;\n}\n\nvoid W5100Class::execCmdSn(SOCKET s, SockCMD _cmd)\n{\n\t// Send command to socket\n\twriteSnCR(s, _cmd);\n\t// Wait for command to complete\n\twhile (readSnCR(s)) ;\n}\n" }, { filename: "src/w5100.h", code: "/*\n * Copyright 2018 Paul Stoffregen\n * Copyright (c) 2010 by Cristian Maglie \n *\n * This file is free software; you can redistribute it and/or modify\n * it under the terms of either the GNU General Public License version 2\n * or the GNU Lesser General Public License version 2.1, both as\n * published by the Free Software Foundation.\n */\n\n// w5100.h contains private W5x00 hardware \"driver\" level definitions\n// which are not meant to be exposed to other libraries or Arduino users\n\n#ifndef\tW5100_H_INCLUDED\n#define\tW5100_H_INCLUDED\n\n#include \n#include \n\n// Safe for all chips\n#define SPI_ETHERNET_SETTINGS SPISettings(14000000, MSBFIRST, SPI_MODE0)\n\n// Safe for W5200 and W5500, but too fast for W5100\n// Uncomment this if you know you'll never need W5100 support.\n// Higher SPI clock only results in faster transfer to hosts on a LAN\n// or with very low packet latency. With ordinary internet latency,\n// the TCP window size & packet loss determine your overall speed.\n//#define SPI_ETHERNET_SETTINGS SPISettings(30000000, MSBFIRST, SPI_MODE0)\n\n\n// Require Ethernet.h, because we need MAX_SOCK_NUM\n#ifndef ethernet_h_\n#error \"Ethernet.h must be included before w5100.h\"\n#endif\n\n\n// Arduino 101's SPI can not run faster than 8 MHz.\n#if defined(ARDUINO_ARCH_ARC32)\n#undef SPI_ETHERNET_SETTINGS\n#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE0)\n#endif\n\n// Arduino Zero can't use W5100-based shields faster than 8 MHz\n// https://github.com/arduino-libraries/Ethernet/issues/37#issuecomment-408036848\n// W5500 does seem to work at 12 MHz. Delete this if only using W5500\n#if defined(__SAMD21G18A__)\n#undef SPI_ETHERNET_SETTINGS\n#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE0)\n#endif\n\n\ntypedef uint8_t SOCKET;\n\nclass SnMR {\npublic:\n static const uint8_t CLOSE = 0x00;\n static const uint8_t TCP = 0x21;\n static const uint8_t UDP = 0x02;\n static const uint8_t IPRAW = 0x03;\n static const uint8_t MACRAW = 0x04;\n static const uint8_t PPPOE = 0x05;\n static const uint8_t ND = 0x20;\n static const uint8_t MULTI = 0x80;\n};\n\nenum SockCMD {\n Sock_OPEN = 0x01,\n Sock_LISTEN = 0x02,\n Sock_CONNECT = 0x04,\n Sock_DISCON = 0x08,\n Sock_CLOSE = 0x10,\n Sock_SEND = 0x20,\n Sock_SEND_MAC = 0x21,\n Sock_SEND_KEEP = 0x22,\n Sock_RECV = 0x40\n};\n\nclass SnIR {\npublic:\n static const uint8_t SEND_OK = 0x10;\n static const uint8_t TIMEOUT = 0x08;\n static const uint8_t RECV = 0x04;\n static const uint8_t DISCON = 0x02;\n static const uint8_t CON = 0x01;\n};\n\nclass SnSR {\npublic:\n static const uint8_t CLOSED = 0x00;\n static const uint8_t INIT = 0x13;\n static const uint8_t LISTEN = 0x14;\n static const uint8_t SYNSENT = 0x15;\n static const uint8_t SYNRECV = 0x16;\n static const uint8_t ESTABLISHED = 0x17;\n static const uint8_t FIN_WAIT = 0x18;\n static const uint8_t CLOSING = 0x1A;\n static const uint8_t TIME_WAIT = 0x1B;\n static const uint8_t CLOSE_WAIT = 0x1C;\n static const uint8_t LAST_ACK = 0x1D;\n static const uint8_t UDP = 0x22;\n static const uint8_t IPRAW = 0x32;\n static const uint8_t MACRAW = 0x42;\n static const uint8_t PPPOE = 0x5F;\n};\n\nclass IPPROTO {\npublic:\n static const uint8_t IP = 0;\n static const uint8_t ICMP = 1;\n static const uint8_t IGMP = 2;\n static const uint8_t GGP = 3;\n static const uint8_t TCP = 6;\n static const uint8_t PUP = 12;\n static const uint8_t UDP = 17;\n static const uint8_t IDP = 22;\n static const uint8_t ND = 77;\n static const uint8_t RAW = 255;\n};\n\nenum W5100Linkstatus {\n UNKNOWN,\n LINK_ON,\n LINK_OFF\n};\n\nclass W5100Class {\n\npublic:\n static uint8_t init(void);\n\n inline void setGatewayIp(const uint8_t * addr) { writeGAR(addr); }\n inline void getGatewayIp(uint8_t * addr) { readGAR(addr); }\n\n inline void setSubnetMask(const uint8_t * addr) { writeSUBR(addr); }\n inline void getSubnetMask(uint8_t * addr) { readSUBR(addr); }\n\n inline void setMACAddress(const uint8_t * addr) { writeSHAR(addr); }\n inline void getMACAddress(uint8_t * addr) { readSHAR(addr); }\n\n inline void setIPAddress(const uint8_t * addr) { writeSIPR(addr); }\n inline void getIPAddress(uint8_t * addr) { readSIPR(addr); }\n\n inline void setRetransmissionTime(uint16_t timeout) { writeRTR(timeout); }\n inline void setRetransmissionCount(uint8_t retry) { writeRCR(retry); }\n\n static void execCmdSn(SOCKET s, SockCMD _cmd);\n\n\n // W5100 Registers\n // ---------------\n//private:\npublic:\n static uint16_t write(uint16_t addr, const uint8_t *buf, uint16_t len);\n static uint8_t write(uint16_t addr, uint8_t data) {\n return write(addr, &data, 1);\n }\n static uint16_t read(uint16_t addr, uint8_t *buf, uint16_t len);\n static uint8_t read(uint16_t addr) {\n uint8_t data;\n read(addr, &data, 1);\n return data;\n }\n\n#define __GP_REGISTER8(name, address) \\\n static inline void write##name(uint8_t _data) { \\\n write(address, _data); \\\n } \\\n static inline uint8_t read##name() { \\\n return read(address); \\\n }\n#define __GP_REGISTER16(name, address) \\\n static void write##name(uint16_t _data) { \\\n uint8_t buf[2]; \\\n buf[0] = _data >> 8; \\\n buf[1] = _data & 0xFF; \\\n write(address, buf, 2); \\\n } \\\n static uint16_t read##name() { \\\n uint8_t buf[2]; \\\n read(address, buf, 2); \\\n return (buf[0] << 8) | buf[1]; \\\n }\n#define __GP_REGISTER_N(name, address, size) \\\n static uint16_t write##name(const uint8_t *_buff) { \\\n return write(address, _buff, size); \\\n } \\\n static uint16_t read##name(uint8_t *_buff) { \\\n return read(address, _buff, size); \\\n }\n static W5100Linkstatus getLinkStatus();\n\npublic:\n __GP_REGISTER8 (MR, 0x0000); // Mode\n __GP_REGISTER_N(GAR, 0x0001, 4); // Gateway IP address\n __GP_REGISTER_N(SUBR, 0x0005, 4); // Subnet mask address\n __GP_REGISTER_N(SHAR, 0x0009, 6); // Source MAC address\n __GP_REGISTER_N(SIPR, 0x000F, 4); // Source IP address\n __GP_REGISTER8 (IR, 0x0015); // Interrupt\n __GP_REGISTER8 (IMR, 0x0016); // Interrupt Mask\n __GP_REGISTER16(RTR, 0x0017); // Timeout address\n __GP_REGISTER8 (RCR, 0x0019); // Retry count\n __GP_REGISTER8 (RMSR, 0x001A); // Receive memory size (W5100 only)\n __GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size (W5100 only)\n __GP_REGISTER8 (PATR, 0x001C); // Authentication type address in PPPoE mode\n __GP_REGISTER8 (PTIMER, 0x0028); // PPP LCP Request Timer\n __GP_REGISTER8 (PMAGIC, 0x0029); // PPP LCP Magic Number\n __GP_REGISTER_N(UIPR, 0x002A, 4); // Unreachable IP address in UDP mode (W5100 only)\n __GP_REGISTER16(UPORT, 0x002E); // Unreachable Port address in UDP mode (W5100 only)\n __GP_REGISTER8 (VERSIONR_W5200,0x001F); // Chip Version Register (W5200 only)\n __GP_REGISTER8 (VERSIONR_W5500,0x0039); // Chip Version Register (W5500 only)\n __GP_REGISTER8 (PSTATUS_W5200, 0x0035); // PHY Status\n __GP_REGISTER8 (PHYCFGR_W5500, 0x002E); // PHY Configuration register, default: 10111xxx\n\n\n#undef __GP_REGISTER8\n#undef __GP_REGISTER16\n#undef __GP_REGISTER_N\n\n // W5100 Socket registers\n // ----------------------\nprivate:\n static uint16_t CH_BASE(void) {\n //if (chip == 55) return 0x1000;\n //if (chip == 52) return 0x4000;\n //return 0x0400;\n return CH_BASE_MSB << 8;\n }\n static uint8_t CH_BASE_MSB; // 1 redundant byte, saves ~80 bytes code on AVR\n static const uint16_t CH_SIZE = 0x0100;\n\n static inline uint8_t readSn(SOCKET s, uint16_t addr) {\n return read(CH_BASE() + s * CH_SIZE + addr);\n }\n static inline uint8_t writeSn(SOCKET s, uint16_t addr, uint8_t data) {\n return write(CH_BASE() + s * CH_SIZE + addr, data);\n }\n static inline uint16_t readSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len) {\n return read(CH_BASE() + s * CH_SIZE + addr, buf, len);\n }\n static inline uint16_t writeSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len) {\n return write(CH_BASE() + s * CH_SIZE + addr, buf, len);\n }\n\n#define __SOCKET_REGISTER8(name, address) \\\n static inline void write##name(SOCKET _s, uint8_t _data) { \\\n writeSn(_s, address, _data); \\\n } \\\n static inline uint8_t read##name(SOCKET _s) { \\\n return readSn(_s, address); \\\n }\n#define __SOCKET_REGISTER16(name, address) \\\n static void write##name(SOCKET _s, uint16_t _data) { \\\n uint8_t buf[2]; \\\n buf[0] = _data >> 8; \\\n buf[1] = _data & 0xFF; \\\n writeSn(_s, address, buf, 2); \\\n } \\\n static uint16_t read##name(SOCKET _s) { \\\n uint8_t buf[2]; \\\n readSn(_s, address, buf, 2); \\\n return (buf[0] << 8) | buf[1]; \\\n }\n#define __SOCKET_REGISTER_N(name, address, size) \\\n static uint16_t write##name(SOCKET _s, uint8_t *_buff) { \\\n return writeSn(_s, address, _buff, size); \\\n } \\\n static uint16_t read##name(SOCKET _s, uint8_t *_buff) { \\\n return readSn(_s, address, _buff, size); \\\n }\n\npublic:\n __SOCKET_REGISTER8(SnMR, 0x0000) // Mode\n __SOCKET_REGISTER8(SnCR, 0x0001) // Command\n __SOCKET_REGISTER8(SnIR, 0x0002) // Interrupt\n __SOCKET_REGISTER8(SnSR, 0x0003) // Status\n __SOCKET_REGISTER16(SnPORT, 0x0004) // Source Port\n __SOCKET_REGISTER_N(SnDHAR, 0x0006, 6) // Destination Hardw Addr\n __SOCKET_REGISTER_N(SnDIPR, 0x000C, 4) // Destination IP Addr\n __SOCKET_REGISTER16(SnDPORT, 0x0010) // Destination Port\n __SOCKET_REGISTER16(SnMSSR, 0x0012) // Max Segment Size\n __SOCKET_REGISTER8(SnPROTO, 0x0014) // Protocol in IP RAW Mode\n __SOCKET_REGISTER8(SnTOS, 0x0015) // IP TOS\n __SOCKET_REGISTER8(SnTTL, 0x0016) // IP TTL\n __SOCKET_REGISTER8(SnRX_SIZE, 0x001E) // RX Memory Size (W5200 only)\n __SOCKET_REGISTER8(SnTX_SIZE, 0x001F) // RX Memory Size (W5200 only)\n __SOCKET_REGISTER16(SnTX_FSR, 0x0020) // TX Free Size\n __SOCKET_REGISTER16(SnTX_RD, 0x0022) // TX Read Pointer\n __SOCKET_REGISTER16(SnTX_WR, 0x0024) // TX Write Pointer\n __SOCKET_REGISTER16(SnRX_RSR, 0x0026) // RX Free Size\n __SOCKET_REGISTER16(SnRX_RD, 0x0028) // RX Read Pointer\n __SOCKET_REGISTER16(SnRX_WR, 0x002A) // RX Write Pointer (supported?)\n\n#undef __SOCKET_REGISTER8\n#undef __SOCKET_REGISTER16\n#undef __SOCKET_REGISTER_N\n\n\nprivate:\n static uint8_t chip;\n static uint8_t ss_pin;\n static uint8_t softReset(void);\n static uint8_t isW5100(void);\n static uint8_t isW5200(void);\n static uint8_t isW5500(void);\n\npublic:\n static uint8_t getChip(void) { return chip; }\n#ifdef ETHERNET_LARGE_BUFFERS\n static uint16_t SSIZE;\n static uint16_t SMASK;\n#else\n static const uint16_t SSIZE = 2048;\n static const uint16_t SMASK = 0x07FF;\n#endif\n static uint16_t SBASE(uint8_t socknum) {\n if (chip == 51) {\n return socknum * SSIZE + 0x4000;\n } else {\n return socknum * SSIZE + 0x8000;\n }\n }\n static uint16_t RBASE(uint8_t socknum) {\n if (chip == 51) {\n return socknum * SSIZE + 0x6000;\n } else {\n return socknum * SSIZE + 0xC000;\n }\n }\n\n static bool hasOffsetAddressMapping(void) {\n if (chip == 55) return true;\n return false;\n }\n static void setSS(uint8_t pin) { ss_pin = pin; }\n\nprivate:\n#if defined(__AVR__)\n\tstatic volatile uint8_t *ss_pin_reg;\n\tstatic uint8_t ss_pin_mask;\n\tinline static void initSS() {\n\t\tss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin));\n\t\tss_pin_mask = digitalPinToBitMask(ss_pin);\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\t*(ss_pin_reg) &= ~ss_pin_mask;\n\t}\n\tinline static void resetSS() {\n\t\t*(ss_pin_reg) |= ss_pin_mask;\n\t}\n#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)\n\tstatic volatile uint8_t *ss_pin_reg;\n\tinline static void initSS() {\n\t\tss_pin_reg = portOutputRegister(ss_pin);\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\t*(ss_pin_reg+256) = 1;\n\t}\n\tinline static void resetSS() {\n\t\t*(ss_pin_reg+128) = 1;\n\t}\n#elif defined(__MKL26Z64__)\n\tstatic volatile uint8_t *ss_pin_reg;\n\tstatic uint8_t ss_pin_mask;\n\tinline static void initSS() {\n\t\tss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin));\n\t\tss_pin_mask = digitalPinToBitMask(ss_pin);\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\t*(ss_pin_reg+8) = ss_pin_mask;\n\t}\n\tinline static void resetSS() {\n\t\t*(ss_pin_reg+4) = ss_pin_mask;\n\t}\n#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)\n\tstatic volatile uint32_t *ss_pin_reg;\n\tstatic uint32_t ss_pin_mask;\n\tinline static void initSS() {\n\t\tss_pin_reg = &(digitalPinToPort(ss_pin)->PIO_PER);\n\t\tss_pin_mask = digitalPinToBitMask(ss_pin);\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\t*(ss_pin_reg+13) = ss_pin_mask;\n\t}\n\tinline static void resetSS() {\n\t\t*(ss_pin_reg+12) = ss_pin_mask;\n\t}\n#elif defined(__PIC32MX__)\n\tstatic volatile uint32_t *ss_pin_reg;\n\tstatic uint32_t ss_pin_mask;\n\tinline static void initSS() {\n\t\tss_pin_reg = portModeRegister(digitalPinToPort(ss_pin));\n\t\tss_pin_mask = digitalPinToBitMask(ss_pin);\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\t*(ss_pin_reg+8+1) = ss_pin_mask;\n\t}\n\tinline static void resetSS() {\n\t\t*(ss_pin_reg+8+2) = ss_pin_mask;\n\t}\n\n#elif defined(ARDUINO_ARCH_ESP8266)\n\tstatic volatile uint32_t *ss_pin_reg;\n\tstatic uint32_t ss_pin_mask;\n\tinline static void initSS() {\n\t\tss_pin_reg = (volatile uint32_t*)GPO;\n\t\tss_pin_mask = 1 << ss_pin;\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\tGPOC = ss_pin_mask;\n\t}\n\tinline static void resetSS() {\n\t\tGPOS = ss_pin_mask;\n\t}\n\n#elif defined(__SAMD21G18A__)\n\tstatic volatile uint32_t *ss_pin_reg;\n\tstatic uint32_t ss_pin_mask;\n\tinline static void initSS() {\n\t\tss_pin_reg = portModeRegister(digitalPinToPort(ss_pin));\n\t\tss_pin_mask = digitalPinToBitMask(ss_pin);\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\t*(ss_pin_reg+5) = ss_pin_mask;\n\t}\n\tinline static void resetSS() {\n\t\t*(ss_pin_reg+6) = ss_pin_mask;\n\t}\n#else\n\tinline static void initSS() {\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\tdigitalWrite(ss_pin, LOW);\n\t}\n\tinline static void resetSS() {\n\t\tdigitalWrite(ss_pin, HIGH);\n\t}\n#endif\n};\n\nextern W5100Class W5100;\n\n\n\n#endif\n\n#ifndef UTIL_H\n#define UTIL_H\n\n#define htons(x) ( (((x)<<8)&0xFF00) | (((x)>>8)&0xFF) )\n#define ntohs(x) htons(x)\n\n#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \\\n ((x)<< 8 & 0x00FF0000UL) | \\\n ((x)>> 8 & 0x0000FF00UL) | \\\n ((x)>>24 & 0x000000FFUL) )\n#define ntohl(x) htonl(x)\n\n#endif\n" }] }; const extFacePanels = {}; const ExtHandler = { onLoad: function onLoad(app, target) { const that = this; if (!that.__workerSetupInstance) { that.__workerSetupInstance = that.workerSetup({ app }).then(() => { that.worker.remote.runExtension('onLoad', target.id); }); } }, onUnload: function onUnload(app) { this.__workerSetupInstance = null; this.worker.remote.runExtension('onUnload'); this.worker.dispose(); }, onConnect: function onConnect(app, device) { this.worker.remote.runExtension('onConnect', device.id); }, onDisconnect: function onDisconnect(app, device) { this.worker.remote.runExtension('onDisconnect', device.id); }, onStopAll: function onStopAll(app, device) { this.worker.remote.runExtension('onStopAll', device.id); }, beforeChangeUploadMode: function beforeChangeUploadMode(app, device) { return this.worker.remote.runExtension('beforeChangeUploadMode', device.id); }, beforeChangeDebugMode: function beforeChangeDebugMode(app, device) { return this.worker.remote.runExtension('beforeChangeDebugMode', device.id); }, afterChangeUploadMode: function afterChangeUploadMode(app, device) { this.worker.remote.runExtension('afterChangeUploadMode', device.id); }, afterChangeDebugMode: function afterChangeDebugMode(app, device) { this.worker.remote.runExtension('afterChangeDebugMode', device.id); }, onSelect: function onSelect(app, device) { if (!this.worker) { setTimeout(() => { this.onSelect(app, device); }, 200); return; } this.worker.remote.runExtension('onSelect', device.id); }, onUnselect: function onUnselect(app, device) { this.worker.remote.runExtension('onUnselect', device.id); }, beforeCodeUpload: function beforeCodeUpload(app, device) { this.worker.remote.runExtension('beforeCodeUpload', device.id); }, afterCodeUpload: function afterCodeUpload(app, device) { this.worker.remote.runExtension('afterCodeUpload', device.id); }, onRead: function onRead(app, device) { this.worker.remote.runExtension('onRead', device.id); }, beforeFirmwareUpdate: function beforeFirmwareUpdate(app, device) { this.worker.remote.runExtension('beforeFirmwareUpdate', device.id); }, afterFirmwareUpdate: function afterFirmwareUpdate(app, device) { this.worker.remote.runExtension('afterFirmwareUpdate', device.id); } }; class ExtVdrEthernetShield { constructor() { this.checkFirmwareInForce = typeof checkFirmwareInForce !== 'undefined' ? checkFirmwareInForce : false; const handlerProxyUrl = window.MbApi.getExtResPath('vdr_ethernet_shield/handlerProxy.js', 'vdr_ethernet_shield'); const that = this; that.workerSetup = async function (exports) { that.worker = await window.__web_worker_rpc.create(handlerProxyUrl, exports).then(worker => { worker.CONFIG.TIMEOUT = 42000; worker.CONFIG.HEARTBEAT = 4200; worker.onFail = () => { that.worker = null; that.workerSetup(exports); const app = exports.app; if (app) { app.workspace.resetEvents(); } }; return worker; }); }; this.funcs = { 'BLOCK_1653780308718': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653780308718', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1675367642335': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1675367642335', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653780309012': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653780309012', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653780309457': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653780309457', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1654274936853': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1654274936853', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653780309804': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653780309804', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653780310011': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653780310011', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1654273986221': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1654273986221', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653855510926': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653855510926', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653780310978': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653780310978', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653780311427': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653780311427', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653780311846': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653780311846', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653780311631': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653780311631', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653780312072': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653780312072', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } }, 'BLOCK_1653780312304': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock('BLOCK_1653780312304', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args)); } } }; } getInfo() { return { "id": "vdr_ethernet_shield", "targets": [{ "name": "arduino_mega2560", "options": { "upload": { "middlewares": [{ "name": "arduino", "params": { "sources": extSources.arduino } }] } } }, { "name": "arduino_uno", "options": { "upload": { "middlewares": [{ "name": "arduino", "params": { "sources": extSources.arduino } }] } } }], "codeTypes": ["arduinoc"], "version": "1.0.0", "platform": ["mblockpc"], "categories": [{ "name": "cate_a6db9026", "colors": ["#05A6FF", "#0097EA", "#0086D0"], "menuIconURI": "", "blockIcon": { "type": "image", "width": 28, "height": 26, "src": window.MbApi.getExtResPath('vdr_ethernet_shield/imgs/c6ed8de0c5964a5fa3964e968e7a6466.png', 'vdr_ethernet_shield') }, "blocks": [{ "opcode": "BLOCK_1653780308718", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "arguments": {}, "branchCount": 1, "codes": { "arduinoc": { "sections": { "include": ["\"src/SPI.h\"", "\"src/Ethernet.h\""], "declare": `#define DEBUG true\r\nEthernetClient client;\r\nbool firstParam=true;;\r\nbool ethSucceed=false;\r\n\r\nvoid receiveData(){\r\n String reponse=\"\";\r\n while (client.connected()){\r\n while (client.available()){\r\n char c = client.read();\r\n reponse += c;\r\n }\r\n }\r\n if (!client.connected()) client.stop();\r\n if(DEBUG) Serial.println(reponse);\r\n}\r\n\r\nvoid ethGetData(){\r\n String reponse=\"\";\r\n ethSucceed = false ;\r\n if (client.find(\"200 OK\")){\r\n ethSucceed = true;\r\n }\r\n client.find(\"\\r\\n\\r\\n\");\r\n while (client.available()){\r\n char c = client.read();\r\n reponse += c;\r\n }\r\n if (!client.connected()) client.stop();\r\n}\r\n\r\nvoid ethernetInitialise(){\r\n byte ethMac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };\r\n\r\n ethSucceed = false ;\r\n if (DEBUG){\r\n Serial.println();\r\n Serial.print(F(\"Set IP...\"));\r\n }\r\n\r\n /*{$BRANCH1}*/ \r\n\r\n \r\n if (DEBUG){\r\n if(ethSucceed) Serial.println(F(\"OK\")); else Serial.println(F(\"Failed\"));\r\n Serial.println(Ethernet.localIP());\r\n }\r\n}` } } }, "handler": this.funcs.BLOCK_1653780308718 }, { "opcode": "BLOCK_1675367642335", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": {}, "branchCount": 0, "codes": { "arduinoc": { "code": `ethSucceed = Ethernet.begin(ethMac);` } }, "handler": this.funcs.BLOCK_1675367642335 }, { "opcode": "BLOCK_1653780309012", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "IP": { "type": "string", "defaultValue": "172.16.112.50" }, "Mask": { "type": "string", "defaultValue": "255.255.240.0" }, "Gateway": { "type": "string", "defaultValue": "172.16.112.254" }, "DNS": { "type": "string", "defaultValue": "172.16.128.1" } }, "branchCount": 0, "codes": { "arduinoc": { "code": `IPAddress ethIP;\r\nIPAddress ethDNS;\r\nIPAddress ethGateway;\r\nIPAddress ethMask;\r\n\r\nethIP.fromString(/*{IP}*/);\r\nethMask.fromString(/*{Mask}*/);\r\nethGateway.fromString(/*{Gateway}*/);\r\nethDNS.fromString(/*{DNS}*/);\r\n\r\nEthernet.begin(ethMac, ethIP, ethDNS, ethGateway, ethMask);\r\nethSucceed = (Ethernet.localIP() == ethIP);\r\n\r` } }, "handler": this.funcs.BLOCK_1653780309012 }, { "opcode": "BLOCK_1653780309457", "blockType": "string", "checkboxInFlyout": false, "gap": 12, "arguments": { "IP": { "type": "fieldMenu", "defaultValue": "0", "menu": "BLOCK_1653780309457_IP" } }, "branchCount": 0, "codes": { "arduinoc": { "code": `ethGetIP(/*{IP}*/)`, "sections": { "declare": `String ethGetIP(int type){\r\n IPAddress ethIP;\r\n switch (type) {\r\n case 0:\r\n ethIP=Ethernet.localIP();\r\n break;\r\n case 1:\r\n ethIP=Ethernet.dnsServerIP();\r\n break;\r\n case 2:\r\n ethIP=Ethernet.gatewayIP();\r\n break;\r\n case 3:\r\n ethIP=Ethernet.subnetMask();\r\n break;\r\n }\r\n String ip;\r\n ip = ethIP[0];\r\n ip +=\".\";\r\n ip += ethIP[1];\r\n ip +=\".\";\r\n ip += ethIP[2];\r\n ip +=\".\";\r\n ip += ethIP[3];\r\n return ip;\r\n}` } } }, "handler": this.funcs.BLOCK_1653780309457 }, { "opcode": "BLOCK_1654274936853", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": {}, "branchCount": 0, "codes": { "arduinoc": { "code": `ethernetInitialise();` } }, "handler": this.funcs.BLOCK_1654274936853 }, { "opcode": "BLOCK_1653780309804", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "champ": { "type": "string", "defaultValue": "" }, "valeur": { "type": "string", "defaultValue": "" } }, "branchCount": 0, "codes": { "arduinoc": { "code": `HttpData(/*{champ}*/,/*{valeur}*/);` } }, "handler": this.funcs.BLOCK_1653780309804 }, { "opcode": "BLOCK_1653780310011", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "arguments": { "server": { "type": "string", "defaultValue": "api.thingspeak.com" }, "page": { "type": "string", "defaultValue": "/update" } }, "branchCount": 1, "codes": { "arduinoc": { "code": `httpRequest(/*{server}*/, /*{page}*/);`, "sections": { "declare": `/*\r\nvoid AddHttpData(String field, String value){\r\n if (firstParam){\r\n ethRequest=\"\";\r\n }else{\r\n ethRequest=ethRequest+\"&\";\r\n }\r\n ethRequest=ethRequest+field+\"=\"+value;\r\n firstParam=false;\r\n}\r\n*/\r\n\r\nvoid HttpData(String field, String value){\r\n if (firstParam){\r\n client.print(field+\"=\"+value);\r\n firstParam=false;\r\n }else{\r\n client.print(\"&\"+field+\"=\"+value);\r\n }\r\n}\r\n\r\nvoid httpRequest(String strServer, String page){\r\n char server[strServer.length()+1];\r\n strServer.toCharArray(server,strServer.length()+1);\r\n if (DEBUG) Serial.print(F(\"Con. serveur...\"));\r\n ethSucceed = client.connect(server,80);\r\n if (DEBUG){\r\n if(ethSucceed) Serial.println(F(\"OK\")); else Serial.println(F(\"Failed\"));\r\n }\r\n if (DEBUG) Serial.print(F(\"Envoyer...\"));\r\n if(ethSucceed){\r\n ethSucceed = false;\r\n \r\n /*\r\n if (/*{POST}*/){\r\n \r\n client.print(F(\"POST \"));\r\n client.print(page);\r\n client.println(F(\" HTTP/1.1\"));\r\n client.print(F(\"Host: \"));\r\n client.println(strServer);\r\n client.println(F(\"Content-Type: application/x-www-form-urlencoded\"));\r\n client.println(F(\"Connection: close\"));\r\n client.println(F(\"User-Agent: Arduino/1.0\"));\r\n client.print(F(\"Content-Length: \"));\r\n client.println(ethRequest.length());\r\n client.println();\r\n client.println(ethRequest);\r\n client.println();\r\n }else{\r\n */ \r\n client.print(F(\"GET \"));\r\n client.print(page + \"?\");\r\n /*{$BRANCH1}*/\r\n client.println(F(\" HTTP/1.1\"));\r\n client.print(F(\"Host: \"));\r\n client.println(strServer);\r\n client.println(F(\"User-Agent: arduino-ethernet\"));\r\n client.println(F(\"Connection: close\"));\r\n client.println();\r\n //}\r\n ethGetData();\r\n }\r\n firstParam=true;\r\n if (DEBUG){\r\n if(ethSucceed){\r\n Serial.println(F(\"OK\")); \r\n }else{\r\n Serial.println(F(\"Failed\"));\r\n }\r\n Serial.print(F(\"reçu...\"));\r\n }\r\n}` } } }, "handler": this.funcs.BLOCK_1653780310011 }, { "opcode": "BLOCK_1654273986221", "blockType": "boolean", "checkboxInFlyout": false, "gap": 12, "arguments": {}, "branchCount": 0, "codes": { "arduinoc": { "code": `ethSucceed` } }, "handler": this.funcs.BLOCK_1654273986221 }, { "opcode": "BLOCK_1653855510926", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "port": { "type": "number", "defaultValue": 80 } }, "branchCount": 0, "codes": { "arduinoc": { "code": `ethernetInitialise();\r\nserver.begin();\r\ndelay(1000);`, "sections": { "declare": `EthernetServer server(/*{port}*/);` } } }, "handler": this.funcs.BLOCK_1653855510926 }, { "opcode": "BLOCK_1653780310978", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "arguments": { "titre": { "type": "string", "defaultValue": "titre" }, "refresh": { "type": "fieldMenu", "defaultValue": "0", "menu": "BLOCK_1653780310978_REFRESH" } }, "branchCount": 1, "codes": { "arduinoc": { "code": `while(1){\r\n EthernetClient Wclient;\r\n Wclient = server.available();\r\n if (Wclient) {\r\n while (Wclient.connected()) { \r\n if (Wclient.available()) {\r\n char c = Wclient.read();\r\n String ethRequest;\r\n if (ethRequest.length() < 100) {\r\n ethRequest += c; \r\n }\r\n if (c == '\\n') {\r\n _loop();\r\n\r\n Wclient.println(F(\"HTTP/1.1 200 OK\")); //send new page\r\n Wclient.println(F(\"Content-Type: text/html\"));\r\n if(/*{refresh}*/>0){\r\n Wclient.print(F(\"Refresh: \"));\r\n Wclient.println(String(/*{refresh}*/));\r\n }\r\n Wclient.println();\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n Wclient.print(F(\"\"));\r\n Wclient.print(String(/*{titre}*/));\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n\r\n /*{$BRANCH1}*/ \r\n\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n \r\n ethRequest = \"\";\r\n delay(1);\r\n Wclient.stop();\r\n }\r\n }\r\n }\r\n }\r\n}` } }, "handler": this.funcs.BLOCK_1653780310978 }, { "opcode": "BLOCK_1653780311427", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "texte": { "type": "string", "defaultValue": "" }, "style": { "type": "fieldMenu", "defaultValue": "p", "menu": "BLOCK_1653780311427_STYLE" } }, "branchCount": 0, "codes": { "arduinoc": { "code": `Wclient.print(F(\"\"));\r\nWclient.print(String(/*{texte}*/));\r\nWclient.println(F(\"\"));` } }, "handler": this.funcs.BLOCK_1653780311427 }, { "opcode": "BLOCK_1653780311846", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "arguments": { "texte": { "type": "string", "defaultValue": "" }, "action": { "type": "string", "defaultValue": "" } }, "branchCount": 1, "codes": { "arduinoc": { "code": `Wclient.print(F(\"\"));\r\nWclient.print(String(/*{texte}*/));\r\nWclient.print(F(\"\"));`, "sections": { "_loop": `if (ethRequest.indexOf(\"?\"+String(/*{action}*/)) >0){\r\n /*{$BRANCH1}*/ \r\n}` } } }, "handler": this.funcs.BLOCK_1653780311846 }, { "opcode": "BLOCK_1653780311631", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": {}, "branchCount": 0, "codes": { "arduinoc": { "code": `Wclient.println(F(\"
\"));` } }, "handler": this.funcs.BLOCK_1653780311631 }, { "opcode": "BLOCK_1653780312072", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "texte": { "type": "string", "defaultValue": "" }, "url": { "type": "string", "defaultValue": "http://" } }, "branchCount": 0, "codes": { "arduinoc": { "code": `Wclient.print(F(\"\"));\r\nWclient.print(String(/*{texte}*/));\r\nWclient.println(F(\"\"));` } }, "handler": this.funcs.BLOCK_1653780312072 }, { "opcode": "BLOCK_1653780312304", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "code": { "type": "string", "defaultValue": "" } }, "branchCount": 0, "codes": { "arduinoc": { "code": `Wclient.print(String(/*{code}*/));` } }, "handler": this.funcs.BLOCK_1653780312304 }], "menus": { "BLOCK_1653780309457_IP": [{ "text": "BLOCK_1653780309457_IP_0", "value": "0" }, { "text": "BLOCK_1653780309457_IP_1", "value": "1" }, { "text": "BLOCK_1653780309457_IP_2", "value": "2" }, { "text": "BLOCK_1653780309457_IP_3", "value": "3" }], "BLOCK_1653780310978_REFRESH": [{ "text": "BLOCK_1653780310978_REFRESH_0", "value": "0" }, { "text": "BLOCK_1653780310978_REFRESH_1", "value": "5" }, { "text": "BLOCK_1653780310978_REFRESH_2", "value": "10" }, { "text": "BLOCK_1653780310978_REFRESH_3", "value": "30" }], "BLOCK_1653780311427_STYLE": [{ "text": "BLOCK_1653780311427_STYLE_0", "value": "p" }, { "text": "BLOCK_1653780311427_STYLE_1", "value": "H1" }, { "text": "BLOCK_1653780311427_STYLE_2", "value": "H2" }] } }], "generators": extGenerators, "translationMap": extTranslationMap, "snippets": codeSnippets, "generatorStartBlocks": [], "feature": ["worker"], "mustLoginBlocks": [], "disabledOffline": [], "disabledOnline": [] }; } getHandler() { if (typeof ExtHandler === 'object') { return ExtHandler; } else if (typeof ExtHandler === 'function') { return new ExtHandler(); } } } var _default = ExtVdrEthernetShield; _exports.default = _default; });PK BV;X6X6handlerProxy.js"use strict";function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg),value=info.value}catch(error){return void reject(error)}info.done?resolve(value):Promise.resolve(value).then(_next,_throw)}function _asyncToGenerator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}var gen=fn.apply(self,args);_next(void 0)})}}function _instanceof(left,right){return null!=right&&"undefined"!=typeof Symbol&&right[Symbol.hasInstance]?!!right[Symbol.hasInstance](left):left instanceof right}function _typeof(obj){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(obj){return typeof obj}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj},_typeof(obj)}self.rpc.CONFIG.TIMEOUT=42e3,self.rpc.CONFIG.HEARTBEAT=4200;var __context={app:self.rpc.remote.app,getDevice:function(deviceId){return new Proxy({},{get:function get(target,name){return"id"==name?deviceId:function(){for(var runDevice=__context.app.runDevice,_len=arguments.length,args=Array(_len),_key=0;_key<_len;_key++)args[_key]=arguments[_key];return runDevice.apply(void 0,[deviceId,name].concat(args))}}})}};!function(global){"use strict";function wrap(innerFn,outerFn,self,tryLocsList){var protoGenerator=outerFn&&_instanceof(outerFn.prototype,Generator)?outerFn:Generator,generator=Object.create(protoGenerator.prototype),context=new Context(tryLocsList||[]);return generator._invoke=makeInvokeMethod(innerFn,self,context),generator}function tryCatch(fn,obj,arg){try{return{type:"normal",arg:fn.call(obj,arg)}}catch(err){return{type:"throw",arg:err}}}function Generator(){}function GeneratorFunction(){}function GeneratorFunctionPrototype(){}function defineIteratorMethods(prototype){["next","throw","return"].forEach(function(method){prototype[method]=function(arg){return this._invoke(method,arg)}})}function AsyncIterator(generator){function invoke(method,arg,resolve,reject){var record=tryCatch(generator[method],generator,arg);if("throw"===record.type)reject(record.arg);else{var result=record.arg,value=result.value;return value&&"object"===_typeof(value)&&hasOwn.call(value,"__await")?Promise.resolve(value.__await).then(function(value){invoke("next",value,resolve,reject)},function(err){invoke("throw",err,resolve,reject)}):Promise.resolve(value).then(function(unwrapped){result.value=unwrapped,resolve(result)},function(error){return invoke("throw",error,resolve,reject)})}}function enqueue(method,arg){function callInvokeWithMethodAndArg(){return new Promise(function(resolve,reject){invoke(method,arg,resolve,reject)})}return previousPromise=previousPromise?previousPromise.then(callInvokeWithMethodAndArg,callInvokeWithMethodAndArg):callInvokeWithMethodAndArg()}var previousPromise;this._invoke=enqueue}function makeInvokeMethod(innerFn,self,context){var state="suspendedStart";return function(method,arg){if(state==="executing")throw new Error("Generator is already running");if("completed"===state){if("throw"===method)throw arg;return doneResult()}for(context.method=method,context.arg=arg;;){var delegate=context.delegate;if(delegate){var delegateResult=maybeInvokeDelegate(delegate,context);if(delegateResult){if(delegateResult===ContinueSentinel)continue;return delegateResult}}if("next"===context.method)context.sent=context._sent=context.arg;else if("throw"===context.method){if("suspendedStart"===state)throw state="completed",context.arg;context.dispatchException(context.arg)}else"return"===context.method&&context.abrupt("return",context.arg);state="executing";var record=tryCatch(innerFn,self,context);if("normal"===record.type){if(state=context.done?"completed":"suspendedYield",record.arg===ContinueSentinel)continue;return{value:record.arg,done:context.done}}"throw"===record.type&&(state="completed",context.method="throw",context.arg=record.arg)}}}function maybeInvokeDelegate(delegate,context){var method=delegate.iterator[context.method];if(void 0===method){if(context.delegate=null,"throw"===context.method){if(delegate.iterator.return&&(context.method="return",context.arg=void 0,maybeInvokeDelegate(delegate,context),"throw"===context.method))return ContinueSentinel;context.method="throw",context.arg=new TypeError("The iterator does not provide a 'throw' method")}return ContinueSentinel}var record=tryCatch(method,delegate.iterator,context.arg);if("throw"===record.type)return context.method="throw",context.arg=record.arg,context.delegate=null,ContinueSentinel;var info=record.arg;if(!info)return context.method="throw",context.arg=new TypeError("iterator result is not an object"),context.delegate=null,ContinueSentinel;if(info.done)context[delegate.resultName]=info.value,context.next=delegate.nextLoc,"return"!==context.method&&(context.method="next",context.arg=void 0);else return info;return context.delegate=null,ContinueSentinel}function pushTryEntry(locs){var entry={tryLoc:locs[0]};1 in locs&&(entry.catchLoc=locs[1]),2 in locs&&(entry.finallyLoc=locs[2],entry.afterLoc=locs[3]),this.tryEntries.push(entry)}function resetTryEntry(entry){var record=entry.completion||{};record.type="normal",delete record.arg,entry.completion=record}function Context(tryLocsList){this.tryEntries=[{tryLoc:"root"}],tryLocsList.forEach(pushTryEntry,this),this.reset(!0)}function values(iterable){if(iterable){var iteratorMethod=iterable[iteratorSymbol];if(iteratorMethod)return iteratorMethod.call(iterable);if("function"==typeof iterable.next)return iterable;if(!isNaN(iterable.length)){var i=-1,next=function next(){for(;++i= 0; --i) { var entry = this.tryEntries[i]; var record = entry.completion; if (entry.tryLoc === "root") { return handle("end") } if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"); var hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true) } else if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc) } } else if (hasCatch) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true) } } else if (hasFinally) { if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc) } } else { throw new Error("try statement without catch or finally") } } } }, abrupt: function(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break } } if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { finallyEntry = null } var record = finallyEntry ? finallyEntry.completion : {}; record.type = type; record.arg = arg; if (finallyEntry) { this.method = "next"; this.next = finallyEntry.finallyLoc; return ContinueSentinel } return this.complete(record) }, complete: function(record, afterLoc) { if (record.type === "throw") { throw record.arg } if (record.type === "break" || record.type === "continue") { this.next = record.arg } else if (record.type === "return") { this.rval = this.arg = record.arg; this.method = "return"; this.next = "end" } else if (record.type === "normal" && afterLoc) { this.next = afterLoc } return ContinueSentinel }, finish: function(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) { this.complete(entry.completion, entry.afterLoc); resetTryEntry(entry); return ContinueSentinel } } }, "catch": function(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if (record.type === "throw") { var thrown = record.arg; resetTryEntry(entry) } return thrown } } throw new Error("illegal catch attempt") }, delegateYield: function(iterable, resultName, nextLoc) { this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }; if (this.method === "next") { this.arg = undefined } return ContinueSentinel } } }(function() { return this || typeof self === "object" && self }() || Function("return this")()); // enter your javascript code here const disableBlocks = { debug: [], upload: [] }; const mustLoginBlocks = []; const triggerBlocksStatus = async (mode, app) => {} class ExtVdrEthernetShield { constructor() { this.funcs = { 'BLOCK_1653780308718': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653780308718', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1675367642335': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1675367642335', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653780309012': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653780309012', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653780309457': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653780309457', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1654274936853': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1654274936853', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653780309804': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653780309804', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653780310011': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653780310011', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1654273986221': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1654273986221', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653855510926': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653855510926', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653780310978': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653780310978', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653780311427': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653780311427', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653780311846': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653780311846', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653780311631': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653780311631', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653780312072': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653780312072', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } }, 'BLOCK_1653780312304': { onRun: (args, app, device, block) => { return this.worker.remote.runBlock( 'BLOCK_1653780312304', 'onRun', device.id, { id: block.id, opcode: block.opcode, arguments: block.arguments }, Object.assign({}, args) ); } } }; } getInfo() { return { "id": "vdr_ethernet_shield", "targets": [{ "name": "arduino_mega2560", "options": { "upload": { "middlewares": [{ "name": "arduino", "params": { "sources": extSources.arduino } }] } } }, { "name": "arduino_uno", "options": { "upload": { "middlewares": [{ "name": "arduino", "params": { "sources": extSources.arduino } }] } } } ], "codeTypes": [ "arduinoc" ], "version": "1.0.0", "platform": [ "mblockpc" ], "categories": cates(facepanels), "generators": extGenerators, "translationMap": extTranslationMap, "snippets": codeSnippets, "generatorStartBlocks": [], "feature": [ "worker" ], "mustLoginBlocks": [], "disabledOffline": [], "disabledOnline": [] }; } getHandler() { if (typeof extHandler === 'object') { return extHandler; } else if (typeof extHandler === 'function') { return new extHandler(); } } } export default ExtVdrEthernetShield;PK BV"v&&src/snippets.jsexport default [ "arduinoc: {}" ];PK BVI~src/generators.jsexport default [({ lang: 'arduinoc', template: `// generated by mBlock5 for // codes make you happy //( include //) #include //( lib //) //({ this.$ALL_VARIABLES.length==0?'':this.$ALL_VARIABLES.map(v=>"float "+v+" = 0;").join('\\n') }//) //( declare //) void _delay(float seconds) { long endTime = millis() + seconds * 1000; while(millis() < endTime) _loop(); } //( void setup() { //( setup //) //( code //) } //) void _loop() { //( _loop //) } void loop() { _loop(); }`, splitor: { frame: { left: "//(", right: "//)", }, expression: { left: "/*{", right: "}*/", } }, reducers: [{ name: 'include', reduce: (codes) => { let codes1 = [] for (let code of codes) { let codeStr = ''; if (typeof code === 'string') { codeStr = code; } else if (typeof code === 'function') { codeStr = code(); } if (codes1.indexOf(codeStr) === -1) { codes1.push(codeStr); } } if (codes1.length === 0) { return undefined; } return codes1.map(code => { return '#include ' + code; }).join('\n') + '\n' } }] })];PK BV_asrc/arduinosources.jsexport default [ "{ filename: \"src/Dhcp.cpp\", code: \"// DHCP Library v0.3 - April 25, 2009\\n// Author: Jordan Terrell - blog.jordanterrell.com\\n\\n#include \\n#include \\\"Ethernet.h\\\"\\n#include \\\"Dhcp.h\\\"\\n#include \\\"w5100.h\\\"\\n\\nint DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)\\n{\\n\\t_dhcpLeaseTime=0;\\n\\t_dhcpT1=0;\\n\\t_dhcpT2=0;\\n\\t_timeout = timeout;\\n\\t_responseTimeout = responseTimeout;\\n\\n\\t// zero out _dhcpMacAddr\\n\\tmemset(_dhcpMacAddr, 0, 6);\\n\\treset_DHCP_lease();\\n\\n\\tmemcpy((void*)_dhcpMacAddr, (void*)mac, 6);\\n\\t_dhcp_state = STATE_DHCP_START;\\n\\treturn request_DHCP_lease();\\n}\\n\\nvoid DhcpClass::reset_DHCP_lease()\\n{\\n\\t// zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp\\n\\tmemset(_dhcpLocalIp, 0, 20);\\n}\\n\\n\\t//return:0 on error, 1 if request is sent and response is received\\nint DhcpClass::request_DHCP_lease()\\n{\\n\\tuint8_t messageType = 0;\\n\\n\\t// Pick an initial transaction ID\\n\\t_dhcpTransactionId = random(1UL, 2000UL);\\n\\t_dhcpInitialTransactionId = _dhcpTransactionId;\\n\\n\\t_dhcpUdpSocket.stop();\\n\\tif (_dhcpUdpSocket.begin(DHCP_CLIENT_PORT) == 0) {\\n\\t\\t// Couldn't get a socket\\n\\t\\treturn 0;\\n\\t}\\n\\n\\tpresend_DHCP();\\n\\n\\tint result = 0;\\n\\n\\tunsigned long startTime = millis();\\n\\n\\twhile (_dhcp_state != STATE_DHCP_LEASED) {\\n\\t\\tif (_dhcp_state == STATE_DHCP_START) {\\n\\t\\t\\t_dhcpTransactionId++;\\n\\t\\t\\tsend_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000));\\n\\t\\t\\t_dhcp_state = STATE_DHCP_DISCOVER;\\n\\t\\t} else if (_dhcp_state == STATE_DHCP_REREQUEST) {\\n\\t\\t\\t_dhcpTransactionId++;\\n\\t\\t\\tsend_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000));\\n\\t\\t\\t_dhcp_state = STATE_DHCP_REQUEST;\\n\\t\\t} else if (_dhcp_state == STATE_DHCP_DISCOVER) {\\n\\t\\t\\tuint32_t respId;\\n\\t\\t\\tmessageType = parseDHCPResponse(_responseTimeout, respId);\\n\\t\\t\\tif (messageType == DHCP_OFFER) {\\n\\t\\t\\t\\t// We'll use the transaction ID that the offer came with,\\n\\t\\t\\t\\t// rather than the one we were up to\\n\\t\\t\\t\\t_dhcpTransactionId = respId;\\n\\t\\t\\t\\tsend_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));\\n\\t\\t\\t\\t_dhcp_state = STATE_DHCP_REQUEST;\\n\\t\\t\\t}\\n\\t\\t} else if (_dhcp_state == STATE_DHCP_REQUEST) {\\n\\t\\t\\tuint32_t respId;\\n\\t\\t\\tmessageType = parseDHCPResponse(_responseTimeout, respId);\\n\\t\\t\\tif (messageType == DHCP_ACK) {\\n\\t\\t\\t\\t_dhcp_state = STATE_DHCP_LEASED;\\n\\t\\t\\t\\tresult = 1;\\n\\t\\t\\t\\t//use default lease time if we didn't get it\\n\\t\\t\\t\\tif (_dhcpLeaseTime == 0) {\\n\\t\\t\\t\\t\\t_dhcpLeaseTime = DEFAULT_LEASE;\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\t// Calculate T1 & T2 if we didn't get it\\n\\t\\t\\t\\tif (_dhcpT1 == 0) {\\n\\t\\t\\t\\t\\t// T1 should be 50% of _dhcpLeaseTime\\n\\t\\t\\t\\t\\t_dhcpT1 = _dhcpLeaseTime >> 1;\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tif (_dhcpT2 == 0) {\\n\\t\\t\\t\\t\\t// T2 should be 87.5% (7/8ths) of _dhcpLeaseTime\\n\\t\\t\\t\\t\\t_dhcpT2 = _dhcpLeaseTime - (_dhcpLeaseTime >> 3);\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\t_renewInSec = _dhcpT1;\\n\\t\\t\\t\\t_rebindInSec = _dhcpT2;\\n\\t\\t\\t} else if (messageType == DHCP_NAK) {\\n\\t\\t\\t\\t_dhcp_state = STATE_DHCP_START;\\n\\t\\t\\t}\\n\\t\\t}\\n\\n\\t\\tif (messageType == 255) {\\n\\t\\t\\tmessageType = 0;\\n\\t\\t\\t_dhcp_state = STATE_DHCP_START;\\n\\t\\t}\\n\\n\\t\\tif (result != 1 && ((millis() - startTime) > _timeout))\\n\\t\\t\\tbreak;\\n\\t}\\n\\n\\t// We're done with the socket now\\n\\t_dhcpUdpSocket.stop();\\n\\t_dhcpTransactionId++;\\n\\n\\t_lastCheckLeaseMillis = millis();\\n\\treturn result;\\n}\\n\\nvoid DhcpClass::presend_DHCP()\\n{\\n}\\n\\nvoid DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed)\\n{\\n\\tuint8_t buffer[32];\\n\\tmemset(buffer, 0, 32);\\n\\tIPAddress dest_addr(255, 255, 255, 255); // Broadcast address\\n\\n\\tif (_dhcpUdpSocket.beginPacket(dest_addr, DHCP_SERVER_PORT) == -1) {\\n\\t\\t//Serial.printf(\\\"DHCP transmit error\\\\n\\\");\\n\\t\\t// FIXME Need to return errors\\n\\t\\treturn;\\n\\t}\\n\\n\\tbuffer[0] = DHCP_BOOTREQUEST; // op\\n\\tbuffer[1] = DHCP_HTYPE10MB; // htype\\n\\tbuffer[2] = DHCP_HLENETHERNET; // hlen\\n\\tbuffer[3] = DHCP_HOPS; // hops\\n\\n\\t// xid\\n\\tunsigned long xid = htonl(_dhcpTransactionId);\\n\\tmemcpy(buffer + 4, &(xid), 4);\\n\\n\\t// 8, 9 - seconds elapsed\\n\\tbuffer[8] = ((secondsElapsed & 0xff00) >> 8);\\n\\tbuffer[9] = (secondsElapsed & 0x00ff);\\n\\n\\t// flags\\n\\tunsigned short flags = htons(DHCP_FLAGSBROADCAST);\\n\\tmemcpy(buffer + 10, &(flags), 2);\\n\\n\\t// ciaddr: already zeroed\\n\\t// yiaddr: already zeroed\\n\\t// siaddr: already zeroed\\n\\t// giaddr: already zeroed\\n\\n\\t//put data in W5100 transmit buffer\\n\\t_dhcpUdpSocket.write(buffer, 28);\\n\\n\\tmemset(buffer, 0, 32); // clear local buffer\\n\\n\\tmemcpy(buffer, _dhcpMacAddr, 6); // chaddr\\n\\n\\t//put data in W5100 transmit buffer\\n\\t_dhcpUdpSocket.write(buffer, 16);\\n\\n\\tmemset(buffer, 0, 32); // clear local buffer\\n\\n\\t// leave zeroed out for sname && file\\n\\t// put in W5100 transmit buffer x 6 (192 bytes)\\n\\n\\tfor(int i = 0; i < 6; i++) {\\n\\t\\t_dhcpUdpSocket.write(buffer, 32);\\n\\t}\\n\\n\\t// OPT - Magic Cookie\\n\\tbuffer[0] = (uint8_t)((MAGIC_COOKIE >> 24)& 0xFF);\\n\\tbuffer[1] = (uint8_t)((MAGIC_COOKIE >> 16)& 0xFF);\\n\\tbuffer[2] = (uint8_t)((MAGIC_COOKIE >> 8)& 0xFF);\\n\\tbuffer[3] = (uint8_t)(MAGIC_COOKIE& 0xFF);\\n\\n\\t// OPT - message type\\n\\tbuffer[4] = dhcpMessageType;\\n\\tbuffer[5] = 0x01;\\n\\tbuffer[6] = messageType; //DHCP_REQUEST;\\n\\n\\t// OPT - client identifier\\n\\tbuffer[7] = dhcpClientIdentifier;\\n\\tbuffer[8] = 0x07;\\n\\tbuffer[9] = 0x01;\\n\\tmemcpy(buffer + 10, _dhcpMacAddr, 6);\\n\\n\\t// OPT - host name\\n\\tbuffer[16] = hostName;\\n\\tbuffer[17] = strlen(HOST_NAME) + 6; // length of hostname + last 3 bytes of mac address\\n\\tstrcpy((char*)&(buffer[18]), HOST_NAME);\\n\\n\\tprintByte((char*)&(buffer[24]), _dhcpMacAddr[3]);\\n\\tprintByte((char*)&(buffer[26]), _dhcpMacAddr[4]);\\n\\tprintByte((char*)&(buffer[28]), _dhcpMacAddr[5]);\\n\\n\\t//put data in W5100 transmit buffer\\n\\t_dhcpUdpSocket.write(buffer, 30);\\n\\n\\tif (messageType == DHCP_REQUEST) {\\n\\t\\tbuffer[0] = dhcpRequestedIPaddr;\\n\\t\\tbuffer[1] = 0x04;\\n\\t\\tbuffer[2] = _dhcpLocalIp[0];\\n\\t\\tbuffer[3] = _dhcpLocalIp[1];\\n\\t\\tbuffer[4] = _dhcpLocalIp[2];\\n\\t\\tbuffer[5] = _dhcpLocalIp[3];\\n\\n\\t\\tbuffer[6] = dhcpServerIdentifier;\\n\\t\\tbuffer[7] = 0x04;\\n\\t\\tbuffer[8] = _dhcpDhcpServerIp[0];\\n\\t\\tbuffer[9] = _dhcpDhcpServerIp[1];\\n\\t\\tbuffer[10] = _dhcpDhcpServerIp[2];\\n\\t\\tbuffer[11] = _dhcpDhcpServerIp[3];\\n\\n\\t\\t//put data in W5100 transmit buffer\\n\\t\\t_dhcpUdpSocket.write(buffer, 12);\\n\\t}\\n\\n\\tbuffer[0] = dhcpParamRequest;\\n\\tbuffer[1] = 0x06;\\n\\tbuffer[2] = subnetMask;\\n\\tbuffer[3] = routersOnSubnet;\\n\\tbuffer[4] = dns;\\n\\tbuffer[5] = domainName;\\n\\tbuffer[6] = dhcpT1value;\\n\\tbuffer[7] = dhcpT2value;\\n\\tbuffer[8] = endOption;\\n\\n\\t//put data in W5100 transmit buffer\\n\\t_dhcpUdpSocket.write(buffer, 9);\\n\\n\\t_dhcpUdpSocket.endPacket();\\n}\\n\\nuint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId)\\n{\\n\\tuint8_t type = 0;\\n\\tuint8_t opt_len = 0;\\n\\n\\tunsigned long startTime = millis();\\n\\n\\twhile (_dhcpUdpSocket.parsePacket() <= 0) {\\n\\t\\tif ((millis() - startTime) > responseTimeout) {\\n\\t\\t\\treturn 255;\\n\\t\\t}\\n\\t\\tdelay(50);\\n\\t}\\n\\t// start reading in the packet\\n\\tRIP_MSG_FIXED fixedMsg;\\n\\t_dhcpUdpSocket.read((uint8_t*)&fixedMsg, sizeof(RIP_MSG_FIXED));\\n\\n\\tif (fixedMsg.op == DHCP_BOOTREPLY && _dhcpUdpSocket.remotePort() == DHCP_SERVER_PORT) {\\n\\t\\ttransactionId = ntohl(fixedMsg.xid);\\n\\t\\tif (memcmp(fixedMsg.chaddr, _dhcpMacAddr, 6) != 0 ||\\n\\t\\t (transactionId < _dhcpInitialTransactionId) ||\\n\\t\\t (transactionId > _dhcpTransactionId)) {\\n\\t\\t\\t// Need to read the rest of the packet here regardless\\n\\t\\t\\t_dhcpUdpSocket.flush(); // FIXME\\n\\t\\t\\treturn 0;\\n\\t\\t}\\n\\n\\t\\tmemcpy(_dhcpLocalIp, fixedMsg.yiaddr, 4);\\n\\n\\t\\t// Skip to the option part\\n\\t\\t_dhcpUdpSocket.read((uint8_t *)NULL, 240 - (int)sizeof(RIP_MSG_FIXED));\\n\\n\\t\\twhile (_dhcpUdpSocket.available() > 0) {\\n\\t\\t\\tswitch (_dhcpUdpSocket.read()) {\\n\\t\\t\\tcase endOption :\\n\\t\\t\\t\\tbreak;\\n\\n\\t\\t\\tcase padOption :\\n\\t\\t\\t\\tbreak;\\n\\n\\t\\t\\tcase dhcpMessageType :\\n\\t\\t\\t\\topt_len = _dhcpUdpSocket.read();\\n\\t\\t\\t\\ttype = _dhcpUdpSocket.read();\\n\\t\\t\\t\\tbreak;\\n\\n\\t\\t\\tcase subnetMask :\\n\\t\\t\\t\\topt_len = _dhcpUdpSocket.read();\\n\\t\\t\\t\\t_dhcpUdpSocket.read(_dhcpSubnetMask, 4);\\n\\t\\t\\t\\tbreak;\\n\\n\\t\\t\\tcase routersOnSubnet :\\n\\t\\t\\t\\topt_len = _dhcpUdpSocket.read();\\n\\t\\t\\t\\t_dhcpUdpSocket.read(_dhcpGatewayIp, 4);\\n\\t\\t\\t\\t_dhcpUdpSocket.read((uint8_t *)NULL, opt_len - 4);\\n\\t\\t\\t\\tbreak;\\n\\n\\t\\t\\tcase dns :\\n\\t\\t\\t\\topt_len = _dhcpUdpSocket.read();\\n\\t\\t\\t\\t_dhcpUdpSocket.read(_dhcpDnsServerIp, 4);\\n\\t\\t\\t\\t_dhcpUdpSocket.read((uint8_t *)NULL, opt_len - 4);\\n\\t\\t\\t\\tbreak;\\n\\n\\t\\t\\tcase dhcpServerIdentifier :\\n\\t\\t\\t\\topt_len = _dhcpUdpSocket.read();\\n\\t\\t\\t\\tif ( IPAddress(_dhcpDhcpServerIp) == IPAddress((uint32_t)0) ||\\n\\t\\t\\t\\t IPAddress(_dhcpDhcpServerIp) == _dhcpUdpSocket.remoteIP() ) {\\n\\t\\t\\t\\t\\t_dhcpUdpSocket.read(_dhcpDhcpServerIp, sizeof(_dhcpDhcpServerIp));\\n\\t\\t\\t\\t} else {\\n\\t\\t\\t\\t\\t// Skip over the rest of this option\\n\\t\\t\\t\\t\\t_dhcpUdpSocket.read((uint8_t *)NULL, opt_len);\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tbreak;\\n\\n\\t\\t\\tcase dhcpT1value :\\n\\t\\t\\t\\topt_len = _dhcpUdpSocket.read();\\n\\t\\t\\t\\t_dhcpUdpSocket.read((uint8_t*)&_dhcpT1, sizeof(_dhcpT1));\\n\\t\\t\\t\\t_dhcpT1 = ntohl(_dhcpT1);\\n\\t\\t\\t\\tbreak;\\n\\n\\t\\t\\tcase dhcpT2value :\\n\\t\\t\\t\\topt_len = _dhcpUdpSocket.read();\\n\\t\\t\\t\\t_dhcpUdpSocket.read((uint8_t*)&_dhcpT2, sizeof(_dhcpT2));\\n\\t\\t\\t\\t_dhcpT2 = ntohl(_dhcpT2);\\n\\t\\t\\t\\tbreak;\\n\\n\\t\\t\\tcase dhcpIPaddrLeaseTime :\\n\\t\\t\\t\\topt_len = _dhcpUdpSocket.read();\\n\\t\\t\\t\\t_dhcpUdpSocket.read((uint8_t*)&_dhcpLeaseTime, sizeof(_dhcpLeaseTime));\\n\\t\\t\\t\\t_dhcpLeaseTime = ntohl(_dhcpLeaseTime);\\n\\t\\t\\t\\t_renewInSec = _dhcpLeaseTime;\\n\\t\\t\\t\\tbreak;\\n\\n\\t\\t\\tdefault :\\n\\t\\t\\t\\topt_len = _dhcpUdpSocket.read();\\n\\t\\t\\t\\t// Skip over the rest of this option\\n\\t\\t\\t\\t_dhcpUdpSocket.read((uint8_t *)NULL, opt_len);\\n\\t\\t\\t\\tbreak;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\t// Need to skip to end of the packet regardless here\\n\\t_dhcpUdpSocket.flush(); // FIXME\\n\\n\\treturn type;\\n}\\n\\n\\n/*\\n returns:\\n 0/DHCP_CHECK_NONE: nothing happened\\n 1/DHCP_CHECK_RENEW_FAIL: renew failed\\n 2/DHCP_CHECK_RENEW_OK: renew success\\n 3/DHCP_CHECK_REBIND_FAIL: rebind fail\\n 4/DHCP_CHECK_REBIND_OK: rebind success\\n*/\\nint DhcpClass::checkLease()\\n{\\n\\tint rc = DHCP_CHECK_NONE;\\n\\n\\tunsigned long now = millis();\\n\\tunsigned long elapsed = now - _lastCheckLeaseMillis;\\n\\n\\t// if more then one sec passed, reduce the counters accordingly\\n\\tif (elapsed >= 1000) {\\n\\t\\t// set the new timestamps\\n\\t\\t_lastCheckLeaseMillis = now - (elapsed % 1000);\\n\\t\\telapsed = elapsed / 1000;\\n\\n\\t\\t// decrease the counters by elapsed seconds\\n\\t\\t// we assume that the cycle time (elapsed) is fairly constant\\n\\t\\t// if the remainder is less than cycle time * 2\\n\\t\\t// do it early instead of late\\n\\t\\tif (_renewInSec < elapsed * 2) {\\n\\t\\t\\t_renewInSec = 0;\\n\\t\\t} else {\\n\\t\\t\\t_renewInSec -= elapsed;\\n\\t\\t}\\n\\t\\tif (_rebindInSec < elapsed * 2) {\\n\\t\\t\\t_rebindInSec = 0;\\n\\t\\t} else {\\n\\t\\t\\t_rebindInSec -= elapsed;\\n\\t\\t}\\n\\t}\\n\\n\\t// if we have a lease but should renew, do it\\n\\tif (_renewInSec == 0 &&_dhcp_state == STATE_DHCP_LEASED) {\\n\\t\\t_dhcp_state = STATE_DHCP_REREQUEST;\\n\\t\\trc = 1 + request_DHCP_lease();\\n\\t}\\n\\n\\t// if we have a lease or is renewing but should bind, do it\\n\\tif (_rebindInSec == 0 && (_dhcp_state == STATE_DHCP_LEASED ||\\n\\t _dhcp_state == STATE_DHCP_START)) {\\n\\t\\t// this should basically restart completely\\n\\t\\t_dhcp_state = STATE_DHCP_START;\\n\\t\\treset_DHCP_lease();\\n\\t\\trc = 3 + request_DHCP_lease();\\n\\t}\\n\\treturn rc;\\n}\\n\\nIPAddress DhcpClass::getLocalIp()\\n{\\n\\treturn IPAddress(_dhcpLocalIp);\\n}\\n\\nIPAddress DhcpClass::getSubnetMask()\\n{\\n\\treturn IPAddress(_dhcpSubnetMask);\\n}\\n\\nIPAddress DhcpClass::getGatewayIp()\\n{\\n\\treturn IPAddress(_dhcpGatewayIp);\\n}\\n\\nIPAddress DhcpClass::getDhcpServerIp()\\n{\\n\\treturn IPAddress(_dhcpDhcpServerIp);\\n}\\n\\nIPAddress DhcpClass::getDnsServerIp()\\n{\\n\\treturn IPAddress(_dhcpDnsServerIp);\\n}\\n\\nvoid DhcpClass::printByte(char * buf, uint8_t n )\\n{\\n\\tchar *str = &buf[1];\\n\\tbuf[0]='0';\\n\\tdo {\\n\\t\\tunsigned long m = n;\\n\\t\\tn /= 16;\\n\\t\\tchar c = m - 16 * n;\\n\\t\\t*str-- = c < 10 ? c + '0' : c + 'A' - 10;\\n\\t} while(n);\\n}\\n\" }", "{ filename: \"src/Dhcp.h\", code: \"// DHCP Library v0.3 - April 25, 2009\\n// Author: Jordan Terrell - blog.jordanterrell.com\\n\\n#ifndef Dhcp_h\\n#define Dhcp_h\\n\\n/* DHCP state machine. */\\n#define STATE_DHCP_START\\t0\\n#define\\tSTATE_DHCP_DISCOVER\\t1\\n#define\\tSTATE_DHCP_REQUEST\\t2\\n#define\\tSTATE_DHCP_LEASED\\t3\\n#define\\tSTATE_DHCP_REREQUEST\\t4\\n#define\\tSTATE_DHCP_RELEASE\\t5\\n\\n#define DHCP_FLAGSBROADCAST\\t0x8000\\n\\n/* UDP port numbers for DHCP */\\n#define\\tDHCP_SERVER_PORT\\t67\\t/* from server to client */\\n#define DHCP_CLIENT_PORT\\t68\\t/* from client to server */\\n\\n/* DHCP message OP code */\\n#define DHCP_BOOTREQUEST\\t1\\n#define DHCP_BOOTREPLY\\t\\t2\\n\\n/* DHCP message type */\\n#define\\tDHCP_DISCOVER\\t\\t1\\n#define DHCP_OFFER\\t\\t2\\n#define\\tDHCP_REQUEST\\t\\t3\\n#define\\tDHCP_DECLINE\\t\\t4\\n#define\\tDHCP_ACK\\t\\t5\\n#define DHCP_NAK\\t\\t6\\n#define\\tDHCP_RELEASE\\t\\t7\\n#define DHCP_INFORM\\t\\t8\\n\\n#define DHCP_HTYPE10MB\\t\\t1\\n#define DHCP_HTYPE100MB\\t\\t2\\n\\n#define DHCP_HLENETHERNET\\t6\\n#define DHCP_HOPS\\t\\t0\\n#define DHCP_SECS\\t\\t0\\n\\n#define MAGIC_COOKIE\\t\\t0x63825363\\n#define MAX_DHCP_OPT\\t\\t16\\n\\n#define HOST_NAME \\\"WIZnet\\\"\\n#define DEFAULT_LEASE\\t(900) //default lease time in seconds\\n\\n#define DHCP_CHECK_NONE (0)\\n#define DHCP_CHECK_RENEW_FAIL (1)\\n#define DHCP_CHECK_RENEW_OK (2)\\n#define DHCP_CHECK_REBIND_FAIL (3)\\n#define DHCP_CHECK_REBIND_OK (4)\\n\\nenum\\n{\\n\\tpadOption\\t\\t=\\t0,\\n\\tsubnetMask\\t\\t=\\t1,\\n\\ttimerOffset\\t\\t=\\t2,\\n\\troutersOnSubnet\\t\\t=\\t3,\\n\\t/* timeServer\\t\\t=\\t4,\\n\\tnameServer\\t\\t=\\t5,*/\\n\\tdns\\t\\t\\t=\\t6,\\n\\t/*logServer\\t\\t=\\t7,\\n\\tcookieServer\\t\\t=\\t8,\\n\\tlprServer\\t\\t=\\t9,\\n\\timpressServer\\t\\t=\\t10,\\n\\tresourceLocationServer\\t=\\t11,*/\\n\\thostName\\t\\t=\\t12,\\n\\t/*bootFileSize\\t\\t=\\t13,\\n\\tmeritDumpFile\\t\\t=\\t14,*/\\n\\tdomainName\\t\\t=\\t15,\\n\\t/*swapServer\\t\\t=\\t16,\\n\\trootPath\\t\\t=\\t17,\\n\\textentionsPath\\t\\t=\\t18,\\n\\tIPforwarding\\t\\t=\\t19,\\n\\tnonLocalSourceRouting\\t=\\t20,\\n\\tpolicyFilter\\t\\t=\\t21,\\n\\tmaxDgramReasmSize\\t=\\t22,\\n\\tdefaultIPTTL\\t\\t=\\t23,\\n\\tpathMTUagingTimeout\\t=\\t24,\\n\\tpathMTUplateauTable\\t=\\t25,\\n\\tifMTU\\t\\t\\t=\\t26,\\n\\tallSubnetsLocal\\t\\t=\\t27,\\n\\tbroadcastAddr\\t\\t=\\t28,\\n\\tperformMaskDiscovery\\t=\\t29,\\n\\tmaskSupplier\\t\\t=\\t30,\\n\\tperformRouterDiscovery\\t=\\t31,\\n\\trouterSolicitationAddr\\t=\\t32,\\n\\tstaticRoute\\t\\t=\\t33,\\n\\ttrailerEncapsulation\\t=\\t34,\\n\\tarpCacheTimeout\\t\\t=\\t35,\\n\\tethernetEncapsulation\\t=\\t36,\\n\\ttcpDefaultTTL\\t\\t=\\t37,\\n\\ttcpKeepaliveInterval\\t=\\t38,\\n\\ttcpKeepaliveGarbage\\t=\\t39,\\n\\tnisDomainName\\t\\t=\\t40,\\n\\tnisServers\\t\\t=\\t41,\\n\\tntpServers\\t\\t=\\t42,\\n\\tvendorSpecificInfo\\t=\\t43,\\n\\tnetBIOSnameServer\\t=\\t44,\\n\\tnetBIOSdgramDistServer\\t=\\t45,\\n\\tnetBIOSnodeType\\t\\t=\\t46,\\n\\tnetBIOSscope\\t\\t=\\t47,\\n\\txFontServer\\t\\t=\\t48,\\n\\txDisplayManager\\t\\t=\\t49,*/\\n\\tdhcpRequestedIPaddr\\t=\\t50,\\n\\tdhcpIPaddrLeaseTime\\t=\\t51,\\n\\t/*dhcpOptionOverload\\t=\\t52,*/\\n\\tdhcpMessageType\\t\\t=\\t53,\\n\\tdhcpServerIdentifier\\t=\\t54,\\n\\tdhcpParamRequest\\t=\\t55,\\n\\t/*dhcpMsg\\t\\t\\t=\\t56,\\n\\tdhcpMaxMsgSize\\t\\t=\\t57,*/\\n\\tdhcpT1value\\t\\t=\\t58,\\n\\tdhcpT2value\\t\\t=\\t59,\\n\\t/*dhcpClassIdentifier\\t=\\t60,*/\\n\\tdhcpClientIdentifier\\t=\\t61,\\n\\tendOption\\t\\t=\\t255\\n};\\n\\ntypedef struct _RIP_MSG_FIXED\\n{\\n\\tuint8_t op;\\n\\tuint8_t htype;\\n\\tuint8_t hlen;\\n\\tuint8_t hops;\\n\\tuint32_t xid;\\n\\tuint16_t secs;\\n\\tuint16_t flags;\\n\\tuint8_t ciaddr[4];\\n\\tuint8_t yiaddr[4];\\n\\tuint8_t siaddr[4];\\n\\tuint8_t giaddr[4];\\n\\tuint8_t chaddr[6];\\n} RIP_MSG_FIXED;\\n\\n#endif\\n\" }", "{ filename: \"src/Dns.cpp\", code: \"// Arduino DNS client for WizNet5100-based Ethernet shield\\n// (c) Copyright 2009-2010 MCQN Ltd.\\n// Released under Apache License, version 2.0\\n\\n#include \\n#include \\\"Ethernet.h\\\"\\n#include \\\"Dns.h\\\"\\n#include \\\"w5100.h\\\"\\n\\n\\n#define SOCKET_NONE 255\\n// Various flags and header field values for a DNS message\\n#define UDP_HEADER_SIZE 8\\n#define DNS_HEADER_SIZE 12\\n#define TTL_SIZE 4\\n#define QUERY_FLAG (0)\\n#define RESPONSE_FLAG (1<<15)\\n#define QUERY_RESPONSE_MASK (1<<15)\\n#define OPCODE_STANDARD_QUERY (0)\\n#define OPCODE_INVERSE_QUERY (1<<11)\\n#define OPCODE_STATUS_REQUEST (2<<11)\\n#define OPCODE_MASK (15<<11)\\n#define AUTHORITATIVE_FLAG (1<<10)\\n#define TRUNCATION_FLAG (1<<9)\\n#define RECURSION_DESIRED_FLAG (1<<8)\\n#define RECURSION_AVAILABLE_FLAG (1<<7)\\n#define RESP_NO_ERROR (0)\\n#define RESP_FORMAT_ERROR (1)\\n#define RESP_SERVER_FAILURE (2)\\n#define RESP_NAME_ERROR (3)\\n#define RESP_NOT_IMPLEMENTED (4)\\n#define RESP_REFUSED (5)\\n#define RESP_MASK (15)\\n#define TYPE_A (0x0001)\\n#define CLASS_IN (0x0001)\\n#define LABEL_COMPRESSION_MASK (0xC0)\\n// Port number that DNS servers listen on\\n#define DNS_PORT 53\\n\\n// Possible return codes from ProcessResponse\\n#define SUCCESS 1\\n#define TIMED_OUT -1\\n#define INVALID_SERVER -2\\n#define TRUNCATED -3\\n#define INVALID_RESPONSE -4\\n\\nvoid DNSClient::begin(const IPAddress& aDNSServer)\\n{\\n\\tiDNSServer = aDNSServer;\\n\\tiRequestId = 0;\\n}\\n\\n\\nint DNSClient::inet_aton(const char* address, IPAddress& result)\\n{\\n\\tuint16_t acc = 0; // Accumulator\\n\\tuint8_t dots = 0;\\n\\n\\twhile (*address) {\\n\\t\\tchar c = *address++;\\n\\t\\tif (c >= '0' && c <= '9') {\\n\\t\\t\\tacc = acc * 10 + (c - '0');\\n\\t\\t\\tif (acc > 255) {\\n\\t\\t\\t\\t// Value out of [0..255] range\\n\\t\\t\\t\\treturn 0;\\n\\t\\t\\t}\\n\\t\\t} else if (c == '.') {\\n\\t\\t\\tif (dots == 3) {\\n\\t\\t\\t\\t// Too much dots (there must be 3 dots)\\n\\t\\t\\t\\treturn 0;\\n\\t\\t\\t}\\n\\t\\t\\tresult[dots++] = acc;\\n\\t\\t\\tacc = 0;\\n\\t\\t} else {\\n\\t\\t\\t// Invalid char\\n\\t\\t\\treturn 0;\\n\\t\\t}\\n\\t}\\n\\n\\tif (dots != 3) {\\n\\t\\t// Too few dots (there must be 3 dots)\\n\\t\\treturn 0;\\n\\t}\\n\\tresult[3] = acc;\\n\\treturn 1;\\n}\\n\\nint DNSClient::getHostByName(const char* aHostname, IPAddress& aResult, uint16_t timeout)\\n{\\n\\tint ret = 0;\\n\\n\\t// See if it's a numeric IP address\\n\\tif (inet_aton(aHostname, aResult)) {\\n\\t\\t// It is, our work here is done\\n\\t\\treturn 1;\\n\\t}\\n\\n\\t// Check we've got a valid DNS server to use\\n\\tif (iDNSServer == INADDR_NONE) {\\n\\t\\treturn INVALID_SERVER;\\n\\t}\\n\\t\\n\\t// Find a socket to use\\n\\tif (iUdp.begin(1024+(millis() & 0xF)) == 1) {\\n\\t\\t// Try up to three times\\n\\t\\tint retries = 0;\\n\\t\\t// while ((retries < 3) && (ret <= 0)) {\\n\\t\\t// Send DNS request\\n\\t\\tret = iUdp.beginPacket(iDNSServer, DNS_PORT);\\n\\t\\tif (ret != 0) {\\n\\t\\t\\t// Now output the request data\\n\\t\\t\\tret = BuildRequest(aHostname);\\n\\t\\t\\tif (ret != 0) {\\n\\t\\t\\t\\t// And finally send the request\\n\\t\\t\\t\\tret = iUdp.endPacket();\\n\\t\\t\\t\\tif (ret != 0) {\\n\\t\\t\\t\\t\\t// Now wait for a response\\n\\t\\t\\t\\t\\tint wait_retries = 0;\\n\\t\\t\\t\\t\\tret = TIMED_OUT;\\n\\t\\t\\t\\t\\twhile ((wait_retries < 3) && (ret == TIMED_OUT)) {\\n\\t\\t\\t\\t\\t\\tret = ProcessResponse(timeout, aResult);\\n\\t\\t\\t\\t\\t\\twait_retries++;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\tretries++;\\n\\t\\t//}\\n\\n\\t\\t// We're done with the socket now\\n\\t\\tiUdp.stop();\\n\\t}\\n\\n\\treturn ret;\\n}\\n\\nuint16_t DNSClient::BuildRequest(const char* aName)\\n{\\n\\t// Build header\\n\\t// 1 1 1 1 1 1\\n\\t// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5\\n\\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\\n\\t// | ID |\\n\\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\\n\\t// |QR| Opcode |AA|TC|RD|RA| Z | RCODE |\\n\\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\\n\\t// | QDCOUNT |\\n\\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\\n\\t// | ANCOUNT |\\n\\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\\n\\t// | NSCOUNT |\\n\\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\\n\\t// | ARCOUNT |\\n\\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\\n\\t// As we only support one request at a time at present, we can simplify\\n\\t// some of this header\\n\\tiRequestId = millis(); // generate a random ID\\n\\tuint16_t twoByteBuffer;\\n\\n\\t// FIXME We should also check that there's enough space available to write to, rather\\n\\t// FIXME than assume there's enough space (as the code does at present)\\n\\tiUdp.write((uint8_t*)&iRequestId, sizeof(iRequestId));\\n\\n\\ttwoByteBuffer = htons(QUERY_FLAG | OPCODE_STANDARD_QUERY | RECURSION_DESIRED_FLAG);\\n\\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\\n\\n\\ttwoByteBuffer = htons(1); // One question record\\n\\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\\n\\n\\ttwoByteBuffer = 0; // Zero answer records\\n\\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\\n\\n\\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\\n\\t// and zero additional records\\n\\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\\n\\n\\t// Build question\\n\\tconst char* start =aName;\\n\\tconst char* end =start;\\n\\tuint8_t len;\\n\\t// Run through the name being requested\\n\\twhile (*end) {\\n\\t\\t// Find out how long this section of the name is\\n\\t\\tend = start;\\n\\t\\twhile (*end && (*end != '.') ) {\\n\\t\\t\\tend++;\\n\\t\\t}\\n\\n\\t\\tif (end-start > 0) {\\n\\t\\t\\t// Write out the size of this section\\n\\t\\t\\tlen = end-start;\\n\\t\\t\\tiUdp.write(&len, sizeof(len));\\n\\t\\t\\t// And then write out the section\\n\\t\\t\\tiUdp.write((uint8_t*)start, end-start);\\n\\t\\t}\\n\\t\\tstart = end+1;\\n\\t}\\n\\n\\t// We've got to the end of the question name, so\\n\\t// terminate it with a zero-length section\\n\\tlen = 0;\\n\\tiUdp.write(&len, sizeof(len));\\n\\t// Finally the type and class of question\\n\\ttwoByteBuffer = htons(TYPE_A);\\n\\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\\n\\n\\ttwoByteBuffer = htons(CLASS_IN); // Internet class of question\\n\\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\\n\\t// Success! Everything buffered okay\\n\\treturn 1;\\n}\\n\\n\\nuint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress)\\n{\\n\\tuint32_t startTime = millis();\\n\\n\\t// Wait for a response packet\\n\\twhile (iUdp.parsePacket() <= 0) {\\n\\t\\tif ((millis() - startTime) > aTimeout) {\\n\\t\\t\\treturn TIMED_OUT;\\n\\t\\t}\\n\\t\\tdelay(50);\\n\\t}\\n\\n\\t// We've had a reply!\\n\\t// Read the UDP header\\n\\t//uint8_t header[DNS_HEADER_SIZE]; // Enough space to reuse for the DNS header\\n\\tunion {\\n\\t\\tuint8_t byte[DNS_HEADER_SIZE]; // Enough space to reuse for the DNS header\\n\\t\\tuint16_t word[DNS_HEADER_SIZE/2];\\n\\t} header;\\n\\n\\t// Check that it's a response from the right server and the right port\\n\\tif ( (iDNSServer != iUdp.remoteIP()) || (iUdp.remotePort() != DNS_PORT) ) {\\n\\t\\t// It's not from who we expected\\n\\t\\treturn INVALID_SERVER;\\n\\t}\\n\\n\\t// Read through the rest of the response\\n\\tif (iUdp.available() < DNS_HEADER_SIZE) {\\n\\t\\treturn TRUNCATED;\\n\\t}\\n\\tiUdp.read(header.byte, DNS_HEADER_SIZE);\\n\\n\\tuint16_t header_flags = htons(header.word[1]);\\n\\t// Check that it's a response to this request\\n\\tif ((iRequestId != (header.word[0])) ||\\n\\t ((header_flags & QUERY_RESPONSE_MASK) != (uint16_t)RESPONSE_FLAG) ) {\\n\\t\\t// Mark the entire packet as read\\n\\t\\tiUdp.flush(); // FIXME\\n\\t\\treturn INVALID_RESPONSE;\\n\\t}\\n\\t// Check for any errors in the response (or in our request)\\n\\t// although we don't do anything to get round these\\n\\tif ( (header_flags & TRUNCATION_FLAG) || (header_flags & RESP_MASK) ) {\\n\\t\\t// Mark the entire packet as read\\n\\t\\tiUdp.flush(); // FIXME\\n\\t\\treturn -5; //INVALID_RESPONSE;\\n\\t}\\n\\n\\t// And make sure we've got (at least) one answer\\n\\tuint16_t answerCount = htons(header.word[3]);\\n\\tif (answerCount == 0) {\\n\\t\\t// Mark the entire packet as read\\n\\t\\tiUdp.flush(); // FIXME\\n\\t\\treturn -6; //INVALID_RESPONSE;\\n\\t}\\n\\n\\t// Skip over any questions\\n\\tfor (uint16_t i=0; i < htons(header.word[2]); i++) {\\n\\t\\t// Skip over the name\\n\\t\\tuint8_t len;\\n\\t\\tdo {\\n\\t\\t\\tiUdp.read(&len, sizeof(len));\\n\\t\\t\\tif (len > 0) {\\n\\t\\t\\t\\t// Don't need to actually read the data out for the string, just\\n\\t\\t\\t\\t// advance ptr to beyond it\\n\\t\\t\\t\\tiUdp.read((uint8_t *)NULL, (size_t)len);\\n\\t\\t\\t}\\n\\t\\t} while (len != 0);\\n\\n\\t\\t// Now jump over the type and class\\n\\t\\tiUdp.read((uint8_t *)NULL, 4);\\n\\t}\\n\\n\\t// Now we're up to the bit we're interested in, the answer\\n\\t// There might be more than one answer (although we'll just use the first\\n\\t// type A answer) and some authority and additional resource records but\\n\\t// we're going to ignore all of them.\\n\\n\\tfor (uint16_t i=0; i < answerCount; i++) {\\n\\t\\t// Skip the name\\n\\t\\tuint8_t len;\\n\\t\\tdo {\\n\\t\\t\\tiUdp.read(&len, sizeof(len));\\n\\t\\t\\tif ((len & LABEL_COMPRESSION_MASK) == 0) {\\n\\t\\t\\t\\t// It's just a normal label\\n\\t\\t\\t\\tif (len > 0) {\\n\\t\\t\\t\\t\\t// And it's got a length\\n\\t\\t\\t\\t\\t// Don't need to actually read the data out for the string,\\n\\t\\t\\t\\t\\t// just advance ptr to beyond it\\n\\t\\t\\t\\t\\tiUdp.read((uint8_t *)NULL, len);\\n\\t\\t\\t\\t}\\n\\t\\t\\t} else {\\n\\t\\t\\t\\t// This is a pointer to a somewhere else in the message for the\\n\\t\\t\\t\\t// rest of the name. We don't care about the name, and RFC1035\\n\\t\\t\\t\\t// says that a name is either a sequence of labels ended with a\\n\\t\\t\\t\\t// 0 length octet or a pointer or a sequence of labels ending in\\n\\t\\t\\t\\t// a pointer. Either way, when we get here we're at the end of\\n\\t\\t\\t\\t// the name\\n\\t\\t\\t\\t// Skip over the pointer\\n\\t\\t\\t\\tiUdp.read((uint8_t *)NULL, 1); // we don't care about the byte\\n\\t\\t\\t\\t// And set len so that we drop out of the name loop\\n\\t\\t\\t\\tlen = 0;\\n\\t\\t\\t}\\n\\t\\t} while (len != 0);\\n\\n\\t\\t// Check the type and class\\n\\t\\tuint16_t answerType;\\n\\t\\tuint16_t answerClass;\\n\\t\\tiUdp.read((uint8_t*)&answerType, sizeof(answerType));\\n\\t\\tiUdp.read((uint8_t*)&answerClass, sizeof(answerClass));\\n\\n\\t\\t// Ignore the Time-To-Live as we don't do any caching\\n\\t\\tiUdp.read((uint8_t *)NULL, TTL_SIZE); // don't care about the returned bytes\\n\\n\\t\\t// And read out the length of this answer\\n\\t\\t// Don't need header_flags anymore, so we can reuse it here\\n\\t\\tiUdp.read((uint8_t*)&header_flags, sizeof(header_flags));\\n\\n\\t\\tif ( (htons(answerType) == TYPE_A) && (htons(answerClass) == CLASS_IN) ) {\\n\\t\\t\\tif (htons(header_flags) != 4) {\\n\\t\\t\\t\\t// It's a weird size\\n\\t\\t\\t\\t// Mark the entire packet as read\\n\\t\\t\\t\\tiUdp.flush(); // FIXME\\n\\t\\t\\t\\treturn -9;//INVALID_RESPONSE;\\n\\t\\t\\t}\\n\\t\\t\\t// FIXME: seeems to lock up here on ESP8266, but why??\\n\\t\\t\\tiUdp.read(aAddress.raw_address(), 4);\\n\\t\\t\\treturn SUCCESS;\\n\\t\\t} else {\\n\\t\\t\\t// This isn't an answer type we're after, move onto the next one\\n\\t\\t\\tiUdp.read((uint8_t *)NULL, htons(header_flags));\\n\\t\\t}\\n\\t}\\n\\n\\t// Mark the entire packet as read\\n\\tiUdp.flush(); // FIXME\\n\\n\\t// If we get here then we haven't found an answer\\n\\treturn -10; //INVALID_RESPONSE;\\n}\\n\\n\" }", "{ filename: \"src/Dns.h\", code: \"// Arduino DNS client for WizNet5100-based Ethernet shield\\n// (c) Copyright 2009-2010 MCQN Ltd.\\n// Released under Apache License, version 2.0\\n\\n#ifndef DNSClient_h\\n#define DNSClient_h\\n\\n#include \\\"Ethernet.h\\\"\\n\\nclass DNSClient\\n{\\npublic:\\n\\tvoid begin(const IPAddress& aDNSServer);\\n\\n\\t/** Convert a numeric IP address string into a four-byte IP address.\\n\\t @param aIPAddrString IP address to convert\\n\\t @param aResult IPAddress structure to store the returned IP address\\n\\t @result 1 if aIPAddrString was successfully converted to an IP address,\\n\\t else error code\\n\\t*/\\n\\tint inet_aton(const char *aIPAddrString, IPAddress& aResult);\\n\\n\\t/** Resolve the given hostname to an IP address.\\n\\t @param aHostname Name to be resolved\\n\\t @param aResult IPAddress structure to store the returned IP address\\n\\t @result 1 if aIPAddrString was successfully converted to an IP address,\\n\\t else error code\\n\\t*/\\n\\tint getHostByName(const char* aHostname, IPAddress& aResult, uint16_t timeout=5000);\\n\\nprotected:\\n\\tuint16_t BuildRequest(const char* aName);\\n\\tuint16_t ProcessResponse(uint16_t aTimeout, IPAddress& aAddress);\\n\\n\\tIPAddress iDNSServer;\\n\\tuint16_t iRequestId;\\n\\tEthernetUDP iUdp;\\n};\\n\\n#endif\\n\" }", "{ filename: \"src/Ethernet.cpp\", code: \"/* Copyright 2018 Paul Stoffregen\\n *\\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this\\n * software and associated documentation files (the \\\"Software\\\"), to deal in the Software\\n * without restriction, including without limitation the rights to use, copy, modify,\\n * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\\n * permit persons to whom the Software is furnished to do so, subject to the following\\n * conditions:\\n *\\n * The above copyright notice and this permission notice shall be included in all\\n * copies or substantial portions of the Software.\\n *\\n * THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\\n */\\n\\n#include \\n#include \\\"Ethernet.h\\\"\\n#include \\\"w5100.h\\\"\\n#include \\\"Dhcp.h\\\"\\n\\nIPAddress EthernetClass::_dnsServerAddress;\\nDhcpClass* EthernetClass::_dhcp = NULL;\\n\\nint EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)\\n{\\n\\tstatic DhcpClass s_dhcp;\\n\\t_dhcp = &s_dhcp;\\n\\n\\t// Initialise the basic info\\n\\tif (W5100.init() == 0) return 0;\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tW5100.setMACAddress(mac);\\n\\tW5100.setIPAddress(IPAddress(0,0,0,0).raw_address());\\n\\tSPI.endTransaction();\\n\\n\\t// Now try to get our config info from a DHCP server\\n\\tint ret = _dhcp->beginWithDHCP(mac, timeout, responseTimeout);\\n\\tif (ret == 1) {\\n\\t\\t// We've successfully found a DHCP server and got our configuration\\n\\t\\t// info, so set things accordingly\\n\\t\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\t\\tW5100.setIPAddress(_dhcp->getLocalIp().raw_address());\\n\\t\\tW5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());\\n\\t\\tW5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());\\n\\t\\tSPI.endTransaction();\\n\\t\\t_dnsServerAddress = _dhcp->getDnsServerIp();\\n\\t\\tsocketPortRand(micros());\\n\\t}\\n\\treturn ret;\\n}\\n\\nvoid EthernetClass::begin(uint8_t *mac, IPAddress ip)\\n{\\n\\t// Assume the DNS server will be the machine on the same network as the local IP\\n\\t// but with last octet being '1'\\n\\tIPAddress dns = ip;\\n\\tdns[3] = 1;\\n\\tbegin(mac, ip, dns);\\n}\\n\\nvoid EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns)\\n{\\n\\t// Assume the gateway will be the machine on the same network as the local IP\\n\\t// but with last octet being '1'\\n\\tIPAddress gateway = ip;\\n\\tgateway[3] = 1;\\n\\tbegin(mac, ip, dns, gateway);\\n}\\n\\nvoid EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway)\\n{\\n\\tIPAddress subnet(255, 255, 255, 0);\\n\\tbegin(mac, ip, dns, gateway, subnet);\\n}\\n\\nvoid EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)\\n{\\n\\tif (W5100.init() == 0) return;\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tW5100.setMACAddress(mac);\\n#if ARDUINO > 106 || TEENSYDUINO > 121\\n\\tW5100.setIPAddress(ip._address.bytes);\\n\\tW5100.setGatewayIp(gateway._address.bytes);\\n\\tW5100.setSubnetMask(subnet._address.bytes);\\n#else\\n\\tW5100.setIPAddress(ip._address);\\n\\tW5100.setGatewayIp(gateway._address);\\n\\tW5100.setSubnetMask(subnet._address);\\n#endif\\n\\tSPI.endTransaction();\\n\\t_dnsServerAddress = dns;\\n}\\n\\nvoid EthernetClass::init(uint8_t sspin)\\n{\\n\\tW5100.setSS(sspin);\\n}\\n\\nEthernetLinkStatus EthernetClass::linkStatus()\\n{\\n\\tswitch (W5100.getLinkStatus()) {\\n\\t\\tcase UNKNOWN: return Unknown;\\n\\t\\tcase LINK_ON: return LinkON;\\n\\t\\tcase LINK_OFF: return LinkOFF;\\n\\t\\tdefault: return Unknown;\\n\\t}\\n}\\n\\nEthernetHardwareStatus EthernetClass::hardwareStatus()\\n{\\n\\tswitch (W5100.getChip()) {\\n\\t\\tcase 51: return EthernetW5100;\\n\\t\\tcase 52: return EthernetW5200;\\n\\t\\tcase 55: return EthernetW5500;\\n\\t\\tdefault: return EthernetNoHardware;\\n\\t}\\n}\\n\\nint EthernetClass::maintain()\\n{\\n\\tint rc = DHCP_CHECK_NONE;\\n\\tif (_dhcp != NULL) {\\n\\t\\t// we have a pointer to dhcp, use it\\n\\t\\trc = _dhcp->checkLease();\\n\\t\\tswitch (rc) {\\n\\t\\tcase DHCP_CHECK_NONE:\\n\\t\\t\\t//nothing done\\n\\t\\t\\tbreak;\\n\\t\\tcase DHCP_CHECK_RENEW_OK:\\n\\t\\tcase DHCP_CHECK_REBIND_OK:\\n\\t\\t\\t//we might have got a new IP.\\n\\t\\t\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\t\\t\\tW5100.setIPAddress(_dhcp->getLocalIp().raw_address());\\n\\t\\t\\tW5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());\\n\\t\\t\\tW5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());\\n\\t\\t\\tSPI.endTransaction();\\n\\t\\t\\t_dnsServerAddress = _dhcp->getDnsServerIp();\\n\\t\\t\\tbreak;\\n\\t\\tdefault:\\n\\t\\t\\t//this is actually an error, it will retry though\\n\\t\\t\\tbreak;\\n\\t\\t}\\n\\t}\\n\\treturn rc;\\n}\\n\\n\\nvoid EthernetClass::MACAddress(uint8_t *mac_address)\\n{\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tW5100.getMACAddress(mac_address);\\n\\tSPI.endTransaction();\\n}\\n\\nIPAddress EthernetClass::localIP()\\n{\\n\\tIPAddress ret;\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tW5100.getIPAddress(ret.raw_address());\\n\\tSPI.endTransaction();\\n\\treturn ret;\\n}\\n\\nIPAddress EthernetClass::subnetMask()\\n{\\n\\tIPAddress ret;\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tW5100.getSubnetMask(ret.raw_address());\\n\\tSPI.endTransaction();\\n\\treturn ret;\\n}\\n\\nIPAddress EthernetClass::gatewayIP()\\n{\\n\\tIPAddress ret;\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tW5100.getGatewayIp(ret.raw_address());\\n\\tSPI.endTransaction();\\n\\treturn ret;\\n}\\n\\nvoid EthernetClass::setMACAddress(const uint8_t *mac_address)\\n{\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tW5100.setMACAddress(mac_address);\\n\\tSPI.endTransaction();\\n}\\n\\nvoid EthernetClass::setLocalIP(const IPAddress local_ip)\\n{\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tIPAddress ip = local_ip;\\n\\tW5100.setIPAddress(ip.raw_address());\\n\\tSPI.endTransaction();\\n}\\n\\nvoid EthernetClass::setSubnetMask(const IPAddress subnet)\\n{\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tIPAddress ip = subnet;\\n\\tW5100.setSubnetMask(ip.raw_address());\\n\\tSPI.endTransaction();\\n}\\n\\nvoid EthernetClass::setGatewayIP(const IPAddress gateway)\\n{\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tIPAddress ip = gateway;\\n\\tW5100.setGatewayIp(ip.raw_address());\\n\\tSPI.endTransaction();\\n}\\n\\nvoid EthernetClass::setRetransmissionTimeout(uint16_t milliseconds)\\n{\\n\\tif (milliseconds > 6553) milliseconds = 6553;\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tW5100.setRetransmissionTime(milliseconds * 10);\\n\\tSPI.endTransaction();\\n}\\n\\nvoid EthernetClass::setRetransmissionCount(uint8_t num)\\n{\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tW5100.setRetransmissionCount(num);\\n\\tSPI.endTransaction();\\n}\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\nEthernetClass Ethernet;\\n\" }", "{ filename: \"src/Ethernet.h\", code: \"/* Copyright 2018 Paul Stoffregen\\n *\\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this\\n * software and associated documentation files (the \\\"Software\\\"), to deal in the Software\\n * without restriction, including without limitation the rights to use, copy, modify,\\n * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\\n * permit persons to whom the Software is furnished to do so, subject to the following\\n * conditions:\\n *\\n * The above copyright notice and this permission notice shall be included in all\\n * copies or substantial portions of the Software.\\n *\\n * THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\\n */\\n\\n#ifndef ethernet_h_\\n#define ethernet_h_\\n\\n// All symbols exposed to Arduino sketches are contained in this header file\\n//\\n// Older versions had much of this stuff in EthernetClient.h, EthernetServer.h,\\n// and socket.h. Including headers in different order could cause trouble, so\\n// these \\\"friend\\\" classes are now defined in the same header file. socket.h\\n// was removed to avoid possible conflict with the C library header files.\\n\\n\\n// Configure the maximum number of sockets to support. W5100 chips can have\\n// up to 4 sockets. W5200 & W5500 can have up to 8 sockets. Several bytes\\n// of RAM are used for each socket. Reducing the maximum can save RAM, but\\n// you are limited to fewer simultaneous connections.\\n#if defined(RAMEND) && defined(RAMSTART) && ((RAMEND - RAMSTART) <= 2048)\\n#define MAX_SOCK_NUM 4\\n#else\\n#define MAX_SOCK_NUM 8\\n#endif\\n\\n// By default, each socket uses 2K buffers inside the Wiznet chip. If\\n// MAX_SOCK_NUM is set to fewer than the chip's maximum, uncommenting\\n// this will use larger buffers within the Wiznet chip. Large buffers\\n// can really help with UDP protocols like Artnet. In theory larger\\n// buffers should allow faster TCP over high-latency links, but this\\n// does not always seem to work in practice (maybe Wiznet bugs?)\\n//#define ETHERNET_LARGE_BUFFERS\\n\\n\\n#include \\n#include \\\"Client.h\\\"\\n#include \\\"Server.h\\\"\\n#include \\\"Udp.h\\\"\\n\\nenum EthernetLinkStatus {\\n\\tUnknown,\\n\\tLinkON,\\n\\tLinkOFF\\n};\\n\\nenum EthernetHardwareStatus {\\n\\tEthernetNoHardware,\\n\\tEthernetW5100,\\n\\tEthernetW5200,\\n\\tEthernetW5500\\n};\\n\\nclass EthernetUDP;\\nclass EthernetClient;\\nclass EthernetServer;\\nclass DhcpClass;\\n\\nclass EthernetClass {\\nprivate:\\n\\tstatic IPAddress _dnsServerAddress;\\n\\tstatic DhcpClass* _dhcp;\\npublic:\\n\\t// Initialise the Ethernet shield to use the provided MAC address and\\n\\t// gain the rest of the configuration through DHCP.\\n\\t// Returns 0 if the DHCP configuration failed, and 1 if it succeeded\\n\\tstatic int begin(uint8_t *mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);\\n\\tstatic int maintain();\\n\\tstatic EthernetLinkStatus linkStatus();\\n\\tstatic EthernetHardwareStatus hardwareStatus();\\n\\n\\t// Manaul configuration\\n\\tstatic void begin(uint8_t *mac, IPAddress ip);\\n\\tstatic void begin(uint8_t *mac, IPAddress ip, IPAddress dns);\\n\\tstatic void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway);\\n\\tstatic void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);\\n\\tstatic void init(uint8_t sspin = 10);\\n\\n\\tstatic void MACAddress(uint8_t *mac_address);\\n\\tstatic IPAddress localIP();\\n\\tstatic IPAddress subnetMask();\\n\\tstatic IPAddress gatewayIP();\\n\\tstatic IPAddress dnsServerIP() { return _dnsServerAddress; }\\n\\n\\tvoid setMACAddress(const uint8_t *mac_address);\\n\\tvoid setLocalIP(const IPAddress local_ip);\\n\\tvoid setSubnetMask(const IPAddress subnet);\\n\\tvoid setGatewayIP(const IPAddress gateway);\\n\\tvoid setDnsServerIP(const IPAddress dns_server) { _dnsServerAddress = dns_server; }\\n\\tvoid setRetransmissionTimeout(uint16_t milliseconds);\\n\\tvoid setRetransmissionCount(uint8_t num);\\n\\n\\tfriend class EthernetClient;\\n\\tfriend class EthernetServer;\\n\\tfriend class EthernetUDP;\\nprivate:\\n\\t// Opens a socket(TCP or UDP or IP_RAW mode)\\n\\tstatic uint8_t socketBegin(uint8_t protocol, uint16_t port);\\n\\tstatic uint8_t socketBeginMulticast(uint8_t protocol, IPAddress ip,uint16_t port);\\n\\tstatic uint8_t socketStatus(uint8_t s);\\n\\t// Close socket\\n\\tstatic void socketClose(uint8_t s);\\n\\t// Establish TCP connection (Active connection)\\n\\tstatic void socketConnect(uint8_t s, uint8_t * addr, uint16_t port);\\n\\t// disconnect the connection\\n\\tstatic void socketDisconnect(uint8_t s);\\n\\t// Establish TCP connection (Passive connection)\\n\\tstatic uint8_t socketListen(uint8_t s);\\n\\t// Send data (TCP)\\n\\tstatic uint16_t socketSend(uint8_t s, const uint8_t * buf, uint16_t len);\\n\\tstatic uint16_t socketSendAvailable(uint8_t s);\\n\\t// Receive data (TCP)\\n\\tstatic int socketRecv(uint8_t s, uint8_t * buf, int16_t len);\\n\\tstatic uint16_t socketRecvAvailable(uint8_t s);\\n\\tstatic uint8_t socketPeek(uint8_t s);\\n\\t// sets up a UDP datagram, the data for which will be provided by one\\n\\t// or more calls to bufferData and then finally sent with sendUDP.\\n\\t// return true if the datagram was successfully set up, or false if there was an error\\n\\tstatic bool socketStartUDP(uint8_t s, uint8_t* addr, uint16_t port);\\n\\t// copy up to len bytes of data from buf into a UDP datagram to be\\n\\t// sent later by sendUDP. Allows datagrams to be built up from a series of bufferData calls.\\n\\t// return Number of bytes successfully buffered\\n\\tstatic uint16_t socketBufferData(uint8_t s, uint16_t offset, const uint8_t* buf, uint16_t len);\\n\\t// Send a UDP datagram built up from a sequence of startUDP followed by one or more\\n\\t// calls to bufferData.\\n\\t// return true if the datagram was successfully sent, or false if there was an error\\n\\tstatic bool socketSendUDP(uint8_t s);\\n\\t// Initialize the \\\"random\\\" source port number\\n\\tstatic void socketPortRand(uint16_t n);\\n};\\n\\nextern EthernetClass Ethernet;\\n\\n\\n#define UDP_TX_PACKET_MAX_SIZE 24\\n\\nclass EthernetUDP : public UDP {\\nprivate:\\n\\tuint16_t _port; // local port to listen on\\n\\tIPAddress _remoteIP; // remote IP address for the incoming packet whilst it's being processed\\n\\tuint16_t _remotePort; // remote port for the incoming packet whilst it's being processed\\n\\tuint16_t _offset; // offset into the packet being sent\\n\\nprotected:\\n\\tuint8_t sockindex;\\n\\tuint16_t _remaining; // remaining bytes of incoming packet yet to be processed\\n\\npublic:\\n\\tEthernetUDP() : sockindex(MAX_SOCK_NUM) {} // Constructor\\n\\tvirtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use\\n\\tvirtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use\\n\\tvirtual void stop(); // Finish with the UDP socket\\n\\n\\t// Sending UDP packets\\n\\n\\t// Start building up a packet to send to the remote host specific in ip and port\\n\\t// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port\\n\\tvirtual int beginPacket(IPAddress ip, uint16_t port);\\n\\t// Start building up a packet to send to the remote host specific in host and port\\n\\t// Returns 1 if successful, 0 if there was a problem resolving the hostname or port\\n\\tvirtual int beginPacket(const char *host, uint16_t port);\\n\\t// Finish off this packet and send it\\n\\t// Returns 1 if the packet was sent successfully, 0 if there was an error\\n\\tvirtual int endPacket();\\n\\t// Write a single byte into the packet\\n\\tvirtual size_t write(uint8_t);\\n\\t// Write size bytes from buffer into the packet\\n\\tvirtual size_t write(const uint8_t *buffer, size_t size);\\n\\n\\tusing Print::write;\\n\\n\\t// Start processing the next available incoming packet\\n\\t// Returns the size of the packet in bytes, or 0 if no packets are available\\n\\tvirtual int parsePacket();\\n\\t// Number of bytes remaining in the current packet\\n\\tvirtual int available();\\n\\t// Read a single byte from the current packet\\n\\tvirtual int read();\\n\\t// Read up to len bytes from the current packet and place them into buffer\\n\\t// Returns the number of bytes read, or 0 if none are available\\n\\tvirtual int read(unsigned char* buffer, size_t len);\\n\\t// Read up to len characters from the current packet and place them into buffer\\n\\t// Returns the number of characters read, or 0 if none are available\\n\\tvirtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };\\n\\t// Return the next byte from the current packet without moving on to the next byte\\n\\tvirtual int peek();\\n\\tvirtual void flush(); // Finish reading the current packet\\n\\n\\t// Return the IP address of the host who sent the current incoming packet\\n\\tvirtual IPAddress remoteIP() { return _remoteIP; };\\n\\t// Return the port of the host who sent the current incoming packet\\n\\tvirtual uint16_t remotePort() { return _remotePort; };\\n\\tvirtual uint16_t localPort() { return _port; }\\n};\\n\\n\\n\\n\\nclass EthernetClient : public Client {\\npublic:\\n\\tEthernetClient() : sockindex(MAX_SOCK_NUM), _timeout(1000) { }\\n\\tEthernetClient(uint8_t s) : sockindex(s), _timeout(1000) { }\\n\\n\\tuint8_t status();\\n\\tvirtual int connect(IPAddress ip, uint16_t port);\\n\\tvirtual int connect(const char *host, uint16_t port);\\n\\tvirtual int availableForWrite(void);\\n\\tvirtual size_t write(uint8_t);\\n\\tvirtual size_t write(const uint8_t *buf, size_t size);\\n\\tvirtual int available();\\n\\tvirtual int read();\\n\\tvirtual int read(uint8_t *buf, size_t size);\\n\\tvirtual int peek();\\n\\tvirtual void flush();\\n\\tvirtual void stop();\\n\\tvirtual uint8_t connected();\\n\\tvirtual operator bool() { return sockindex < MAX_SOCK_NUM; }\\n\\tvirtual bool operator==(const bool value) { return bool() == value; }\\n\\tvirtual bool operator!=(const bool value) { return bool() != value; }\\n\\tvirtual bool operator==(const EthernetClient&);\\n\\tvirtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); }\\n\\tuint8_t getSocketNumber() const { return sockindex; }\\n\\tvirtual uint16_t localPort();\\n\\tvirtual IPAddress remoteIP();\\n\\tvirtual uint16_t remotePort();\\n\\tvirtual void setConnectionTimeout(uint16_t timeout) { _timeout = timeout; }\\n\\n\\tfriend class EthernetServer;\\n\\n\\tusing Print::write;\\n\\nprivate:\\n\\tuint8_t sockindex; // MAX_SOCK_NUM means client not in use\\n\\tuint16_t _timeout;\\n};\\n\\n\\nclass EthernetServer : public Server {\\nprivate:\\n\\tuint16_t _port;\\npublic:\\n\\tEthernetServer(uint16_t port) : _port(port) { }\\n\\tEthernetClient available();\\n\\tEthernetClient accept();\\n\\tvirtual void begin();\\n\\tvirtual size_t write(uint8_t);\\n\\tvirtual size_t write(const uint8_t *buf, size_t size);\\n\\tvirtual operator bool();\\n\\tusing Print::write;\\n\\t//void statusreport();\\n\\n\\t// TODO: make private when socket allocation moves to EthernetClass\\n\\tstatic uint16_t server_port[MAX_SOCK_NUM];\\n};\\n\\n\\nclass DhcpClass {\\nprivate:\\n\\tuint32_t _dhcpInitialTransactionId;\\n\\tuint32_t _dhcpTransactionId;\\n\\tuint8_t _dhcpMacAddr[6];\\n#ifdef __arm__\\n\\tuint8_t _dhcpLocalIp[4] __attribute__((aligned(4)));\\n\\tuint8_t _dhcpSubnetMask[4] __attribute__((aligned(4)));\\n\\tuint8_t _dhcpGatewayIp[4] __attribute__((aligned(4)));\\n\\tuint8_t _dhcpDhcpServerIp[4] __attribute__((aligned(4)));\\n\\tuint8_t _dhcpDnsServerIp[4] __attribute__((aligned(4)));\\n#else\\n\\tuint8_t _dhcpLocalIp[4];\\n\\tuint8_t _dhcpSubnetMask[4];\\n\\tuint8_t _dhcpGatewayIp[4];\\n\\tuint8_t _dhcpDhcpServerIp[4];\\n\\tuint8_t _dhcpDnsServerIp[4];\\n#endif\\n\\tuint32_t _dhcpLeaseTime;\\n\\tuint32_t _dhcpT1, _dhcpT2;\\n\\tuint32_t _renewInSec;\\n\\tuint32_t _rebindInSec;\\n\\tunsigned long _timeout;\\n\\tunsigned long _responseTimeout;\\n\\tunsigned long _lastCheckLeaseMillis;\\n\\tuint8_t _dhcp_state;\\n\\tEthernetUDP _dhcpUdpSocket;\\n\\n\\tint request_DHCP_lease();\\n\\tvoid reset_DHCP_lease();\\n\\tvoid presend_DHCP();\\n\\tvoid send_DHCP_MESSAGE(uint8_t, uint16_t);\\n\\tvoid printByte(char *, uint8_t);\\n\\n\\tuint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId);\\npublic:\\n\\tIPAddress getLocalIp();\\n\\tIPAddress getSubnetMask();\\n\\tIPAddress getGatewayIp();\\n\\tIPAddress getDhcpServerIp();\\n\\tIPAddress getDnsServerIp();\\n\\n\\tint beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);\\n\\tint checkLease();\\n};\\n\\n\\n\\n\\n\\n#endif\\n\" }", "{ filename: \"src/EthernetClient.cpp\", code: \"/* Copyright 2018 Paul Stoffregen\\n *\\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this\\n * software and associated documentation files (the \\\"Software\\\"), to deal in the Software\\n * without restriction, including without limitation the rights to use, copy, modify,\\n * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\\n * permit persons to whom the Software is furnished to do so, subject to the following\\n * conditions:\\n *\\n * The above copyright notice and this permission notice shall be included in all\\n * copies or substantial portions of the Software.\\n *\\n * THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\\n */\\n\\n#include \\n#include \\\"Ethernet.h\\\"\\n#include \\\"Dns.h\\\"\\n#include \\\"w5100.h\\\"\\n\\nint EthernetClient::connect(const char * host, uint16_t port)\\n{\\n\\tDNSClient dns; // Look up the host first\\n\\tIPAddress remote_addr;\\n\\n\\tif (sockindex < MAX_SOCK_NUM) {\\n\\t\\tif (Ethernet.socketStatus(sockindex) != SnSR::CLOSED) {\\n\\t\\t\\tEthernet.socketDisconnect(sockindex); // TODO: should we call stop()?\\n\\t\\t}\\n\\t\\tsockindex = MAX_SOCK_NUM;\\n\\t}\\n\\tdns.begin(Ethernet.dnsServerIP());\\n\\tif (!dns.getHostByName(host, remote_addr)) return 0; // TODO: use _timeout\\n\\treturn connect(remote_addr, port);\\n}\\n\\nint EthernetClient::connect(IPAddress ip, uint16_t port)\\n{\\n\\tif (sockindex < MAX_SOCK_NUM) {\\n\\t\\tif (Ethernet.socketStatus(sockindex) != SnSR::CLOSED) {\\n\\t\\t\\tEthernet.socketDisconnect(sockindex); // TODO: should we call stop()?\\n\\t\\t}\\n\\t\\tsockindex = MAX_SOCK_NUM;\\n\\t}\\n#if defined(ESP8266) || defined(ESP32)\\n\\tif (ip == IPAddress((uint32_t)0) || ip == IPAddress(0xFFFFFFFFul)) return 0;\\n#else\\n\\tif (ip == IPAddress(0ul) || ip == IPAddress(0xFFFFFFFFul)) return 0;\\n#endif\\n\\tsockindex = Ethernet.socketBegin(SnMR::TCP, 0);\\n\\tif (sockindex >= MAX_SOCK_NUM) return 0;\\n\\tEthernet.socketConnect(sockindex, rawIPAddress(ip), port);\\n\\tuint32_t start = millis();\\n\\twhile (1) {\\n\\t\\tuint8_t stat = Ethernet.socketStatus(sockindex);\\n\\t\\tif (stat == SnSR::ESTABLISHED) return 1;\\n\\t\\tif (stat == SnSR::CLOSE_WAIT) return 1;\\n\\t\\tif (stat == SnSR::CLOSED) return 0;\\n\\t\\tif (millis() - start > _timeout) break;\\n\\t\\tdelay(1);\\n\\t}\\n\\tEthernet.socketClose(sockindex);\\n\\tsockindex = MAX_SOCK_NUM;\\n\\treturn 0;\\n}\\n\\nint EthernetClient::availableForWrite(void)\\n{\\n\\tif (sockindex >= MAX_SOCK_NUM) return 0;\\n\\treturn Ethernet.socketSendAvailable(sockindex);\\n}\\n\\nsize_t EthernetClient::write(uint8_t b)\\n{\\n\\treturn write(&b, 1);\\n}\\n\\nsize_t EthernetClient::write(const uint8_t *buf, size_t size)\\n{\\n\\tif (sockindex >= MAX_SOCK_NUM) return 0;\\n\\tif (Ethernet.socketSend(sockindex, buf, size)) return size;\\n\\tsetWriteError();\\n\\treturn 0;\\n}\\n\\nint EthernetClient::available()\\n{\\n\\tif (sockindex >= MAX_SOCK_NUM) return 0;\\n\\treturn Ethernet.socketRecvAvailable(sockindex);\\n\\t// TODO: do the Wiznet chips automatically retransmit TCP ACK\\n\\t// packets if they are lost by the network? Someday this should\\n\\t// be checked by a man-in-the-middle test which discards certain\\n\\t// packets. If ACKs aren't resent, we would need to check for\\n\\t// returning 0 here and after a timeout do another Sock_RECV\\n\\t// command to cause the Wiznet chip to resend the ACK packet.\\n}\\n\\nint EthernetClient::read(uint8_t *buf, size_t size)\\n{\\n\\tif (sockindex >= MAX_SOCK_NUM) return 0;\\n\\treturn Ethernet.socketRecv(sockindex, buf, size);\\n}\\n\\nint EthernetClient::peek()\\n{\\n\\tif (sockindex >= MAX_SOCK_NUM) return -1;\\n\\tif (!available()) return -1;\\n\\treturn Ethernet.socketPeek(sockindex);\\n}\\n\\nint EthernetClient::read()\\n{\\n\\tuint8_t b;\\n\\tif (Ethernet.socketRecv(sockindex, &b, 1) > 0) return b;\\n\\treturn -1;\\n}\\n\\nvoid EthernetClient::flush()\\n{\\n\\twhile (sockindex < MAX_SOCK_NUM) {\\n\\t\\tuint8_t stat = Ethernet.socketStatus(sockindex);\\n\\t\\tif (stat != SnSR::ESTABLISHED && stat != SnSR::CLOSE_WAIT) return;\\n\\t\\tif (Ethernet.socketSendAvailable(sockindex) >= W5100.SSIZE) return;\\n\\t}\\n}\\n\\nvoid EthernetClient::stop()\\n{\\n\\tif (sockindex >= MAX_SOCK_NUM) return;\\n\\n\\t// attempt to close the connection gracefully (send a FIN to other side)\\n\\tEthernet.socketDisconnect(sockindex);\\n\\tunsigned long start = millis();\\n\\n\\t// wait up to a second for the connection to close\\n\\tdo {\\n\\t\\tif (Ethernet.socketStatus(sockindex) == SnSR::CLOSED) {\\n\\t\\t\\tsockindex = MAX_SOCK_NUM;\\n\\t\\t\\treturn; // exit the loop\\n\\t\\t}\\n\\t\\tdelay(1);\\n\\t} while (millis() - start < _timeout);\\n\\n\\t// if it hasn't closed, close it forcefully\\n\\tEthernet.socketClose(sockindex);\\n\\tsockindex = MAX_SOCK_NUM;\\n}\\n\\nuint8_t EthernetClient::connected()\\n{\\n\\tif (sockindex >= MAX_SOCK_NUM) return 0;\\n\\n\\tuint8_t s = Ethernet.socketStatus(sockindex);\\n\\treturn !(s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::FIN_WAIT ||\\n\\t\\t(s == SnSR::CLOSE_WAIT && !available()));\\n}\\n\\nuint8_t EthernetClient::status()\\n{\\n\\tif (sockindex >= MAX_SOCK_NUM) return SnSR::CLOSED;\\n\\treturn Ethernet.socketStatus(sockindex);\\n}\\n\\n// the next function allows us to use the client returned by\\n// EthernetServer::available() as the condition in an if-statement.\\nbool EthernetClient::operator==(const EthernetClient& rhs)\\n{\\n\\tif (sockindex != rhs.sockindex) return false;\\n\\tif (sockindex >= MAX_SOCK_NUM) return false;\\n\\tif (rhs.sockindex >= MAX_SOCK_NUM) return false;\\n\\treturn true;\\n}\\n\\n// https://github.com/per1234/EthernetMod\\n// from: https://github.com/ntruchsess/Arduino-1/commit/937bce1a0bb2567f6d03b15df79525569377dabd\\nuint16_t EthernetClient::localPort()\\n{\\n\\tif (sockindex >= MAX_SOCK_NUM) return 0;\\n\\tuint16_t port;\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tport = W5100.readSnPORT(sockindex);\\n\\tSPI.endTransaction();\\n\\treturn port;\\n}\\n\\n// https://github.com/per1234/EthernetMod\\n// returns the remote IP address: http://forum.arduino.cc/index.php?topic=82416.0\\nIPAddress EthernetClient::remoteIP()\\n{\\n\\tif (sockindex >= MAX_SOCK_NUM) return IPAddress((uint32_t)0);\\n\\tuint8_t remoteIParray[4];\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tW5100.readSnDIPR(sockindex, remoteIParray);\\n\\tSPI.endTransaction();\\n\\treturn IPAddress(remoteIParray);\\n}\\n\\n// https://github.com/per1234/EthernetMod\\n// from: https://github.com/ntruchsess/Arduino-1/commit/ca37de4ba4ecbdb941f14ac1fe7dd40f3008af75\\nuint16_t EthernetClient::remotePort()\\n{\\n\\tif (sockindex >= MAX_SOCK_NUM) return 0;\\n\\tuint16_t port;\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\tport = W5100.readSnDPORT(sockindex);\\n\\tSPI.endTransaction();\\n\\treturn port;\\n}\\n\\n\\n\" }", "{ filename: \"src/EthernetClient.h\", code: \"// This file is in the public domain. No copyright is claimed.\\n\\n#include \\\"Ethernet.h\\\"\\n\" }", "{ filename: \"src/EthernetServer.cpp\", code: \"/* Copyright 2018 Paul Stoffregen\\n *\\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this\\n * software and associated documentation files (the \\\"Software\\\"), to deal in the Software\\n * without restriction, including without limitation the rights to use, copy, modify,\\n * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\\n * permit persons to whom the Software is furnished to do so, subject to the following\\n * conditions:\\n *\\n * The above copyright notice and this permission notice shall be included in all\\n * copies or substantial portions of the Software.\\n *\\n * THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\\n */\\n\\n#include \\n#include \\\"Ethernet.h\\\"\\n#include \\\"w5100.h\\\"\\n\\nuint16_t EthernetServer::server_port[MAX_SOCK_NUM];\\n\\n\\nvoid EthernetServer::begin()\\n{\\n\\tuint8_t sockindex = Ethernet.socketBegin(SnMR::TCP, _port);\\n\\tif (sockindex < MAX_SOCK_NUM) {\\n\\t\\tif (Ethernet.socketListen(sockindex)) {\\n\\t\\t\\tserver_port[sockindex] = _port;\\n\\t\\t} else {\\n\\t\\t\\tEthernet.socketDisconnect(sockindex);\\n\\t\\t}\\n\\t}\\n}\\n\\nEthernetClient EthernetServer::available()\\n{\\n\\tbool listening = false;\\n\\tuint8_t sockindex = MAX_SOCK_NUM;\\n\\tuint8_t chip, maxindex=MAX_SOCK_NUM;\\n\\n\\tchip = W5100.getChip();\\n\\tif (!chip) return EthernetClient(MAX_SOCK_NUM);\\n#if MAX_SOCK_NUM > 4\\n\\tif (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets\\n#endif\\n\\tfor (uint8_t i=0; i < maxindex; i++) {\\n\\t\\tif (server_port[i] == _port) {\\n\\t\\t\\tuint8_t stat = Ethernet.socketStatus(i);\\n\\t\\t\\tif (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT) {\\n\\t\\t\\t\\tif (Ethernet.socketRecvAvailable(i) > 0) {\\n\\t\\t\\t\\t\\tsockindex = i;\\n\\t\\t\\t\\t} else {\\n\\t\\t\\t\\t\\t// remote host closed connection, our end still open\\n\\t\\t\\t\\t\\tif (stat == SnSR::CLOSE_WAIT) {\\n\\t\\t\\t\\t\\t\\tEthernet.socketDisconnect(i);\\n\\t\\t\\t\\t\\t\\t// status becomes LAST_ACK for short time\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t} else if (stat == SnSR::LISTEN) {\\n\\t\\t\\t\\tlistening = true;\\n\\t\\t\\t} else if (stat == SnSR::CLOSED) {\\n\\t\\t\\t\\tserver_port[i] = 0;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\tif (!listening) begin();\\n\\treturn EthernetClient(sockindex);\\n}\\n\\nEthernetClient EthernetServer::accept()\\n{\\n\\tbool listening = false;\\n\\tuint8_t sockindex = MAX_SOCK_NUM;\\n\\tuint8_t chip, maxindex=MAX_SOCK_NUM;\\n\\n\\tchip = W5100.getChip();\\n\\tif (!chip) return EthernetClient(MAX_SOCK_NUM);\\n#if MAX_SOCK_NUM > 4\\n\\tif (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets\\n#endif\\n\\tfor (uint8_t i=0; i < maxindex; i++) {\\n\\t\\tif (server_port[i] == _port) {\\n\\t\\t\\tuint8_t stat = Ethernet.socketStatus(i);\\n\\t\\t\\tif (sockindex == MAX_SOCK_NUM &&\\n\\t\\t\\t (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT)) {\\n\\t\\t\\t\\t// Return the connected client even if no data received.\\n\\t\\t\\t\\t// Some protocols like FTP expect the server to send the\\n\\t\\t\\t\\t// first data.\\n\\t\\t\\t\\tsockindex = i;\\n\\t\\t\\t\\tserver_port[i] = 0; // only return the client once\\n\\t\\t\\t} else if (stat == SnSR::LISTEN) {\\n\\t\\t\\t\\tlistening = true;\\n\\t\\t\\t} else if (stat == SnSR::CLOSED) {\\n\\t\\t\\t\\tserver_port[i] = 0;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\tif (!listening) begin();\\n\\treturn EthernetClient(sockindex);\\n}\\n\\nEthernetServer::operator bool()\\n{\\n\\tuint8_t maxindex=MAX_SOCK_NUM;\\n#if MAX_SOCK_NUM > 4\\n\\tif (W5100.getChip() == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets\\n#endif\\n\\tfor (uint8_t i=0; i < maxindex; i++) {\\n\\t\\tif (server_port[i] == _port) {\\n\\t\\t\\tif (Ethernet.socketStatus(i) == SnSR::LISTEN) {\\n\\t\\t\\t\\treturn true; // server is listening for incoming clients\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\treturn false;\\n}\\n\\n#if 0\\nvoid EthernetServer::statusreport()\\n{\\n\\tSerial.printf(\\\"EthernetServer, port=%d\\\\n\\\", _port);\\n\\tfor (uint8_t i=0; i < MAX_SOCK_NUM; i++) {\\n\\t\\tuint16_t port = server_port[i];\\n\\t\\tuint8_t stat = Ethernet.socketStatus(i);\\n\\t\\tconst char *name;\\n\\t\\tswitch (stat) {\\n\\t\\t\\tcase 0x00: name = \\\"CLOSED\\\"; break;\\n\\t\\t\\tcase 0x13: name = \\\"INIT\\\"; break;\\n\\t\\t\\tcase 0x14: name = \\\"LISTEN\\\"; break;\\n\\t\\t\\tcase 0x15: name = \\\"SYNSENT\\\"; break;\\n\\t\\t\\tcase 0x16: name = \\\"SYNRECV\\\"; break;\\n\\t\\t\\tcase 0x17: name = \\\"ESTABLISHED\\\"; break;\\n\\t\\t\\tcase 0x18: name = \\\"FIN_WAIT\\\"; break;\\n\\t\\t\\tcase 0x1A: name = \\\"CLOSING\\\"; break;\\n\\t\\t\\tcase 0x1B: name = \\\"TIME_WAIT\\\"; break;\\n\\t\\t\\tcase 0x1C: name = \\\"CLOSE_WAIT\\\"; break;\\n\\t\\t\\tcase 0x1D: name = \\\"LAST_ACK\\\"; break;\\n\\t\\t\\tcase 0x22: name = \\\"UDP\\\"; break;\\n\\t\\t\\tcase 0x32: name = \\\"IPRAW\\\"; break;\\n\\t\\t\\tcase 0x42: name = \\\"MACRAW\\\"; break;\\n\\t\\t\\tcase 0x5F: name = \\\"PPPOE\\\"; break;\\n\\t\\t\\tdefault: name = \\\"???\\\";\\n\\t\\t}\\n\\t\\tint avail = Ethernet.socketRecvAvailable(i);\\n\\t\\tSerial.printf(\\\" %d: port=%d, status=%s (0x%02X), avail=%d\\\\n\\\",\\n\\t\\t\\ti, port, name, stat, avail);\\n\\t}\\n}\\n#endif\\n\\nsize_t EthernetServer::write(uint8_t b)\\n{\\n\\treturn write(&b, 1);\\n}\\n\\nsize_t EthernetServer::write(const uint8_t *buffer, size_t size)\\n{\\n\\tuint8_t chip, maxindex=MAX_SOCK_NUM;\\n\\n\\tchip = W5100.getChip();\\n\\tif (!chip) return 0;\\n#if MAX_SOCK_NUM > 4\\n\\tif (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets\\n#endif\\n\\tavailable();\\n\\tfor (uint8_t i=0; i < maxindex; i++) {\\n\\t\\tif (server_port[i] == _port) {\\n\\t\\t\\tif (Ethernet.socketStatus(i) == SnSR::ESTABLISHED) {\\n\\t\\t\\t\\tEthernet.socketSend(i, buffer, size);\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\treturn size;\\n}\\n\" }", "{ filename: \"src/EthernetServer.h\", code: \"// This file is in the public domain. No copyright is claimed.\\n\\n#include \\\"Ethernet.h\\\"\\n\" }", "{ filename: \"src/SPI.cpp\", code: \"/*\\n * Copyright (c) 2010 by Cristian Maglie \\n * Copyright (c) 2014 by Paul Stoffregen (Transaction API)\\n * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR)\\n * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes)\\n * SPI Master library for arduino.\\n *\\n * This file is free software; you can redistribute it and/or modify\\n * it under the terms of either the GNU General Public License version 2\\n * or the GNU Lesser General Public License version 2.1, both as\\n * published by the Free Software Foundation.\\n */\\n\\n#include \\\"SPI.h\\\"\\n\\nSPIClass SPI;\\n\\nuint8_t SPIClass::initialized = 0;\\nuint8_t SPIClass::interruptMode = 0;\\nuint8_t SPIClass::interruptMask = 0;\\nuint8_t SPIClass::interruptSave = 0;\\n#ifdef SPI_TRANSACTION_MISMATCH_LED\\nuint8_t SPIClass::inTransactionFlag = 0;\\n#endif\\n\\nvoid SPIClass::begin()\\n{\\n uint8_t sreg = SREG;\\n noInterrupts(); // Protect from a scheduler and prevent transactionBegin\\n if (!initialized) {\\n // Set SS to high so a connected chip will be \\\"deselected\\\" by default\\n uint8_t port = digitalPinToPort(SS);\\n uint8_t bit = digitalPinToBitMask(SS);\\n volatile uint8_t *reg = portModeRegister(port);\\n\\n // if the SS pin is not already configured as an output\\n // then set it high (to enable the internal pull-up resistor)\\n if(!(*reg & bit)){\\n digitalWrite(SS, HIGH);\\n }\\n\\n // When the SS pin is set as OUTPUT, it can be used as\\n // a general purpose output port (it doesn't influence\\n // SPI operations).\\n pinMode(SS, OUTPUT);\\n\\n // Warning: if the SS pin ever becomes a LOW INPUT then SPI\\n // automatically switches to Slave, so the data direction of\\n // the SS pin MUST be kept as OUTPUT.\\n SPCR |= _BV(MSTR);\\n SPCR |= _BV(SPE);\\n\\n // Set direction register for SCK and MOSI pin.\\n // MISO pin automatically overrides to INPUT.\\n // By doing this AFTER enabling SPI, we avoid accidentally\\n // clocking in a single bit since the lines go directly\\n // from \\\"input\\\" to SPI control.\\n // http://code.google.com/p/arduino/issues/detail?id=888\\n pinMode(SCK, OUTPUT);\\n pinMode(MOSI, OUTPUT);\\n }\\n initialized++; // reference count\\n SREG = sreg;\\n}\\n\\nvoid SPIClass::end() {\\n uint8_t sreg = SREG;\\n noInterrupts(); // Protect from a scheduler and prevent transactionBegin\\n // Decrease the reference counter\\n if (initialized)\\n initialized--;\\n // If there are no more references disable SPI\\n if (!initialized) {\\n SPCR &= ~_BV(SPE);\\n interruptMode = 0;\\n #ifdef SPI_TRANSACTION_MISMATCH_LED\\n inTransactionFlag = 0;\\n #endif\\n }\\n SREG = sreg;\\n}\\n\\n// mapping of interrupt numbers to bits within SPI_AVR_EIMSK\\n#if defined(__AVR_ATmega32U4__)\\n #define SPI_INT0_MASK (1<\\n * Copyright (c) 2014 by Paul Stoffregen (Transaction API)\\n * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR)\\n * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes)\\n * SPI Master library for arduino.\\n *\\n * This file is free software; you can redistribute it and/or modify\\n * it under the terms of either the GNU General Public License version 2\\n * or the GNU Lesser General Public License version 2.1, both as\\n * published by the Free Software Foundation.\\n */\\n\\n#ifndef _SPI_H_INCLUDED\\n#define _SPI_H_INCLUDED\\n\\n#include \\n\\n// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),\\n// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)\\n#define SPI_HAS_TRANSACTION 1\\n\\n// SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method\\n#define SPI_HAS_NOTUSINGINTERRUPT 1\\n\\n// SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version.\\n// This way when there is a bug fix you can check this define to alert users\\n// of your code if it uses better version of this library.\\n// This also implies everything that SPI_HAS_TRANSACTION as documented above is\\n// available too.\\n#define SPI_ATOMIC_VERSION 1\\n\\n// Uncomment this line to add detection of mismatched begin/end transactions.\\n// A mismatch occurs if other libraries fail to use SPI.endTransaction() for\\n// each SPI.beginTransaction(). Connect an LED to this pin. The LED will turn\\n// on if any mismatch is ever detected.\\n//#define SPI_TRANSACTION_MISMATCH_LED 5\\n\\n#ifndef LSBFIRST\\n#define LSBFIRST 0\\n#endif\\n#ifndef MSBFIRST\\n#define MSBFIRST 1\\n#endif\\n\\n#define SPI_CLOCK_DIV4 0x00\\n#define SPI_CLOCK_DIV16 0x01\\n#define SPI_CLOCK_DIV64 0x02\\n#define SPI_CLOCK_DIV128 0x03\\n#define SPI_CLOCK_DIV2 0x04\\n#define SPI_CLOCK_DIV8 0x05\\n#define SPI_CLOCK_DIV32 0x06\\n\\n#define SPI_MODE0 0x00\\n#define SPI_MODE1 0x04\\n#define SPI_MODE2 0x08\\n#define SPI_MODE3 0x0C\\n\\n#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR\\n#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR\\n#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR\\n\\n// define SPI_AVR_EIMSK for AVR boards with external interrupt pins\\n#if defined(EIMSK)\\n #define SPI_AVR_EIMSK EIMSK\\n#elif defined(GICR)\\n #define SPI_AVR_EIMSK GICR\\n#elif defined(GIMSK)\\n #define SPI_AVR_EIMSK GIMSK\\n#endif\\n\\nclass SPISettings {\\npublic:\\n SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {\\n if (__builtin_constant_p(clock)) {\\n init_AlwaysInline(clock, bitOrder, dataMode);\\n } else {\\n init_MightInline(clock, bitOrder, dataMode);\\n }\\n }\\n SPISettings() {\\n init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);\\n }\\nprivate:\\n void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {\\n init_AlwaysInline(clock, bitOrder, dataMode);\\n }\\n void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)\\n __attribute__((__always_inline__)) {\\n // Clock settings are defined as follows. Note that this shows SPI2X\\n // inverted, so the bits form increasing numbers. Also note that\\n // fosc/64 appears twice\\n // SPR1 SPR0 ~SPI2X Freq\\n // 0 0 0 fosc/2\\n // 0 0 1 fosc/4\\n // 0 1 0 fosc/8\\n // 0 1 1 fosc/16\\n // 1 0 0 fosc/32\\n // 1 0 1 fosc/64\\n // 1 1 0 fosc/64\\n // 1 1 1 fosc/128\\n\\n // We find the fastest clock that is less than or equal to the\\n // given clock rate. The clock divider that results in clock_setting\\n // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the\\n // slowest (128 == 2 ^^ 7, so clock_div = 6).\\n uint8_t clockDiv;\\n\\n // When the clock is known at compile time, use this if-then-else\\n // cascade, which the compiler knows how to completely optimize\\n // away. When clock is not known, use a loop instead, which generates\\n // shorter code.\\n if (__builtin_constant_p(clock)) {\\n if (clock >= F_CPU / 2) {\\n clockDiv = 0;\\n } else if (clock >= F_CPU / 4) {\\n clockDiv = 1;\\n } else if (clock >= F_CPU / 8) {\\n clockDiv = 2;\\n } else if (clock >= F_CPU / 16) {\\n clockDiv = 3;\\n } else if (clock >= F_CPU / 32) {\\n clockDiv = 4;\\n } else if (clock >= F_CPU / 64) {\\n clockDiv = 5;\\n } else {\\n clockDiv = 6;\\n }\\n } else {\\n uint32_t clockSetting = F_CPU / 2;\\n clockDiv = 0;\\n while (clockDiv < 6 && clock < clockSetting) {\\n clockSetting /= 2;\\n clockDiv++;\\n }\\n }\\n\\n // Compensate for the duplicate fosc/64\\n if (clockDiv == 6)\\n clockDiv = 7;\\n\\n // Invert the SPI2X bit\\n clockDiv ^= 0x1;\\n\\n // Pack into the SPISettings class\\n spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) |\\n (dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK);\\n spsr = clockDiv & SPI_2XCLOCK_MASK;\\n }\\n uint8_t spcr;\\n uint8_t spsr;\\n friend class SPIClass;\\n};\\n\\n\\nclass SPIClass {\\npublic:\\n // Initialize the SPI library\\n static void begin();\\n\\n // If SPI is used from within an interrupt, this function registers\\n // that interrupt with the SPI library, so beginTransaction() can\\n // prevent conflicts. The input interruptNumber is the number used\\n // with attachInterrupt. If SPI is used from a different interrupt\\n // (eg, a timer), interruptNumber should be 255.\\n static void usingInterrupt(uint8_t interruptNumber);\\n // And this does the opposite.\\n static void notUsingInterrupt(uint8_t interruptNumber);\\n // Note: the usingInterrupt and notUsingInterrupt functions should\\n // not to be called from ISR context or inside a transaction.\\n // For details see:\\n // https://github.com/arduino/Arduino/pull/2381\\n // https://github.com/arduino/Arduino/pull/2449\\n\\n // Before using SPI.transfer() or asserting chip select pins,\\n // this function is used to gain exclusive access to the SPI bus\\n // and configure the correct settings.\\n inline static void beginTransaction(SPISettings settings) {\\n if (interruptMode > 0) {\\n uint8_t sreg = SREG;\\n noInterrupts();\\n\\n #ifdef SPI_AVR_EIMSK\\n if (interruptMode == 1) {\\n interruptSave = SPI_AVR_EIMSK;\\n SPI_AVR_EIMSK &= ~interruptMask;\\n SREG = sreg;\\n } else\\n #endif\\n {\\n interruptSave = sreg;\\n }\\n }\\n\\n #ifdef SPI_TRANSACTION_MISMATCH_LED\\n if (inTransactionFlag) {\\n pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);\\n digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);\\n }\\n inTransactionFlag = 1;\\n #endif\\n\\n SPCR = settings.spcr;\\n SPSR = settings.spsr;\\n }\\n\\n // Write to the SPI bus (MOSI pin) and also receive (MISO pin)\\n inline static uint8_t transfer(uint8_t data) {\\n SPDR = data;\\n /*\\n * The following NOP introduces a small delay that can prevent the wait\\n * loop form iterating when running at the maximum speed. This gives\\n * about 10% more speed, even if it seems counter-intuitive. At lower\\n * speeds it is unnoticed.\\n */\\n asm volatile(\\\"nop\\\");\\n while (!(SPSR & _BV(SPIF))) ; // wait\\n return SPDR;\\n }\\n inline static uint16_t transfer16(uint16_t data) {\\n union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;\\n in.val = data;\\n if (!(SPCR & _BV(DORD))) {\\n SPDR = in.msb;\\n asm volatile(\\\"nop\\\"); // See transfer(uint8_t) function\\n while (!(SPSR & _BV(SPIF))) ;\\n out.msb = SPDR;\\n SPDR = in.lsb;\\n asm volatile(\\\"nop\\\");\\n while (!(SPSR & _BV(SPIF))) ;\\n out.lsb = SPDR;\\n } else {\\n SPDR = in.lsb;\\n asm volatile(\\\"nop\\\");\\n while (!(SPSR & _BV(SPIF))) ;\\n out.lsb = SPDR;\\n SPDR = in.msb;\\n asm volatile(\\\"nop\\\");\\n while (!(SPSR & _BV(SPIF))) ;\\n out.msb = SPDR;\\n }\\n return out.val;\\n }\\n inline static void transfer(void *buf, size_t count) {\\n if (count == 0) return;\\n uint8_t *p = (uint8_t *)buf;\\n SPDR = *p;\\n while (--count > 0) {\\n uint8_t out = *(p + 1);\\n while (!(SPSR & _BV(SPIF))) ;\\n uint8_t in = SPDR;\\n SPDR = out;\\n *p++ = in;\\n }\\n while (!(SPSR & _BV(SPIF))) ;\\n *p = SPDR;\\n }\\n // After performing a group of transfers and releasing the chip select\\n // signal, this function allows others to access the SPI bus\\n inline static void endTransaction(void) {\\n #ifdef SPI_TRANSACTION_MISMATCH_LED\\n if (!inTransactionFlag) {\\n pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);\\n digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);\\n }\\n inTransactionFlag = 0;\\n #endif\\n\\n if (interruptMode > 0) {\\n #ifdef SPI_AVR_EIMSK\\n uint8_t sreg = SREG;\\n #endif\\n noInterrupts();\\n #ifdef SPI_AVR_EIMSK\\n if (interruptMode == 1) {\\n SPI_AVR_EIMSK = interruptSave;\\n SREG = sreg;\\n } else\\n #endif\\n {\\n SREG = interruptSave;\\n }\\n }\\n }\\n\\n // Disable the SPI bus\\n static void end();\\n\\n // This function is deprecated. New applications should use\\n // beginTransaction() to configure SPI settings.\\n inline static void setBitOrder(uint8_t bitOrder) {\\n if (bitOrder == LSBFIRST) SPCR |= _BV(DORD);\\n else SPCR &= ~(_BV(DORD));\\n }\\n // This function is deprecated. New applications should use\\n // beginTransaction() to configure SPI settings.\\n inline static void setDataMode(uint8_t dataMode) {\\n SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;\\n }\\n // This function is deprecated. New applications should use\\n // beginTransaction() to configure SPI settings.\\n inline static void setClockDivider(uint8_t clockDiv) {\\n SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK);\\n SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK);\\n }\\n // These undocumented functions should not be used. SPI.transfer()\\n // polls the hardware flag which is automatically cleared as the\\n // AVR responds to SPI's interrupt\\n inline static void attachInterrupt() { SPCR |= _BV(SPIE); }\\n inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); }\\n\\nprivate:\\n static uint8_t initialized;\\n static uint8_t interruptMode; // 0=none, 1=mask, 2=global\\n static uint8_t interruptMask; // which interrupts to mask\\n static uint8_t interruptSave; // temp storage, to restore state\\n #ifdef SPI_TRANSACTION_MISMATCH_LED\\n static uint8_t inTransactionFlag;\\n #endif\\n};\\n\\nextern SPIClass SPI;\\n\\n#endif\\n\" }", "{ filename: \"src/w5100.cpp\", code: \"/*\\n * Copyright 2018 Paul Stoffregen\\n * Copyright (c) 2010 by Cristian Maglie \\n *\\n * This file is free software; you can redistribute it and/or modify\\n * it under the terms of either the GNU General Public License version 2\\n * or the GNU Lesser General Public License version 2.1, both as\\n * published by the Free Software Foundation.\\n */\\n\\n#include \\n#include \\\"Ethernet.h\\\"\\n#include \\\"w5100.h\\\"\\n\\n\\n/***************************************************/\\n/** Default SS pin setting **/\\n/***************************************************/\\n\\n// If variant.h or other headers specifically define the\\n// default SS pin for ethernet, use it.\\n#if defined(PIN_SPI_SS_ETHERNET_LIB)\\n#define SS_PIN_DEFAULT PIN_SPI_SS_ETHERNET_LIB\\n\\n// MKR boards default to pin 5 for MKR ETH\\n// Pins 8-10 are MOSI/SCK/MISO on MRK, so don't use pin 10\\n#elif defined(USE_ARDUINO_MKR_PIN_LAYOUT) || defined(ARDUINO_SAMD_MKRZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWAN1300)\\n#define SS_PIN_DEFAULT 5\\n\\n// For boards using AVR, assume shields with SS on pin 10\\n// will be used. This allows for Arduino Mega (where\\n// SS is pin 53) and Arduino Leonardo (where SS is pin 17)\\n// to work by default with Arduino Ethernet Shield R2 & R3.\\n#elif defined(__AVR__)\\n#define SS_PIN_DEFAULT 10\\n\\n// If variant.h or other headers define these names\\n// use them if none of the other cases match\\n#elif defined(PIN_SPI_SS)\\n#define SS_PIN_DEFAULT PIN_SPI_SS\\n#elif defined(CORE_SS0_PIN)\\n#define SS_PIN_DEFAULT CORE_SS0_PIN\\n\\n// As a final fallback, use pin 10\\n#else\\n#define SS_PIN_DEFAULT 10\\n#endif\\n\\n\\n\\n\\n// W5100 controller instance\\nuint8_t W5100Class::chip = 0;\\nuint8_t W5100Class::CH_BASE_MSB;\\nuint8_t W5100Class::ss_pin = SS_PIN_DEFAULT;\\n#ifdef ETHERNET_LARGE_BUFFERS\\nuint16_t W5100Class::SSIZE = 2048;\\nuint16_t W5100Class::SMASK = 0x07FF;\\n#endif\\nW5100Class W5100;\\n\\n// pointers and bitmasks for optimized SS pin\\n#if defined(__AVR__)\\n volatile uint8_t * W5100Class::ss_pin_reg;\\n uint8_t W5100Class::ss_pin_mask;\\n#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)\\n volatile uint8_t * W5100Class::ss_pin_reg;\\n#elif defined(__MKL26Z64__)\\n volatile uint8_t * W5100Class::ss_pin_reg;\\n uint8_t W5100Class::ss_pin_mask;\\n#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)\\n volatile uint32_t * W5100Class::ss_pin_reg;\\n uint32_t W5100Class::ss_pin_mask;\\n#elif defined(__PIC32MX__)\\n volatile uint32_t * W5100Class::ss_pin_reg;\\n uint32_t W5100Class::ss_pin_mask;\\n#elif defined(ARDUINO_ARCH_ESP8266)\\n volatile uint32_t * W5100Class::ss_pin_reg;\\n uint32_t W5100Class::ss_pin_mask;\\n#elif defined(__SAMD21G18A__)\\n volatile uint32_t * W5100Class::ss_pin_reg;\\n uint32_t W5100Class::ss_pin_mask;\\n#endif\\n\\n\\nuint8_t W5100Class::init(void)\\n{\\n\\tstatic bool initialized = false;\\n\\tuint8_t i;\\n\\n\\tif (initialized) return 1;\\n\\n\\t// Many Ethernet shields have a CAT811 or similar reset chip\\n\\t// connected to W5100 or W5200 chips. The W5200 will not work at\\n\\t// all, and may even drive its MISO pin, until given an active low\\n\\t// reset pulse! The CAT811 has a 240 ms typical pulse length, and\\n\\t// a 400 ms worst case maximum pulse length. MAX811 has a worst\\n\\t// case maximum 560 ms pulse length. This delay is meant to wait\\n\\t// until the reset pulse is ended. If your hardware has a shorter\\n\\t// reset time, this can be edited or removed.\\n\\tdelay(560);\\n\\t//Serial.println(\\\"w5100 init\\\");\\n\\n\\tSPI.begin();\\n\\tinitSS();\\n\\tresetSS();\\n\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\n\\t// Attempt W5200 detection first, because W5200 does not properly\\n\\t// reset its SPI state when CS goes high (inactive). Communication\\n\\t// from detecting the other chips can leave the W5200 in a state\\n\\t// where it won't recover, unless given a reset pulse.\\n\\tif (isW5200()) {\\n\\t\\tCH_BASE_MSB = 0x40;\\n#ifdef ETHERNET_LARGE_BUFFERS\\n#if MAX_SOCK_NUM <= 1\\n\\t\\tSSIZE = 16384;\\n#elif MAX_SOCK_NUM <= 2\\n\\t\\tSSIZE = 8192;\\n#elif MAX_SOCK_NUM <= 4\\n\\t\\tSSIZE = 4096;\\n#else\\n\\t\\tSSIZE = 2048;\\n#endif\\n\\t\\tSMASK = SSIZE - 1;\\n#endif\\n\\t\\tfor (i=0; i> 10);\\n\\t\\t\\twriteSnTX_SIZE(i, SSIZE >> 10);\\n\\t\\t}\\n\\t\\tfor (; i<8; i++) {\\n\\t\\t\\twriteSnRX_SIZE(i, 0);\\n\\t\\t\\twriteSnTX_SIZE(i, 0);\\n\\t\\t}\\n\\t// Try W5500 next. Wiznet finally seems to have implemented\\n\\t// SPI well with this chip. It appears to be very resilient,\\n\\t// so try it after the fragile W5200\\n\\t} else if (isW5500()) {\\n\\t\\tCH_BASE_MSB = 0x10;\\n#ifdef ETHERNET_LARGE_BUFFERS\\n#if MAX_SOCK_NUM <= 1\\n\\t\\tSSIZE = 16384;\\n#elif MAX_SOCK_NUM <= 2\\n\\t\\tSSIZE = 8192;\\n#elif MAX_SOCK_NUM <= 4\\n\\t\\tSSIZE = 4096;\\n#else\\n\\t\\tSSIZE = 2048;\\n#endif\\n\\t\\tSMASK = SSIZE - 1;\\n\\t\\tfor (i=0; i> 10);\\n\\t\\t\\twriteSnTX_SIZE(i, SSIZE >> 10);\\n\\t\\t}\\n\\t\\tfor (; i<8; i++) {\\n\\t\\t\\twriteSnRX_SIZE(i, 0);\\n\\t\\t\\twriteSnTX_SIZE(i, 0);\\n\\t\\t}\\n#endif\\n\\t// Try W5100 last. This simple chip uses fixed 4 byte frames\\n\\t// for every 8 bit access. Terribly inefficient, but so simple\\n\\t// it recovers from \\\"hearing\\\" unsuccessful W5100 or W5200\\n\\t// communication. W5100 is also the only chip without a VERSIONR\\n\\t// register for identification, so we check this last.\\n\\t} else if (isW5100()) {\\n\\t\\tCH_BASE_MSB = 0x04;\\n#ifdef ETHERNET_LARGE_BUFFERS\\n#if MAX_SOCK_NUM <= 1\\n\\t\\tSSIZE = 8192;\\n\\t\\twriteTMSR(0x03);\\n\\t\\twriteRMSR(0x03);\\n#elif MAX_SOCK_NUM <= 2\\n\\t\\tSSIZE = 4096;\\n\\t\\twriteTMSR(0x0A);\\n\\t\\twriteRMSR(0x0A);\\n#else\\n\\t\\tSSIZE = 2048;\\n\\t\\twriteTMSR(0x55);\\n\\t\\twriteRMSR(0x55);\\n#endif\\n\\t\\tSMASK = SSIZE - 1;\\n#else\\n\\t\\twriteTMSR(0x55);\\n\\t\\twriteRMSR(0x55);\\n#endif\\n\\t// No hardware seems to be present. Or it could be a W5200\\n\\t// that's heard other SPI communication if its chip select\\n\\t// pin wasn't high when a SD card or other SPI chip was used.\\n\\t} else {\\n\\t\\t//Serial.println(\\\"no chip :-(\\\");\\n\\t\\tchip = 0;\\n\\t\\tSPI.endTransaction();\\n\\t\\treturn 0; // no known chip is responding :-(\\n\\t}\\n\\tSPI.endTransaction();\\n\\tinitialized = true;\\n\\treturn 1; // successful init\\n}\\n\\n// Soft reset the Wiznet chip, by writing to its MR register reset bit\\nuint8_t W5100Class::softReset(void)\\n{\\n\\tuint16_t count=0;\\n\\n\\t//Serial.println(\\\"Wiznet soft reset\\\");\\n\\t// write to reset bit\\n\\twriteMR(0x80);\\n\\t// then wait for soft reset to complete\\n\\tdo {\\n\\t\\tuint8_t mr = readMR();\\n\\t\\t//Serial.print(\\\"mr=\\\");\\n\\t\\t//Serial.println(mr, HEX);\\n\\t\\tif (mr == 0) return 1;\\n\\t\\tdelay(1);\\n\\t} while (++count < 20);\\n\\treturn 0;\\n}\\n\\nuint8_t W5100Class::isW5100(void)\\n{\\n\\tchip = 51;\\n\\t//Serial.println(\\\"w5100.cpp: detect W5100 chip\\\");\\n\\tif (!softReset()) return 0;\\n\\twriteMR(0x10);\\n\\tif (readMR() != 0x10) return 0;\\n\\twriteMR(0x12);\\n\\tif (readMR() != 0x12) return 0;\\n\\twriteMR(0x00);\\n\\tif (readMR() != 0x00) return 0;\\n\\t//Serial.println(\\\"chip is W5100\\\");\\n\\treturn 1;\\n}\\n\\nuint8_t W5100Class::isW5200(void)\\n{\\n\\tchip = 52;\\n\\t//Serial.println(\\\"w5100.cpp: detect W5200 chip\\\");\\n\\tif (!softReset()) return 0;\\n\\twriteMR(0x08);\\n\\tif (readMR() != 0x08) return 0;\\n\\twriteMR(0x10);\\n\\tif (readMR() != 0x10) return 0;\\n\\twriteMR(0x00);\\n\\tif (readMR() != 0x00) return 0;\\n\\tint ver = readVERSIONR_W5200();\\n\\t//Serial.print(\\\"version=\\\");\\n\\t//Serial.println(ver);\\n\\tif (ver != 3) return 0;\\n\\t//Serial.println(\\\"chip is W5200\\\");\\n\\treturn 1;\\n}\\n\\nuint8_t W5100Class::isW5500(void)\\n{\\n\\tchip = 55;\\n\\t//Serial.println(\\\"w5100.cpp: detect W5500 chip\\\");\\n\\tif (!softReset()) return 0;\\n\\twriteMR(0x08);\\n\\tif (readMR() != 0x08) return 0;\\n\\twriteMR(0x10);\\n\\tif (readMR() != 0x10) return 0;\\n\\twriteMR(0x00);\\n\\tif (readMR() != 0x00) return 0;\\n\\tint ver = readVERSIONR_W5500();\\n\\t//Serial.print(\\\"version=\\\");\\n\\t//Serial.println(ver);\\n\\tif (ver != 4) return 0;\\n\\t//Serial.println(\\\"chip is W5500\\\");\\n\\treturn 1;\\n}\\n\\nW5100Linkstatus W5100Class::getLinkStatus()\\n{\\n\\tuint8_t phystatus;\\n\\n\\tif (!init()) return UNKNOWN;\\n\\tswitch (chip) {\\n\\t case 52:\\n\\t\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\t\\tphystatus = readPSTATUS_W5200();\\n\\t\\tSPI.endTransaction();\\n\\t\\tif (phystatus & 0x20) return LINK_ON;\\n\\t\\treturn LINK_OFF;\\n\\t case 55:\\n\\t\\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\\n\\t\\tphystatus = readPHYCFGR_W5500();\\n\\t\\tSPI.endTransaction();\\n\\t\\tif (phystatus & 0x01) return LINK_ON;\\n\\t\\treturn LINK_OFF;\\n\\t default:\\n\\t\\treturn UNKNOWN;\\n\\t}\\n}\\n\\nuint16_t W5100Class::write(uint16_t addr, const uint8_t *buf, uint16_t len)\\n{\\n\\tuint8_t cmd[8];\\n\\n\\tif (chip == 51) {\\n\\t\\tfor (uint16_t i=0; i> 8);\\n\\t\\t\\tSPI.transfer(addr & 0xFF);\\n\\t\\t\\taddr++;\\n\\t\\t\\tSPI.transfer(buf[i]);\\n\\t\\t\\tresetSS();\\n\\t\\t}\\n\\t} else if (chip == 52) {\\n\\t\\tsetSS();\\n\\t\\tcmd[0] = addr >> 8;\\n\\t\\tcmd[1] = addr & 0xFF;\\n\\t\\tcmd[2] = ((len >> 8) & 0x7F) | 0x80;\\n\\t\\tcmd[3] = len & 0xFF;\\n\\t\\tSPI.transfer(cmd, 4);\\n#ifdef SPI_HAS_TRANSFER_BUF\\n\\t\\tSPI.transfer(buf, NULL, len);\\n#else\\n\\t\\t// TODO: copy 8 bytes at a time to cmd[] and block transfer\\n\\t\\tfor (uint16_t i=0; i < len; i++) {\\n\\t\\t\\tSPI.transfer(buf[i]);\\n\\t\\t}\\n#endif\\n\\t\\tresetSS();\\n\\t} else { // chip == 55\\n\\t\\tsetSS();\\n\\t\\tif (addr < 0x100) {\\n\\t\\t\\t// common registers 00nn\\n\\t\\t\\tcmd[0] = 0;\\n\\t\\t\\tcmd[1] = addr & 0xFF;\\n\\t\\t\\tcmd[2] = 0x04;\\n\\t\\t} else if (addr < 0x8000) {\\n\\t\\t\\t// socket registers 10nn, 11nn, 12nn, 13nn, etc\\n\\t\\t\\tcmd[0] = 0;\\n\\t\\t\\tcmd[1] = addr & 0xFF;\\n\\t\\t\\tcmd[2] = ((addr >> 3) & 0xE0) | 0x0C;\\n\\t\\t} else if (addr < 0xC000) {\\n\\t\\t\\t// transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc\\n\\t\\t\\t// 10## #nnn nnnn nnnn\\n\\t\\t\\tcmd[0] = addr >> 8;\\n\\t\\t\\tcmd[1] = addr & 0xFF;\\n\\t\\t\\t#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1\\n\\t\\t\\tcmd[2] = 0x14; // 16K buffers\\n\\t\\t\\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2\\n\\t\\t\\tcmd[2] = ((addr >> 8) & 0x20) | 0x14; // 8K buffers\\n\\t\\t\\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4\\n\\t\\t\\tcmd[2] = ((addr >> 7) & 0x60) | 0x14; // 4K buffers\\n\\t\\t\\t#else\\n\\t\\t\\tcmd[2] = ((addr >> 6) & 0xE0) | 0x14; // 2K buffers\\n\\t\\t\\t#endif\\n\\t\\t} else {\\n\\t\\t\\t// receive buffers\\n\\t\\t\\tcmd[0] = addr >> 8;\\n\\t\\t\\tcmd[1] = addr & 0xFF;\\n\\t\\t\\t#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1\\n\\t\\t\\tcmd[2] = 0x1C; // 16K buffers\\n\\t\\t\\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2\\n\\t\\t\\tcmd[2] = ((addr >> 8) & 0x20) | 0x1C; // 8K buffers\\n\\t\\t\\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4\\n\\t\\t\\tcmd[2] = ((addr >> 7) & 0x60) | 0x1C; // 4K buffers\\n\\t\\t\\t#else\\n\\t\\t\\tcmd[2] = ((addr >> 6) & 0xE0) | 0x1C; // 2K buffers\\n\\t\\t\\t#endif\\n\\t\\t}\\n\\t\\tif (len <= 5) {\\n\\t\\t\\tfor (uint8_t i=0; i < len; i++) {\\n\\t\\t\\t\\tcmd[i + 3] = buf[i];\\n\\t\\t\\t}\\n\\t\\t\\tSPI.transfer(cmd, len + 3);\\n\\t\\t} else {\\n\\t\\t\\tSPI.transfer(cmd, 3);\\n#ifdef SPI_HAS_TRANSFER_BUF\\n\\t\\t\\tSPI.transfer(buf, NULL, len);\\n#else\\n\\t\\t\\t// TODO: copy 8 bytes at a time to cmd[] and block transfer\\n\\t\\t\\tfor (uint16_t i=0; i < len; i++) {\\n\\t\\t\\t\\tSPI.transfer(buf[i]);\\n\\t\\t\\t}\\n#endif\\n\\t\\t}\\n\\t\\tresetSS();\\n\\t}\\n\\treturn len;\\n}\\n\\nuint16_t W5100Class::read(uint16_t addr, uint8_t *buf, uint16_t len)\\n{\\n\\tuint8_t cmd[4];\\n\\n\\tif (chip == 51) {\\n\\t\\tfor (uint16_t i=0; i < len; i++) {\\n\\t\\t\\tsetSS();\\n\\t\\t\\t#if 1\\n\\t\\t\\tSPI.transfer(0x0F);\\n\\t\\t\\tSPI.transfer(addr >> 8);\\n\\t\\t\\tSPI.transfer(addr & 0xFF);\\n\\t\\t\\taddr++;\\n\\t\\t\\tbuf[i] = SPI.transfer(0);\\n\\t\\t\\t#else\\n\\t\\t\\tcmd[0] = 0x0F;\\n\\t\\t\\tcmd[1] = addr >> 8;\\n\\t\\t\\tcmd[2] = addr & 0xFF;\\n\\t\\t\\tcmd[3] = 0;\\n\\t\\t\\tSPI.transfer(cmd, 4); // TODO: why doesn't this work?\\n\\t\\t\\tbuf[i] = cmd[3];\\n\\t\\t\\taddr++;\\n\\t\\t\\t#endif\\n\\t\\t\\tresetSS();\\n\\t\\t}\\n\\t} else if (chip == 52) {\\n\\t\\tsetSS();\\n\\t\\tcmd[0] = addr >> 8;\\n\\t\\tcmd[1] = addr & 0xFF;\\n\\t\\tcmd[2] = (len >> 8) & 0x7F;\\n\\t\\tcmd[3] = len & 0xFF;\\n\\t\\tSPI.transfer(cmd, 4);\\n\\t\\tmemset(buf, 0, len);\\n\\t\\tSPI.transfer(buf, len);\\n\\t\\tresetSS();\\n\\t} else { // chip == 55\\n\\t\\tsetSS();\\n\\t\\tif (addr < 0x100) {\\n\\t\\t\\t// common registers 00nn\\n\\t\\t\\tcmd[0] = 0;\\n\\t\\t\\tcmd[1] = addr & 0xFF;\\n\\t\\t\\tcmd[2] = 0x00;\\n\\t\\t} else if (addr < 0x8000) {\\n\\t\\t\\t// socket registers 10nn, 11nn, 12nn, 13nn, etc\\n\\t\\t\\tcmd[0] = 0;\\n\\t\\t\\tcmd[1] = addr & 0xFF;\\n\\t\\t\\tcmd[2] = ((addr >> 3) & 0xE0) | 0x08;\\n\\t\\t} else if (addr < 0xC000) {\\n\\t\\t\\t// transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc\\n\\t\\t\\t// 10## #nnn nnnn nnnn\\n\\t\\t\\tcmd[0] = addr >> 8;\\n\\t\\t\\tcmd[1] = addr & 0xFF;\\n\\t\\t\\t#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1\\n\\t\\t\\tcmd[2] = 0x10; // 16K buffers\\n\\t\\t\\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2\\n\\t\\t\\tcmd[2] = ((addr >> 8) & 0x20) | 0x10; // 8K buffers\\n\\t\\t\\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4\\n\\t\\t\\tcmd[2] = ((addr >> 7) & 0x60) | 0x10; // 4K buffers\\n\\t\\t\\t#else\\n\\t\\t\\tcmd[2] = ((addr >> 6) & 0xE0) | 0x10; // 2K buffers\\n\\t\\t\\t#endif\\n\\t\\t} else {\\n\\t\\t\\t// receive buffers\\n\\t\\t\\tcmd[0] = addr >> 8;\\n\\t\\t\\tcmd[1] = addr & 0xFF;\\n\\t\\t\\t#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1\\n\\t\\t\\tcmd[2] = 0x18; // 16K buffers\\n\\t\\t\\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2\\n\\t\\t\\tcmd[2] = ((addr >> 8) & 0x20) | 0x18; // 8K buffers\\n\\t\\t\\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4\\n\\t\\t\\tcmd[2] = ((addr >> 7) & 0x60) | 0x18; // 4K buffers\\n\\t\\t\\t#else\\n\\t\\t\\tcmd[2] = ((addr >> 6) & 0xE0) | 0x18; // 2K buffers\\n\\t\\t\\t#endif\\n\\t\\t}\\n\\t\\tSPI.transfer(cmd, 3);\\n\\t\\tmemset(buf, 0, len);\\n\\t\\tSPI.transfer(buf, len);\\n\\t\\tresetSS();\\n\\t}\\n\\treturn len;\\n}\\n\\nvoid W5100Class::execCmdSn(SOCKET s, SockCMD _cmd)\\n{\\n\\t// Send command to socket\\n\\twriteSnCR(s, _cmd);\\n\\t// Wait for command to complete\\n\\twhile (readSnCR(s)) ;\\n}\\n\" }", "{ filename: \"src/w5100.h\", code: \"/*\\n * Copyright 2018 Paul Stoffregen\\n * Copyright (c) 2010 by Cristian Maglie \\n *\\n * This file is free software; you can redistribute it and/or modify\\n * it under the terms of either the GNU General Public License version 2\\n * or the GNU Lesser General Public License version 2.1, both as\\n * published by the Free Software Foundation.\\n */\\n\\n// w5100.h contains private W5x00 hardware \\\"driver\\\" level definitions\\n// which are not meant to be exposed to other libraries or Arduino users\\n\\n#ifndef\\tW5100_H_INCLUDED\\n#define\\tW5100_H_INCLUDED\\n\\n#include \\n#include \\n\\n// Safe for all chips\\n#define SPI_ETHERNET_SETTINGS SPISettings(14000000, MSBFIRST, SPI_MODE0)\\n\\n// Safe for W5200 and W5500, but too fast for W5100\\n// Uncomment this if you know you'll never need W5100 support.\\n// Higher SPI clock only results in faster transfer to hosts on a LAN\\n// or with very low packet latency. With ordinary internet latency,\\n// the TCP window size & packet loss determine your overall speed.\\n//#define SPI_ETHERNET_SETTINGS SPISettings(30000000, MSBFIRST, SPI_MODE0)\\n\\n\\n// Require Ethernet.h, because we need MAX_SOCK_NUM\\n#ifndef ethernet_h_\\n#error \\\"Ethernet.h must be included before w5100.h\\\"\\n#endif\\n\\n\\n// Arduino 101's SPI can not run faster than 8 MHz.\\n#if defined(ARDUINO_ARCH_ARC32)\\n#undef SPI_ETHERNET_SETTINGS\\n#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE0)\\n#endif\\n\\n// Arduino Zero can't use W5100-based shields faster than 8 MHz\\n// https://github.com/arduino-libraries/Ethernet/issues/37#issuecomment-408036848\\n// W5500 does seem to work at 12 MHz. Delete this if only using W5500\\n#if defined(__SAMD21G18A__)\\n#undef SPI_ETHERNET_SETTINGS\\n#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE0)\\n#endif\\n\\n\\ntypedef uint8_t SOCKET;\\n\\nclass SnMR {\\npublic:\\n static const uint8_t CLOSE = 0x00;\\n static const uint8_t TCP = 0x21;\\n static const uint8_t UDP = 0x02;\\n static const uint8_t IPRAW = 0x03;\\n static const uint8_t MACRAW = 0x04;\\n static const uint8_t PPPOE = 0x05;\\n static const uint8_t ND = 0x20;\\n static const uint8_t MULTI = 0x80;\\n};\\n\\nenum SockCMD {\\n Sock_OPEN = 0x01,\\n Sock_LISTEN = 0x02,\\n Sock_CONNECT = 0x04,\\n Sock_DISCON = 0x08,\\n Sock_CLOSE = 0x10,\\n Sock_SEND = 0x20,\\n Sock_SEND_MAC = 0x21,\\n Sock_SEND_KEEP = 0x22,\\n Sock_RECV = 0x40\\n};\\n\\nclass SnIR {\\npublic:\\n static const uint8_t SEND_OK = 0x10;\\n static const uint8_t TIMEOUT = 0x08;\\n static const uint8_t RECV = 0x04;\\n static const uint8_t DISCON = 0x02;\\n static const uint8_t CON = 0x01;\\n};\\n\\nclass SnSR {\\npublic:\\n static const uint8_t CLOSED = 0x00;\\n static const uint8_t INIT = 0x13;\\n static const uint8_t LISTEN = 0x14;\\n static const uint8_t SYNSENT = 0x15;\\n static const uint8_t SYNRECV = 0x16;\\n static const uint8_t ESTABLISHED = 0x17;\\n static const uint8_t FIN_WAIT = 0x18;\\n static const uint8_t CLOSING = 0x1A;\\n static const uint8_t TIME_WAIT = 0x1B;\\n static const uint8_t CLOSE_WAIT = 0x1C;\\n static const uint8_t LAST_ACK = 0x1D;\\n static const uint8_t UDP = 0x22;\\n static const uint8_t IPRAW = 0x32;\\n static const uint8_t MACRAW = 0x42;\\n static const uint8_t PPPOE = 0x5F;\\n};\\n\\nclass IPPROTO {\\npublic:\\n static const uint8_t IP = 0;\\n static const uint8_t ICMP = 1;\\n static const uint8_t IGMP = 2;\\n static const uint8_t GGP = 3;\\n static const uint8_t TCP = 6;\\n static const uint8_t PUP = 12;\\n static const uint8_t UDP = 17;\\n static const uint8_t IDP = 22;\\n static const uint8_t ND = 77;\\n static const uint8_t RAW = 255;\\n};\\n\\nenum W5100Linkstatus {\\n UNKNOWN,\\n LINK_ON,\\n LINK_OFF\\n};\\n\\nclass W5100Class {\\n\\npublic:\\n static uint8_t init(void);\\n\\n inline void setGatewayIp(const uint8_t * addr) { writeGAR(addr); }\\n inline void getGatewayIp(uint8_t * addr) { readGAR(addr); }\\n\\n inline void setSubnetMask(const uint8_t * addr) { writeSUBR(addr); }\\n inline void getSubnetMask(uint8_t * addr) { readSUBR(addr); }\\n\\n inline void setMACAddress(const uint8_t * addr) { writeSHAR(addr); }\\n inline void getMACAddress(uint8_t * addr) { readSHAR(addr); }\\n\\n inline void setIPAddress(const uint8_t * addr) { writeSIPR(addr); }\\n inline void getIPAddress(uint8_t * addr) { readSIPR(addr); }\\n\\n inline void setRetransmissionTime(uint16_t timeout) { writeRTR(timeout); }\\n inline void setRetransmissionCount(uint8_t retry) { writeRCR(retry); }\\n\\n static void execCmdSn(SOCKET s, SockCMD _cmd);\\n\\n\\n // W5100 Registers\\n // ---------------\\n//private:\\npublic:\\n static uint16_t write(uint16_t addr, const uint8_t *buf, uint16_t len);\\n static uint8_t write(uint16_t addr, uint8_t data) {\\n return write(addr, &data, 1);\\n }\\n static uint16_t read(uint16_t addr, uint8_t *buf, uint16_t len);\\n static uint8_t read(uint16_t addr) {\\n uint8_t data;\\n read(addr, &data, 1);\\n return data;\\n }\\n\\n#define __GP_REGISTER8(name, address) \\\\\\n static inline void write##name(uint8_t _data) { \\\\\\n write(address, _data); \\\\\\n } \\\\\\n static inline uint8_t read##name() { \\\\\\n return read(address); \\\\\\n }\\n#define __GP_REGISTER16(name, address) \\\\\\n static void write##name(uint16_t _data) { \\\\\\n uint8_t buf[2]; \\\\\\n buf[0] = _data >> 8; \\\\\\n buf[1] = _data & 0xFF; \\\\\\n write(address, buf, 2); \\\\\\n } \\\\\\n static uint16_t read##name() { \\\\\\n uint8_t buf[2]; \\\\\\n read(address, buf, 2); \\\\\\n return (buf[0] << 8) | buf[1]; \\\\\\n }\\n#define __GP_REGISTER_N(name, address, size) \\\\\\n static uint16_t write##name(const uint8_t *_buff) { \\\\\\n return write(address, _buff, size); \\\\\\n } \\\\\\n static uint16_t read##name(uint8_t *_buff) { \\\\\\n return read(address, _buff, size); \\\\\\n }\\n static W5100Linkstatus getLinkStatus();\\n\\npublic:\\n __GP_REGISTER8 (MR, 0x0000); // Mode\\n __GP_REGISTER_N(GAR, 0x0001, 4); // Gateway IP address\\n __GP_REGISTER_N(SUBR, 0x0005, 4); // Subnet mask address\\n __GP_REGISTER_N(SHAR, 0x0009, 6); // Source MAC address\\n __GP_REGISTER_N(SIPR, 0x000F, 4); // Source IP address\\n __GP_REGISTER8 (IR, 0x0015); // Interrupt\\n __GP_REGISTER8 (IMR, 0x0016); // Interrupt Mask\\n __GP_REGISTER16(RTR, 0x0017); // Timeout address\\n __GP_REGISTER8 (RCR, 0x0019); // Retry count\\n __GP_REGISTER8 (RMSR, 0x001A); // Receive memory size (W5100 only)\\n __GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size (W5100 only)\\n __GP_REGISTER8 (PATR, 0x001C); // Authentication type address in PPPoE mode\\n __GP_REGISTER8 (PTIMER, 0x0028); // PPP LCP Request Timer\\n __GP_REGISTER8 (PMAGIC, 0x0029); // PPP LCP Magic Number\\n __GP_REGISTER_N(UIPR, 0x002A, 4); // Unreachable IP address in UDP mode (W5100 only)\\n __GP_REGISTER16(UPORT, 0x002E); // Unreachable Port address in UDP mode (W5100 only)\\n __GP_REGISTER8 (VERSIONR_W5200,0x001F); // Chip Version Register (W5200 only)\\n __GP_REGISTER8 (VERSIONR_W5500,0x0039); // Chip Version Register (W5500 only)\\n __GP_REGISTER8 (PSTATUS_W5200, 0x0035); // PHY Status\\n __GP_REGISTER8 (PHYCFGR_W5500, 0x002E); // PHY Configuration register, default: 10111xxx\\n\\n\\n#undef __GP_REGISTER8\\n#undef __GP_REGISTER16\\n#undef __GP_REGISTER_N\\n\\n // W5100 Socket registers\\n // ----------------------\\nprivate:\\n static uint16_t CH_BASE(void) {\\n //if (chip == 55) return 0x1000;\\n //if (chip == 52) return 0x4000;\\n //return 0x0400;\\n return CH_BASE_MSB << 8;\\n }\\n static uint8_t CH_BASE_MSB; // 1 redundant byte, saves ~80 bytes code on AVR\\n static const uint16_t CH_SIZE = 0x0100;\\n\\n static inline uint8_t readSn(SOCKET s, uint16_t addr) {\\n return read(CH_BASE() + s * CH_SIZE + addr);\\n }\\n static inline uint8_t writeSn(SOCKET s, uint16_t addr, uint8_t data) {\\n return write(CH_BASE() + s * CH_SIZE + addr, data);\\n }\\n static inline uint16_t readSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len) {\\n return read(CH_BASE() + s * CH_SIZE + addr, buf, len);\\n }\\n static inline uint16_t writeSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len) {\\n return write(CH_BASE() + s * CH_SIZE + addr, buf, len);\\n }\\n\\n#define __SOCKET_REGISTER8(name, address) \\\\\\n static inline void write##name(SOCKET _s, uint8_t _data) { \\\\\\n writeSn(_s, address, _data); \\\\\\n } \\\\\\n static inline uint8_t read##name(SOCKET _s) { \\\\\\n return readSn(_s, address); \\\\\\n }\\n#define __SOCKET_REGISTER16(name, address) \\\\\\n static void write##name(SOCKET _s, uint16_t _data) { \\\\\\n uint8_t buf[2]; \\\\\\n buf[0] = _data >> 8; \\\\\\n buf[1] = _data & 0xFF; \\\\\\n writeSn(_s, address, buf, 2); \\\\\\n } \\\\\\n static uint16_t read##name(SOCKET _s) { \\\\\\n uint8_t buf[2]; \\\\\\n readSn(_s, address, buf, 2); \\\\\\n return (buf[0] << 8) | buf[1]; \\\\\\n }\\n#define __SOCKET_REGISTER_N(name, address, size) \\\\\\n static uint16_t write##name(SOCKET _s, uint8_t *_buff) { \\\\\\n return writeSn(_s, address, _buff, size); \\\\\\n } \\\\\\n static uint16_t read##name(SOCKET _s, uint8_t *_buff) { \\\\\\n return readSn(_s, address, _buff, size); \\\\\\n }\\n\\npublic:\\n __SOCKET_REGISTER8(SnMR, 0x0000) // Mode\\n __SOCKET_REGISTER8(SnCR, 0x0001) // Command\\n __SOCKET_REGISTER8(SnIR, 0x0002) // Interrupt\\n __SOCKET_REGISTER8(SnSR, 0x0003) // Status\\n __SOCKET_REGISTER16(SnPORT, 0x0004) // Source Port\\n __SOCKET_REGISTER_N(SnDHAR, 0x0006, 6) // Destination Hardw Addr\\n __SOCKET_REGISTER_N(SnDIPR, 0x000C, 4) // Destination IP Addr\\n __SOCKET_REGISTER16(SnDPORT, 0x0010) // Destination Port\\n __SOCKET_REGISTER16(SnMSSR, 0x0012) // Max Segment Size\\n __SOCKET_REGISTER8(SnPROTO, 0x0014) // Protocol in IP RAW Mode\\n __SOCKET_REGISTER8(SnTOS, 0x0015) // IP TOS\\n __SOCKET_REGISTER8(SnTTL, 0x0016) // IP TTL\\n __SOCKET_REGISTER8(SnRX_SIZE, 0x001E) // RX Memory Size (W5200 only)\\n __SOCKET_REGISTER8(SnTX_SIZE, 0x001F) // RX Memory Size (W5200 only)\\n __SOCKET_REGISTER16(SnTX_FSR, 0x0020) // TX Free Size\\n __SOCKET_REGISTER16(SnTX_RD, 0x0022) // TX Read Pointer\\n __SOCKET_REGISTER16(SnTX_WR, 0x0024) // TX Write Pointer\\n __SOCKET_REGISTER16(SnRX_RSR, 0x0026) // RX Free Size\\n __SOCKET_REGISTER16(SnRX_RD, 0x0028) // RX Read Pointer\\n __SOCKET_REGISTER16(SnRX_WR, 0x002A) // RX Write Pointer (supported?)\\n\\n#undef __SOCKET_REGISTER8\\n#undef __SOCKET_REGISTER16\\n#undef __SOCKET_REGISTER_N\\n\\n\\nprivate:\\n static uint8_t chip;\\n static uint8_t ss_pin;\\n static uint8_t softReset(void);\\n static uint8_t isW5100(void);\\n static uint8_t isW5200(void);\\n static uint8_t isW5500(void);\\n\\npublic:\\n static uint8_t getChip(void) { return chip; }\\n#ifdef ETHERNET_LARGE_BUFFERS\\n static uint16_t SSIZE;\\n static uint16_t SMASK;\\n#else\\n static const uint16_t SSIZE = 2048;\\n static const uint16_t SMASK = 0x07FF;\\n#endif\\n static uint16_t SBASE(uint8_t socknum) {\\n if (chip == 51) {\\n return socknum * SSIZE + 0x4000;\\n } else {\\n return socknum * SSIZE + 0x8000;\\n }\\n }\\n static uint16_t RBASE(uint8_t socknum) {\\n if (chip == 51) {\\n return socknum * SSIZE + 0x6000;\\n } else {\\n return socknum * SSIZE + 0xC000;\\n }\\n }\\n\\n static bool hasOffsetAddressMapping(void) {\\n if (chip == 55) return true;\\n return false;\\n }\\n static void setSS(uint8_t pin) { ss_pin = pin; }\\n\\nprivate:\\n#if defined(__AVR__)\\n\\tstatic volatile uint8_t *ss_pin_reg;\\n\\tstatic uint8_t ss_pin_mask;\\n\\tinline static void initSS() {\\n\\t\\tss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin));\\n\\t\\tss_pin_mask = digitalPinToBitMask(ss_pin);\\n\\t\\tpinMode(ss_pin, OUTPUT);\\n\\t}\\n\\tinline static void setSS() {\\n\\t\\t*(ss_pin_reg) &= ~ss_pin_mask;\\n\\t}\\n\\tinline static void resetSS() {\\n\\t\\t*(ss_pin_reg) |= ss_pin_mask;\\n\\t}\\n#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)\\n\\tstatic volatile uint8_t *ss_pin_reg;\\n\\tinline static void initSS() {\\n\\t\\tss_pin_reg = portOutputRegister(ss_pin);\\n\\t\\tpinMode(ss_pin, OUTPUT);\\n\\t}\\n\\tinline static void setSS() {\\n\\t\\t*(ss_pin_reg+256) = 1;\\n\\t}\\n\\tinline static void resetSS() {\\n\\t\\t*(ss_pin_reg+128) = 1;\\n\\t}\\n#elif defined(__MKL26Z64__)\\n\\tstatic volatile uint8_t *ss_pin_reg;\\n\\tstatic uint8_t ss_pin_mask;\\n\\tinline static void initSS() {\\n\\t\\tss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin));\\n\\t\\tss_pin_mask = digitalPinToBitMask(ss_pin);\\n\\t\\tpinMode(ss_pin, OUTPUT);\\n\\t}\\n\\tinline static void setSS() {\\n\\t\\t*(ss_pin_reg+8) = ss_pin_mask;\\n\\t}\\n\\tinline static void resetSS() {\\n\\t\\t*(ss_pin_reg+4) = ss_pin_mask;\\n\\t}\\n#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)\\n\\tstatic volatile uint32_t *ss_pin_reg;\\n\\tstatic uint32_t ss_pin_mask;\\n\\tinline static void initSS() {\\n\\t\\tss_pin_reg = &(digitalPinToPort(ss_pin)->PIO_PER);\\n\\t\\tss_pin_mask = digitalPinToBitMask(ss_pin);\\n\\t\\tpinMode(ss_pin, OUTPUT);\\n\\t}\\n\\tinline static void setSS() {\\n\\t\\t*(ss_pin_reg+13) = ss_pin_mask;\\n\\t}\\n\\tinline static void resetSS() {\\n\\t\\t*(ss_pin_reg+12) = ss_pin_mask;\\n\\t}\\n#elif defined(__PIC32MX__)\\n\\tstatic volatile uint32_t *ss_pin_reg;\\n\\tstatic uint32_t ss_pin_mask;\\n\\tinline static void initSS() {\\n\\t\\tss_pin_reg = portModeRegister(digitalPinToPort(ss_pin));\\n\\t\\tss_pin_mask = digitalPinToBitMask(ss_pin);\\n\\t\\tpinMode(ss_pin, OUTPUT);\\n\\t}\\n\\tinline static void setSS() {\\n\\t\\t*(ss_pin_reg+8+1) = ss_pin_mask;\\n\\t}\\n\\tinline static void resetSS() {\\n\\t\\t*(ss_pin_reg+8+2) = ss_pin_mask;\\n\\t}\\n\\n#elif defined(ARDUINO_ARCH_ESP8266)\\n\\tstatic volatile uint32_t *ss_pin_reg;\\n\\tstatic uint32_t ss_pin_mask;\\n\\tinline static void initSS() {\\n\\t\\tss_pin_reg = (volatile uint32_t*)GPO;\\n\\t\\tss_pin_mask = 1 << ss_pin;\\n\\t\\tpinMode(ss_pin, OUTPUT);\\n\\t}\\n\\tinline static void setSS() {\\n\\t\\tGPOC = ss_pin_mask;\\n\\t}\\n\\tinline static void resetSS() {\\n\\t\\tGPOS = ss_pin_mask;\\n\\t}\\n\\n#elif defined(__SAMD21G18A__)\\n\\tstatic volatile uint32_t *ss_pin_reg;\\n\\tstatic uint32_t ss_pin_mask;\\n\\tinline static void initSS() {\\n\\t\\tss_pin_reg = portModeRegister(digitalPinToPort(ss_pin));\\n\\t\\tss_pin_mask = digitalPinToBitMask(ss_pin);\\n\\t\\tpinMode(ss_pin, OUTPUT);\\n\\t}\\n\\tinline static void setSS() {\\n\\t\\t*(ss_pin_reg+5) = ss_pin_mask;\\n\\t}\\n\\tinline static void resetSS() {\\n\\t\\t*(ss_pin_reg+6) = ss_pin_mask;\\n\\t}\\n#else\\n\\tinline static void initSS() {\\n\\t\\tpinMode(ss_pin, OUTPUT);\\n\\t}\\n\\tinline static void setSS() {\\n\\t\\tdigitalWrite(ss_pin, LOW);\\n\\t}\\n\\tinline static void resetSS() {\\n\\t\\tdigitalWrite(ss_pin, HIGH);\\n\\t}\\n#endif\\n};\\n\\nextern W5100Class W5100;\\n\\n\\n\\n#endif\\n\\n#ifndef UTIL_H\\n#define UTIL_H\\n\\n#define htons(x) ( (((x)<<8)&0xFF00) | (((x)>>8)&0xFF) )\\n#define ntohs(x) htons(x)\\n\\n#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \\\\\\n ((x)<< 8 & 0x00FF0000UL) | \\\\\\n ((x)>> 8 & 0x0000FF00UL) | \\\\\\n ((x)>>24 & 0x000000FFUL) )\\n#define ntohl(x) htonl(x)\\n\\n#endif\\n\" }" ];PK BVEsrc/facepanels.jsexport default {};PK BV_[[src/exthandler.jsconst ExtHandler = { // when extension is loaded onLoad(app, target) {}, // when extension is unloaded onUnload(app) { // TODO }, // when device is connected onConnect(app, device) { // TODO }, // when device is disconnected onDisconnect(app, device) { // TODO }, // when stop button is clicked onStopAll(app, device) { // TODO }, // before switch to upload mode beforeChangeUploadMode(app, device) { // TODO return true; }, // before switch to debug mode beforeChangeDebugMode(app, device) { // TODO return true; }, // after switched to upload mode afterChangeUploadMode(app, device) { // TODO return true; }, // after switched to debug mode afterChangeDebugMode(app, device) { // TODO return true; }, // when device is selected onSelect(app, device) { // TODO }, // when device is unselected onUnselect(app, device) { // TODO }, // before upload code beforeCodeUpload(app, device) { // TODO }, // after code uploaded afterCodeUpload(app, device) { // TODO }, // when receiving and reading byte onRead(app, device) { // TODO } } export default ExtHandler;PK BV0G0Gsrc/handlerProxy.jsself.rpc.CONFIG.TIMEOUT = 42000; self.rpc.CONFIG.HEARTBEAT = 4200; const __context = { app: self.rpc.remote.app, getDevice: function getDevice(deviceId) { return new Proxy({}, { get(target, name) { if (name == "id") { return deviceId; } return function (...args) { let runDevice = __context.app.runDevice; return runDevice(deviceId, name, ...args); }; } }); } }; !function (global) { "use strict"; var Op = Object.prototype; var hasOwn = Op.hasOwnProperty; var undefined; var $Symbol = typeof Symbol === "function" ? Symbol : {}; var iteratorSymbol = $Symbol.iterator || "@@iterator"; var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; var inModule = typeof module === "object"; var runtime = global.regeneratorRuntime; if (runtime) { if (inModule) { module.exports = runtime; } return; } runtime = global.regeneratorRuntime = inModule ? module.exports || {} : {}; function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; var generator = Object.create(protoGenerator.prototype); var context = new Context(tryLocsList || []); generator._invoke = makeInvokeMethod(innerFn, self, context); return generator; } runtime.wrap = wrap; function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } var GenStateSuspendedStart = "suspendedStart"; var GenStateSuspendedYield = "suspendedYield"; var GenStateExecuting = "executing"; var GenStateCompleted = "completed"; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; IteratorPrototype[iteratorSymbol] = function () { return this; }; var getProto = Object.getPrototypeOf; var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { IteratorPrototype = NativeIteratorPrototype; } var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; GeneratorFunctionPrototype.constructor = GeneratorFunction; GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction"; function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { prototype[method] = function (arg) { return this._invoke(method, arg); }; }); } runtime.isGeneratorFunction = function (genFun) { var ctor = typeof genFun === "function" && genFun.constructor; return ctor ? ctor === GeneratorFunction || (ctor.displayName || ctor.name) === "GeneratorFunction" : false; }; runtime.mark = function (genFun) { if (Object.setPrototypeOf) { Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); } else { genFun.__proto__ = GeneratorFunctionPrototype; if (!(toStringTagSymbol in genFun)) { genFun[toStringTagSymbol] = "GeneratorFunction"; } } genFun.prototype = Object.create(Gp); return genFun; }; runtime.awrap = function (arg) { return { __await: arg }; }; function AsyncIterator(generator) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if (record.type === "throw") { reject(record.arg); } else { var result = record.arg; var value = result.value; if (value && typeof value === "object" && hasOwn.call(value, "__await")) { return Promise.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }); } return Promise.resolve(value).then(function (unwrapped) { result.value = unwrapped; resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } } var previousPromise; function enqueue(method, arg) { function callInvokeWithMethodAndArg() { return new Promise(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } this._invoke = enqueue; } defineIteratorMethods(AsyncIterator.prototype); AsyncIterator.prototype[asyncIteratorSymbol] = function () { return this; }; runtime.AsyncIterator = AsyncIterator; runtime.async = function (innerFn, outerFn, self, tryLocsList) { var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList)); return runtime.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }; function makeInvokeMethod(innerFn, self, context) { var state = GenStateSuspendedStart; return function invoke(method, arg) { if (state === GenStateExecuting) { throw new Error("Generator is already running"); } if (state === GenStateCompleted) { if (method === "throw") { throw arg; } return doneResult(); } context.method = method; context.arg = arg; while (true) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if (context.method === "next") { context.sent = context._sent = context.arg; } else if (context.method === "throw") { if (state === GenStateSuspendedStart) { state = GenStateCompleted; throw context.arg; } context.dispatchException(context.arg); } else if (context.method === "return") { context.abrupt("return", context.arg); } state = GenStateExecuting; var record = tryCatch(innerFn, self, context); if (record.type === "normal") { state = context.done ? GenStateCompleted : GenStateSuspendedYield; if (record.arg === ContinueSentinel) { continue; } return { value: record.arg, done: context.done }; } else if (record.type === "throw") { state = GenStateCompleted; context.method = "throw"; context.arg = record.arg; } } }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (method === undefined) { context.delegate = null; if (context.method === "throw") { if (delegate.iterator.return) { context.method = "return"; context.arg = undefined; maybeInvokeDelegate(delegate, context); if (context.method === "throw") { return ContinueSentinel; } } context.method = "throw"; context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if (record.type === "throw") { context.method = "throw"; context.arg = record.arg; context.delegate = null; return ContinueSentinel; } var info = record.arg; if (!info) { context.method = "throw"; context.arg = new TypeError("iterator result is not an object"); context.delegate = null; return ContinueSentinel; } if (info.done) { context[delegate.resultName] = info.value; context.next = delegate.nextLoc; if (context.method !== "return") { context.method = "next"; context.arg = undefined; } } else { return info; } context.delegate = null; return ContinueSentinel; } defineIteratorMethods(Gp); Gp[toStringTagSymbol] = "Generator"; Gp[iteratorSymbol] = function () { return this; }; Gp.toString = function () { return "[object Generator]"; }; function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; if (1 in locs) { entry.catchLoc = locs[1]; } if (2 in locs) { entry.finallyLoc = locs[2]; entry.afterLoc = locs[3]; } this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal"; delete record.arg; entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }]; tryLocsList.forEach(pushTryEntry, this); this.reset(true); } runtime.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } keys.reverse(); return function next() { while (keys.length) { var key = keys.pop(); if (key in object) { next.value = key; next.done = false; return next; } } next.done = true; return next; }; }; function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) { return iteratorMethod.call(iterable); } if (typeof iterable.next === "function") { return iterable; } if (!isNaN(iterable.length)) { var i = -1, next = function next() { while (++i < iterable.length) { if (hasOwn.call(iterable, i)) { next.value = iterable[i]; next.done = false; return next; } } next.value = undefined; next.done = true; return next; }; return next.next = next; } } return { next: doneResult }; } runtime.values = values; function doneResult() { return { value: undefined, done: true }; } Context.prototype = { constructor: Context, reset: function (skipTempReset) { this.prev = 0; this.next = 0; this.sent = this._sent = undefined; this.done = false; this.delegate = null; this.method = "next"; this.arg = undefined; this.tryEntries.forEach(resetTryEntry); if (!skipTempReset) { for (var name in this) { if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) { this[name] = undefined; } } } }, stop: function () { this.done = true; var rootEntry = this.tryEntries[0]; var rootRecord = rootEntry.completion; if (rootRecord.type === "throw") { throw rootRecord.arg; } return this.rval; }, dispatchException: function (exception) { if (this.done) { throw exception; } var context = this; function handle(loc, caught) { record.type = "throw"; record.arg = exception; context.next = loc; if (caught) { context.method = "next"; context.arg = undefined; } return !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; var record = entry.completion; if (entry.tryLoc === "root") { return handle("end"); } if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"); var hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } else if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else if (hasCatch) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } } else if (hasFinally) { if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else { throw new Error("try statement without catch or finally"); } } } }, abrupt: function (type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { finallyEntry = null; } var record = finallyEntry ? finallyEntry.completion : {}; record.type = type; record.arg = arg; if (finallyEntry) { this.method = "next"; this.next = finallyEntry.finallyLoc; return ContinueSentinel; } return this.complete(record); }, complete: function (record, afterLoc) { if (record.type === "throw") { throw record.arg; } if (record.type === "break" || record.type === "continue") { this.next = record.arg; } else if (record.type === "return") { this.rval = this.arg = record.arg; this.method = "return"; this.next = "end"; } else if (record.type === "normal" && afterLoc) { this.next = afterLoc; } return ContinueSentinel; }, finish: function (finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) { this.complete(entry.completion, entry.afterLoc); resetTryEntry(entry); return ContinueSentinel; } } }, "catch": function (tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if (record.type === "throw") { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function (iterable, resultName, nextLoc) { this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }; if (this.method === "next") { this.arg = undefined; } return ContinueSentinel; } }; }(function () { return this || typeof self === "object" && self; }() || Function("return this")()); const disableBlocks = { debug: [], upload: [] }; const mustLoginBlocks = []; const triggerBlocksStatus = async (mode, app) => {}; const blockHandlers = { 'BLOCK_1653780308718': { onRun: (args, app, device, block) => {} }, 'BLOCK_1675367642335': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653780309012': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653780309457': { onRun: (args, app, device, block) => {} }, 'BLOCK_1654274936853': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653780309804': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653780310011': { onRun: (args, app, device, block) => {} }, 'BLOCK_1654273986221': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653855510926': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653780310978': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653780311427': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653780311846': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653780311631': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653780312072': { onRun: (args, app, device, block) => {} }, 'BLOCK_1653780312304': { onRun: (args, app, device, block) => {} } }; const ExtHandler = { onLoad(app, target) {}, onUnload(app) {}, onConnect(app, device) {}, onDisconnect(app, device) {}, onStopAll(app, device) {}, beforeChangeUploadMode(app, device) { return true; }, beforeChangeDebugMode(app, device) { return true; }, afterChangeUploadMode(app, device) { return true; }, afterChangeDebugMode(app, device) { return true; }, onSelect(app, device) {}, onUnselect(app, device) {}, beforeCodeUpload(app, device) {}, afterCodeUpload(app, device) {}, onRead(app, device) {} }; self.rpc.exports = { runBlock: function runBlock(opcode, method, deviceId, block, args) { var blockHandler = blockHandlers[opcode]; if (!blockHandler) { console.error('cannot find opcode of ' + opcode); return null; } var handle = blockHandler[method]; let app = __context.app; let device = __context.getDevice(deviceId); if (method === 'onRun') { return handle(args, app, device, block); } else { return handle(app, device, block); } }, runExtension: function runExtension(srcMethod, deviceId) { var method = ExtHandler[srcMethod]; if (!method) { console.error('method of ' + srcMethod + ' is no valid'); return null; } let app = __context.app; if (deviceId) { let device = __context.getDevice(deviceId); return method(app, device); } else { return method(app); } } };PK BV src/cates/PK BVsrc/cates/cate_a6db9026/PK BVMM src/cates/cate_a6db9026/index.jsimport blocks from './blocks.js'; const cate_a6db9026 = (facepanels) => ({ "name": "cate_a6db9026", "colors": [ "#05A6FF", "#0097EA", "#0086D0" ], "menuIconURI": "", "blockIcon": { "type": "image", "width": 28, "height": 26, "src": window.MbApi.getExtResPath('vdr_ethernet_shield/imgs/c6ed8de0c5964a5fa3964e968e7a6466.png', 'vdr_ethernet_shield') }, "blocks": blocks(facepanels), "menus": { "BLOCK_1653780309457_IP": [{ "text": "BLOCK_1653780309457_IP_0", "value": "0" }, { "text": "BLOCK_1653780309457_IP_1", "value": "1" }, { "text": "BLOCK_1653780309457_IP_2", "value": "2" }, { "text": "BLOCK_1653780309457_IP_3", "value": "3" } ], "BLOCK_1653780310978_REFRESH": [{ "text": "BLOCK_1653780310978_REFRESH_0", "value": "0" }, { "text": "BLOCK_1653780310978_REFRESH_1", "value": "5" }, { "text": "BLOCK_1653780310978_REFRESH_2", "value": "10" }, { "text": "BLOCK_1653780310978_REFRESH_3", "value": "30" } ], "BLOCK_1653780311427_STYLE": [{ "text": "BLOCK_1653780311427_STYLE_0", "value": "p" }, { "text": "BLOCK_1653780311427_STYLE_1", "value": "H1" }, { "text": "BLOCK_1653780311427_STYLE_2", "value": "H2" } ] } }); export default cate_a6db9026;PK BVT5src/cates/index.jsimport cate_a6db9026 from './cate_a6db9026/index.js'; const cates = (facepanels) => ([ cate_a6db9026(facepanels) ]); export default cates;PK BV|99!src/cates/cate_a6db9026/blocks.jsconst blocks = (extFacePanels) => ([{ "opcode": "BLOCK_1653780308718", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "arguments": {}, "branchCount": 1, "codes": { "arduinoc": { "sections": { "include": [ "\"src/SPI.h\"", "\"src/Ethernet.h\"" ], "declare": `#define DEBUG true\r\nEthernetClient client;\r\nbool firstParam=true;;\r\nbool ethSucceed=false;\r\n\r\nvoid receiveData(){\r\n String reponse=\"\";\r\n while (client.connected()){\r\n while (client.available()){\r\n char c = client.read();\r\n reponse += c;\r\n }\r\n }\r\n if (!client.connected()) client.stop();\r\n if(DEBUG) Serial.println(reponse);\r\n}\r\n\r\nvoid ethGetData(){\r\n String reponse=\"\";\r\n ethSucceed = false ;\r\n if (client.find(\"200 OK\")){\r\n ethSucceed = true;\r\n }\r\n client.find(\"\\r\\n\\r\\n\");\r\n while (client.available()){\r\n char c = client.read();\r\n reponse += c;\r\n }\r\n if (!client.connected()) client.stop();\r\n}\r\n\r\nvoid ethernetInitialise(){\r\n byte ethMac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };\r\n\r\n ethSucceed = false ;\r\n if (DEBUG){\r\n Serial.println();\r\n Serial.print(F(\"Set IP...\"));\r\n }\r\n\r\n /*{$BRANCH1}*/ \r\n\r\n \r\n if (DEBUG){\r\n if(ethSucceed) Serial.println(F(\"OK\")); else Serial.println(F(\"Failed\"));\r\n Serial.println(Ethernet.localIP());\r\n }\r\n}` } } }, "handler": this.funcs.BLOCK_1653780308718 }, { "opcode": "BLOCK_1675367642335", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": {}, "branchCount": 0, "codes": { "arduinoc": { "code": `ethSucceed = Ethernet.begin(ethMac);` } }, "handler": this.funcs.BLOCK_1675367642335 }, { "opcode": "BLOCK_1653780309012", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "IP": { "type": "string", "defaultValue": "172.16.112.50" }, "Mask": { "type": "string", "defaultValue": "255.255.240.0" }, "Gateway": { "type": "string", "defaultValue": "172.16.112.254" }, "DNS": { "type": "string", "defaultValue": "172.16.128.1" } }, "branchCount": 0, "codes": { "arduinoc": { "code": `IPAddress ethIP;\r\nIPAddress ethDNS;\r\nIPAddress ethGateway;\r\nIPAddress ethMask;\r\n\r\nethIP.fromString(/*{IP}*/);\r\nethMask.fromString(/*{Mask}*/);\r\nethGateway.fromString(/*{Gateway}*/);\r\nethDNS.fromString(/*{DNS}*/);\r\n\r\nEthernet.begin(ethMac, ethIP, ethDNS, ethGateway, ethMask);\r\nethSucceed = (Ethernet.localIP() == ethIP);\r\n\r` } }, "handler": this.funcs.BLOCK_1653780309012 }, { "opcode": "BLOCK_1653780309457", "blockType": "string", "checkboxInFlyout": false, "gap": 12, "arguments": { "IP": { "type": "fieldMenu", "defaultValue": "0", "menu": "BLOCK_1653780309457_IP" } }, "branchCount": 0, "codes": { "arduinoc": { "code": `ethGetIP(/*{IP}*/)`, "sections": { "declare": `String ethGetIP(int type){\r\n IPAddress ethIP;\r\n switch (type) {\r\n case 0:\r\n ethIP=Ethernet.localIP();\r\n break;\r\n case 1:\r\n ethIP=Ethernet.dnsServerIP();\r\n break;\r\n case 2:\r\n ethIP=Ethernet.gatewayIP();\r\n break;\r\n case 3:\r\n ethIP=Ethernet.subnetMask();\r\n break;\r\n }\r\n String ip;\r\n ip = ethIP[0];\r\n ip +=\".\";\r\n ip += ethIP[1];\r\n ip +=\".\";\r\n ip += ethIP[2];\r\n ip +=\".\";\r\n ip += ethIP[3];\r\n return ip;\r\n}` } } }, "handler": this.funcs.BLOCK_1653780309457 }, { "opcode": "BLOCK_1654274936853", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": {}, "branchCount": 0, "codes": { "arduinoc": { "code": `ethernetInitialise();` } }, "handler": this.funcs.BLOCK_1654274936853 }, { "opcode": "BLOCK_1653780309804", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "champ": { "type": "string", "defaultValue": "" }, "valeur": { "type": "string", "defaultValue": "" } }, "branchCount": 0, "codes": { "arduinoc": { "code": `HttpData(/*{champ}*/,/*{valeur}*/);` } }, "handler": this.funcs.BLOCK_1653780309804 }, { "opcode": "BLOCK_1653780310011", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "arguments": { "server": { "type": "string", "defaultValue": "api.thingspeak.com" }, "page": { "type": "string", "defaultValue": "/update" } }, "branchCount": 1, "codes": { "arduinoc": { "code": `httpRequest(/*{server}*/, /*{page}*/);`, "sections": { "declare": `/*\r\nvoid AddHttpData(String field, String value){\r\n if (firstParam){\r\n ethRequest=\"\";\r\n }else{\r\n ethRequest=ethRequest+\"&\";\r\n }\r\n ethRequest=ethRequest+field+\"=\"+value;\r\n firstParam=false;\r\n}\r\n*/\r\n\r\nvoid HttpData(String field, String value){\r\n if (firstParam){\r\n client.print(field+\"=\"+value);\r\n firstParam=false;\r\n }else{\r\n client.print(\"&\"+field+\"=\"+value);\r\n }\r\n}\r\n\r\nvoid httpRequest(String strServer, String page){\r\n char server[strServer.length()+1];\r\n strServer.toCharArray(server,strServer.length()+1);\r\n if (DEBUG) Serial.print(F(\"Con. serveur...\"));\r\n ethSucceed = client.connect(server,80);\r\n if (DEBUG){\r\n if(ethSucceed) Serial.println(F(\"OK\")); else Serial.println(F(\"Failed\"));\r\n }\r\n if (DEBUG) Serial.print(F(\"Envoyer...\"));\r\n if(ethSucceed){\r\n ethSucceed = false;\r\n \r\n /*\r\n if (/*{POST}*/){\r\n \r\n client.print(F(\"POST \"));\r\n client.print(page);\r\n client.println(F(\" HTTP/1.1\"));\r\n client.print(F(\"Host: \"));\r\n client.println(strServer);\r\n client.println(F(\"Content-Type: application/x-www-form-urlencoded\"));\r\n client.println(F(\"Connection: close\"));\r\n client.println(F(\"User-Agent: Arduino/1.0\"));\r\n client.print(F(\"Content-Length: \"));\r\n client.println(ethRequest.length());\r\n client.println();\r\n client.println(ethRequest);\r\n client.println();\r\n }else{\r\n */ \r\n client.print(F(\"GET \"));\r\n client.print(page + \"?\");\r\n /*{$BRANCH1}*/\r\n client.println(F(\" HTTP/1.1\"));\r\n client.print(F(\"Host: \"));\r\n client.println(strServer);\r\n client.println(F(\"User-Agent: arduino-ethernet\"));\r\n client.println(F(\"Connection: close\"));\r\n client.println();\r\n //}\r\n ethGetData();\r\n }\r\n firstParam=true;\r\n if (DEBUG){\r\n if(ethSucceed){\r\n Serial.println(F(\"OK\")); \r\n }else{\r\n Serial.println(F(\"Failed\"));\r\n }\r\n Serial.print(F(\"reçu...\"));\r\n }\r\n}` } } }, "handler": this.funcs.BLOCK_1653780310011 }, { "opcode": "BLOCK_1654273986221", "blockType": "boolean", "checkboxInFlyout": false, "gap": 12, "arguments": {}, "branchCount": 0, "codes": { "arduinoc": { "code": `ethSucceed` } }, "handler": this.funcs.BLOCK_1654273986221 }, { "opcode": "BLOCK_1653855510926", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "port": { "type": "number", "defaultValue": 80 } }, "branchCount": 0, "codes": { "arduinoc": { "code": `ethernetInitialise();\r\nserver.begin();\r\ndelay(1000);`, "sections": { "declare": `EthernetServer server(/*{port}*/);` } } }, "handler": this.funcs.BLOCK_1653855510926 }, { "opcode": "BLOCK_1653780310978", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "arguments": { "titre": { "type": "string", "defaultValue": "titre" }, "refresh": { "type": "fieldMenu", "defaultValue": "0", "menu": "BLOCK_1653780310978_REFRESH" } }, "branchCount": 1, "codes": { "arduinoc": { "code": `while(1){\r\n EthernetClient Wclient;\r\n Wclient = server.available();\r\n if (Wclient) {\r\n while (Wclient.connected()) { \r\n if (Wclient.available()) {\r\n char c = Wclient.read();\r\n String ethRequest;\r\n if (ethRequest.length() < 100) {\r\n ethRequest += c; \r\n }\r\n if (c == '\\n') {\r\n _loop();\r\n\r\n Wclient.println(F(\"HTTP/1.1 200 OK\")); //send new page\r\n Wclient.println(F(\"Content-Type: text/html\"));\r\n if(/*{refresh}*/>0){\r\n Wclient.print(F(\"Refresh: \"));\r\n Wclient.println(String(/*{refresh}*/));\r\n }\r\n Wclient.println();\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n Wclient.print(F(\"\"));\r\n Wclient.print(String(/*{titre}*/));\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n\r\n /*{$BRANCH1}*/ \r\n\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n \r\n ethRequest = \"\";\r\n delay(1);\r\n Wclient.stop();\r\n }\r\n }\r\n }\r\n }\r\n}` } }, "handler": this.funcs.BLOCK_1653780310978 }, { "opcode": "BLOCK_1653780311427", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "texte": { "type": "string", "defaultValue": "" }, "style": { "type": "fieldMenu", "defaultValue": "p", "menu": "BLOCK_1653780311427_STYLE" } }, "branchCount": 0, "codes": { "arduinoc": { "code": `Wclient.print(F(\"\"));\r\nWclient.print(String(/*{texte}*/));\r\nWclient.println(F(\"\"));` } }, "handler": this.funcs.BLOCK_1653780311427 }, { "opcode": "BLOCK_1653780311846", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "arguments": { "texte": { "type": "string", "defaultValue": "" }, "action": { "type": "string", "defaultValue": "" } }, "branchCount": 1, "codes": { "arduinoc": { "code": `Wclient.print(F(\"\"));\r\nWclient.print(String(/*{texte}*/));\r\nWclient.print(F(\"\"));`, "sections": { "_loop": `if (ethRequest.indexOf(\"?\"+String(/*{action}*/)) >0){\r\n /*{$BRANCH1}*/ \r\n}` } } }, "handler": this.funcs.BLOCK_1653780311846 }, { "opcode": "BLOCK_1653780311631", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": {}, "branchCount": 0, "codes": { "arduinoc": { "code": `Wclient.println(F(\"
\"));` } }, "handler": this.funcs.BLOCK_1653780311631 }, { "opcode": "BLOCK_1653780312072", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "texte": { "type": "string", "defaultValue": "" }, "url": { "type": "string", "defaultValue": "http://" } }, "branchCount": 0, "codes": { "arduinoc": { "code": `Wclient.print(F(\"\"));\r\nWclient.print(String(/*{texte}*/));\r\nWclient.println(F(\"\"));` } }, "handler": this.funcs.BLOCK_1653780312072 }, { "opcode": "BLOCK_1653780312304", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "arguments": { "code": { "type": "string", "defaultValue": "" } }, "branchCount": 0, "codes": { "arduinoc": { "code": `Wclient.print(String(/*{code}*/));` } }, "handler": this.funcs.BLOCK_1653780312304 } ]); export default blocks;PK BV src/langs/PK BVsrc/langs/zh.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/de.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/es.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/fr.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/id.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/ja.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/ja-jph.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/ko.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/pl.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/uk.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/zh-hant.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/nl.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/it.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/hr.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/ru.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/pt.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/fi.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/tr.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/tk.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BVsrc/langs/en.jsexport default { "vdr_ethernet_shield": "vdr ethernet shield ", "extensionName": "vdr ethernet shield ", "extensionDescription": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "BLOCK_1653780308718": "Initialise Ethenet", "BLOCK_1675367642335": "Définir IP DHCP", "BLOCK_1653780309012": "Definir IP [IP] , Masque [Mask] , Passerelle [Gateway] , DNS [DNS] ", "BLOCK_1653780309457_IP_0": "IP", "BLOCK_1653780309457_IP_1": "DNS", "BLOCK_1653780309457_IP_2": "Passerelle", "BLOCK_1653780309457_IP_3": "Masque", "BLOCK_1653780309457": "Lire [IP] ", "BLOCK_1654274936853": "Démarrer le client WEB", "BLOCK_1653780309804": "Ajouter Donnée URL Champ [champ] Valeur [valeur]", "BLOCK_1653780310011": "Acceder page web : serveur [server] page [page] ", "BLOCK_1654273986221": "Succès", "BLOCK_1653855510926": "Démarrer serveur WEB port [port] ", "BLOCK_1653780310978_REFRESH_0": "jamais", "BLOCK_1653780310978_REFRESH_1": "5 s", "BLOCK_1653780310978_REFRESH_2": "10 s", "BLOCK_1653780310978_REFRESH_3": "30 s", "BLOCK_1653780310978": "Afficher la page WEB titre [titre] rafraichir [refresh] ", "BLOCK_1653780311427_STYLE_0": "texte", "BLOCK_1653780311427_STYLE_1": "Titre1", "BLOCK_1653780311427_STYLE_2": "Titre2", "BLOCK_1653780311427": "Texte [texte] style [style] ", "BLOCK_1653780311846": "Bouton Texte [texte] nom action [action] ", "BLOCK_1653780311631": "Retour-chariot", "BLOCK_1653780312072": "Lien texte [texte] url [url] ", "BLOCK_1653780312304": "code html [code] ", "cate_a6db9026": "Ethernet shield" };PK BViisrc/langs/index.jsimport zh from './zh.js'; import de from './de.js'; import es from './es.js'; import fr from './fr.js'; import id from './id.js'; import ja from './ja.js'; import jaJph from './ja-jph.js'; import ko from './ko.js'; import pl from './pl.js'; import uk from './uk.js'; import zhHant from './zh-hant.js'; import nl from './nl.js'; import it from './it.js'; import hr from './hr.js'; import ru from './ru.js'; import pt from './pt.js'; import fi from './fi.js'; import tr from './tr.js'; import tk from './tk.js'; import en from './en.js'; const langs = { 'zh': zh, 'de': de, 'es': es, 'fr': fr, 'id': id, 'ja': ja, 'ja-jph': jaJph, 'ko': ko, 'pl': pl, 'uk': uk, 'zh-hant': zhHant, 'nl': nl, 'it': it, 'hr': hr, 'ru': ru, 'pt': pt, 'fi': fi, 'tr': tr, 'tk': tk, 'en': en }; export default langs;PK BVDm6 6 manifest.json{ "id": "vdr_ethernet_shield", "iconURL": "vdr_ethernet_shield/imgs/8af277f6fe6c4f1b8c6232ec68cee5b0.jpg", "coverURL": "./res/8af277f6fe6c4f1b8c6232ec68cee5b0.jpg", "name": { "zh": "vdr ethernet shield ", "de": "vdr ethernet shield ", "es": "vdr ethernet shield ", "fr": "vdr ethernet shield ", "id": "vdr ethernet shield ", "ja": "vdr ethernet shield ", "ja-jph": "vdr ethernet shield ", "ko": "vdr ethernet shield ", "pl": "vdr ethernet shield ", "uk": "vdr ethernet shield ", "zh-hant": "vdr ethernet shield ", "nl": "vdr ethernet shield ", "it": "vdr ethernet shield ", "hr": "vdr ethernet shield ", "ru": "vdr ethernet shield ", "pt": "vdr ethernet shield ", "fi": "vdr ethernet shield ", "tr": "vdr ethernet shield ", "tk": "vdr ethernet shield ", "en": "vdr ethernet shield " }, "description": { "zh": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "de": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "es": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "fr": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "id": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "ja": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "ja-jph": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "ko": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "pl": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "uk": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "zh-hant": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "nl": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "it": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "hr": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "ru": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "pt": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "fi": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "tr": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "tk": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "en": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique" }, "targets": [ "arduino_mega2560", "arduino_uno" ], "main": "vdr_ethernet_shield/index.js", "codeTypes": [ "arduinoc" ], "device": false, "sortId": 999, "version": "1.0.0", "extApiVersion": [ "1.0.3" ], "platform": [ "mblockpc" ], "homepage": "https://www.du-man.net", "feature": [ "worker" ] }PK BV data.bak/PK BV,{;;data.bak/ext.json{ "identify": "vdr_ethernet_shield", "version": "1.0.0", "device": false, "template": "arduinoc", "cover": { "name": "shield ethernet.jpg", "url": "https://mblock-expanded.oss-cn-shenzhen.aliyuncs.com/8af277f6fe6c4f1b8c6232ec68cee5b0.jpg" }, "codeTypes": [ "arduinoc" ], "generator": { "arduinoc": { "template": "// generated by mBlock5 for \n// codes make you happy\n\n//( include //)\n#include \n//( lib //)\n\n//({\n this.$ALL_VARIABLES.length==0?'':this.$ALL_VARIABLES.map(v=>\"float \"+v+\" = 0;\").join('\\\\n')\n}//)\n\n//( declare //)\n\n\nvoid _delay(float seconds) {\n long endTime = millis() + seconds * 1000;\n while(millis() < endTime) _loop();\n}\n\n//(\nvoid setup() {\n //( setup //)\n //( code //)\n}\n//)\n\nvoid _loop() {\n //( _loop //)\n}\n\nvoid loop() {\n _loop();\n}", "generator": "({\n lang: 'arduinoc',\n template: `<%=template%>`,\n splitor: {\n frame: {\n left: \"//(\",\n right: \"//)\",\n },\n expression: {\n left: \"/*{\",\n right: \"}*/\",\n }\n },\n reducers: [\n {\n name: 'include',\n reduce: (codes) => {\n let codes1 = []\n for (let code of codes) {\n let codeStr = '';\n if (typeof code === 'string') {\n codeStr = code;\n } else if (typeof code === 'function') {\n codeStr = code();\n }\n if (codes1.indexOf(codeStr) === -1) {\n codes1.push(codeStr);\n }\n }\n if (codes1.length === 0) {\n return undefined;\n }\n return codes1.map(code => {\n return '#include ' + code;\n }).join('\\n') + '\\n'\n }\n }\n ]\n})", "snippets": "", "sources": [ { "name": "src/Dhcp.cpp", "url": "src/Dhcp.cpp", "fileData": "// DHCP Library v0.3 - April 25, 2009\n// Author: Jordan Terrell - blog.jordanterrell.com\n\n#include \n#include \"Ethernet.h\"\n#include \"Dhcp.h\"\n#include \"w5100.h\"\n\nint DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)\n{\n\t_dhcpLeaseTime=0;\n\t_dhcpT1=0;\n\t_dhcpT2=0;\n\t_timeout = timeout;\n\t_responseTimeout = responseTimeout;\n\n\t// zero out _dhcpMacAddr\n\tmemset(_dhcpMacAddr, 0, 6);\n\treset_DHCP_lease();\n\n\tmemcpy((void*)_dhcpMacAddr, (void*)mac, 6);\n\t_dhcp_state = STATE_DHCP_START;\n\treturn request_DHCP_lease();\n}\n\nvoid DhcpClass::reset_DHCP_lease()\n{\n\t// zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp\n\tmemset(_dhcpLocalIp, 0, 20);\n}\n\n\t//return:0 on error, 1 if request is sent and response is received\nint DhcpClass::request_DHCP_lease()\n{\n\tuint8_t messageType = 0;\n\n\t// Pick an initial transaction ID\n\t_dhcpTransactionId = random(1UL, 2000UL);\n\t_dhcpInitialTransactionId = _dhcpTransactionId;\n\n\t_dhcpUdpSocket.stop();\n\tif (_dhcpUdpSocket.begin(DHCP_CLIENT_PORT) == 0) {\n\t\t// Couldn't get a socket\n\t\treturn 0;\n\t}\n\n\tpresend_DHCP();\n\n\tint result = 0;\n\n\tunsigned long startTime = millis();\n\n\twhile (_dhcp_state != STATE_DHCP_LEASED) {\n\t\tif (_dhcp_state == STATE_DHCP_START) {\n\t\t\t_dhcpTransactionId++;\n\t\t\tsend_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000));\n\t\t\t_dhcp_state = STATE_DHCP_DISCOVER;\n\t\t} else if (_dhcp_state == STATE_DHCP_REREQUEST) {\n\t\t\t_dhcpTransactionId++;\n\t\t\tsend_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000));\n\t\t\t_dhcp_state = STATE_DHCP_REQUEST;\n\t\t} else if (_dhcp_state == STATE_DHCP_DISCOVER) {\n\t\t\tuint32_t respId;\n\t\t\tmessageType = parseDHCPResponse(_responseTimeout, respId);\n\t\t\tif (messageType == DHCP_OFFER) {\n\t\t\t\t// We'll use the transaction ID that the offer came with,\n\t\t\t\t// rather than the one we were up to\n\t\t\t\t_dhcpTransactionId = respId;\n\t\t\t\tsend_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));\n\t\t\t\t_dhcp_state = STATE_DHCP_REQUEST;\n\t\t\t}\n\t\t} else if (_dhcp_state == STATE_DHCP_REQUEST) {\n\t\t\tuint32_t respId;\n\t\t\tmessageType = parseDHCPResponse(_responseTimeout, respId);\n\t\t\tif (messageType == DHCP_ACK) {\n\t\t\t\t_dhcp_state = STATE_DHCP_LEASED;\n\t\t\t\tresult = 1;\n\t\t\t\t//use default lease time if we didn't get it\n\t\t\t\tif (_dhcpLeaseTime == 0) {\n\t\t\t\t\t_dhcpLeaseTime = DEFAULT_LEASE;\n\t\t\t\t}\n\t\t\t\t// Calculate T1 & T2 if we didn't get it\n\t\t\t\tif (_dhcpT1 == 0) {\n\t\t\t\t\t// T1 should be 50% of _dhcpLeaseTime\n\t\t\t\t\t_dhcpT1 = _dhcpLeaseTime >> 1;\n\t\t\t\t}\n\t\t\t\tif (_dhcpT2 == 0) {\n\t\t\t\t\t// T2 should be 87.5% (7/8ths) of _dhcpLeaseTime\n\t\t\t\t\t_dhcpT2 = _dhcpLeaseTime - (_dhcpLeaseTime >> 3);\n\t\t\t\t}\n\t\t\t\t_renewInSec = _dhcpT1;\n\t\t\t\t_rebindInSec = _dhcpT2;\n\t\t\t} else if (messageType == DHCP_NAK) {\n\t\t\t\t_dhcp_state = STATE_DHCP_START;\n\t\t\t}\n\t\t}\n\n\t\tif (messageType == 255) {\n\t\t\tmessageType = 0;\n\t\t\t_dhcp_state = STATE_DHCP_START;\n\t\t}\n\n\t\tif (result != 1 && ((millis() - startTime) > _timeout))\n\t\t\tbreak;\n\t}\n\n\t// We're done with the socket now\n\t_dhcpUdpSocket.stop();\n\t_dhcpTransactionId++;\n\n\t_lastCheckLeaseMillis = millis();\n\treturn result;\n}\n\nvoid DhcpClass::presend_DHCP()\n{\n}\n\nvoid DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed)\n{\n\tuint8_t buffer[32];\n\tmemset(buffer, 0, 32);\n\tIPAddress dest_addr(255, 255, 255, 255); // Broadcast address\n\n\tif (_dhcpUdpSocket.beginPacket(dest_addr, DHCP_SERVER_PORT) == -1) {\n\t\t//Serial.printf(\"DHCP transmit error\\n\");\n\t\t// FIXME Need to return errors\n\t\treturn;\n\t}\n\n\tbuffer[0] = DHCP_BOOTREQUEST; // op\n\tbuffer[1] = DHCP_HTYPE10MB; // htype\n\tbuffer[2] = DHCP_HLENETHERNET; // hlen\n\tbuffer[3] = DHCP_HOPS; // hops\n\n\t// xid\n\tunsigned long xid = htonl(_dhcpTransactionId);\n\tmemcpy(buffer + 4, &(xid), 4);\n\n\t// 8, 9 - seconds elapsed\n\tbuffer[8] = ((secondsElapsed & 0xff00) >> 8);\n\tbuffer[9] = (secondsElapsed & 0x00ff);\n\n\t// flags\n\tunsigned short flags = htons(DHCP_FLAGSBROADCAST);\n\tmemcpy(buffer + 10, &(flags), 2);\n\n\t// ciaddr: already zeroed\n\t// yiaddr: already zeroed\n\t// siaddr: already zeroed\n\t// giaddr: already zeroed\n\n\t//put data in W5100 transmit buffer\n\t_dhcpUdpSocket.write(buffer, 28);\n\n\tmemset(buffer, 0, 32); // clear local buffer\n\n\tmemcpy(buffer, _dhcpMacAddr, 6); // chaddr\n\n\t//put data in W5100 transmit buffer\n\t_dhcpUdpSocket.write(buffer, 16);\n\n\tmemset(buffer, 0, 32); // clear local buffer\n\n\t// leave zeroed out for sname && file\n\t// put in W5100 transmit buffer x 6 (192 bytes)\n\n\tfor(int i = 0; i < 6; i++) {\n\t\t_dhcpUdpSocket.write(buffer, 32);\n\t}\n\n\t// OPT - Magic Cookie\n\tbuffer[0] = (uint8_t)((MAGIC_COOKIE >> 24)& 0xFF);\n\tbuffer[1] = (uint8_t)((MAGIC_COOKIE >> 16)& 0xFF);\n\tbuffer[2] = (uint8_t)((MAGIC_COOKIE >> 8)& 0xFF);\n\tbuffer[3] = (uint8_t)(MAGIC_COOKIE& 0xFF);\n\n\t// OPT - message type\n\tbuffer[4] = dhcpMessageType;\n\tbuffer[5] = 0x01;\n\tbuffer[6] = messageType; //DHCP_REQUEST;\n\n\t// OPT - client identifier\n\tbuffer[7] = dhcpClientIdentifier;\n\tbuffer[8] = 0x07;\n\tbuffer[9] = 0x01;\n\tmemcpy(buffer + 10, _dhcpMacAddr, 6);\n\n\t// OPT - host name\n\tbuffer[16] = hostName;\n\tbuffer[17] = strlen(HOST_NAME) + 6; // length of hostname + last 3 bytes of mac address\n\tstrcpy((char*)&(buffer[18]), HOST_NAME);\n\n\tprintByte((char*)&(buffer[24]), _dhcpMacAddr[3]);\n\tprintByte((char*)&(buffer[26]), _dhcpMacAddr[4]);\n\tprintByte((char*)&(buffer[28]), _dhcpMacAddr[5]);\n\n\t//put data in W5100 transmit buffer\n\t_dhcpUdpSocket.write(buffer, 30);\n\n\tif (messageType == DHCP_REQUEST) {\n\t\tbuffer[0] = dhcpRequestedIPaddr;\n\t\tbuffer[1] = 0x04;\n\t\tbuffer[2] = _dhcpLocalIp[0];\n\t\tbuffer[3] = _dhcpLocalIp[1];\n\t\tbuffer[4] = _dhcpLocalIp[2];\n\t\tbuffer[5] = _dhcpLocalIp[3];\n\n\t\tbuffer[6] = dhcpServerIdentifier;\n\t\tbuffer[7] = 0x04;\n\t\tbuffer[8] = _dhcpDhcpServerIp[0];\n\t\tbuffer[9] = _dhcpDhcpServerIp[1];\n\t\tbuffer[10] = _dhcpDhcpServerIp[2];\n\t\tbuffer[11] = _dhcpDhcpServerIp[3];\n\n\t\t//put data in W5100 transmit buffer\n\t\t_dhcpUdpSocket.write(buffer, 12);\n\t}\n\n\tbuffer[0] = dhcpParamRequest;\n\tbuffer[1] = 0x06;\n\tbuffer[2] = subnetMask;\n\tbuffer[3] = routersOnSubnet;\n\tbuffer[4] = dns;\n\tbuffer[5] = domainName;\n\tbuffer[6] = dhcpT1value;\n\tbuffer[7] = dhcpT2value;\n\tbuffer[8] = endOption;\n\n\t//put data in W5100 transmit buffer\n\t_dhcpUdpSocket.write(buffer, 9);\n\n\t_dhcpUdpSocket.endPacket();\n}\n\nuint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId)\n{\n\tuint8_t type = 0;\n\tuint8_t opt_len = 0;\n\n\tunsigned long startTime = millis();\n\n\twhile (_dhcpUdpSocket.parsePacket() <= 0) {\n\t\tif ((millis() - startTime) > responseTimeout) {\n\t\t\treturn 255;\n\t\t}\n\t\tdelay(50);\n\t}\n\t// start reading in the packet\n\tRIP_MSG_FIXED fixedMsg;\n\t_dhcpUdpSocket.read((uint8_t*)&fixedMsg, sizeof(RIP_MSG_FIXED));\n\n\tif (fixedMsg.op == DHCP_BOOTREPLY && _dhcpUdpSocket.remotePort() == DHCP_SERVER_PORT) {\n\t\ttransactionId = ntohl(fixedMsg.xid);\n\t\tif (memcmp(fixedMsg.chaddr, _dhcpMacAddr, 6) != 0 ||\n\t\t (transactionId < _dhcpInitialTransactionId) ||\n\t\t (transactionId > _dhcpTransactionId)) {\n\t\t\t// Need to read the rest of the packet here regardless\n\t\t\t_dhcpUdpSocket.flush(); // FIXME\n\t\t\treturn 0;\n\t\t}\n\n\t\tmemcpy(_dhcpLocalIp, fixedMsg.yiaddr, 4);\n\n\t\t// Skip to the option part\n\t\t_dhcpUdpSocket.read((uint8_t *)NULL, 240 - (int)sizeof(RIP_MSG_FIXED));\n\n\t\twhile (_dhcpUdpSocket.available() > 0) {\n\t\t\tswitch (_dhcpUdpSocket.read()) {\n\t\t\tcase endOption :\n\t\t\t\tbreak;\n\n\t\t\tcase padOption :\n\t\t\t\tbreak;\n\n\t\t\tcase dhcpMessageType :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\ttype = _dhcpUdpSocket.read();\n\t\t\t\tbreak;\n\n\t\t\tcase subnetMask :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t_dhcpUdpSocket.read(_dhcpSubnetMask, 4);\n\t\t\t\tbreak;\n\n\t\t\tcase routersOnSubnet :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t_dhcpUdpSocket.read(_dhcpGatewayIp, 4);\n\t\t\t\t_dhcpUdpSocket.read((uint8_t *)NULL, opt_len - 4);\n\t\t\t\tbreak;\n\n\t\t\tcase dns :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t_dhcpUdpSocket.read(_dhcpDnsServerIp, 4);\n\t\t\t\t_dhcpUdpSocket.read((uint8_t *)NULL, opt_len - 4);\n\t\t\t\tbreak;\n\n\t\t\tcase dhcpServerIdentifier :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\tif ( IPAddress(_dhcpDhcpServerIp) == IPAddress((uint32_t)0) ||\n\t\t\t\t IPAddress(_dhcpDhcpServerIp) == _dhcpUdpSocket.remoteIP() ) {\n\t\t\t\t\t_dhcpUdpSocket.read(_dhcpDhcpServerIp, sizeof(_dhcpDhcpServerIp));\n\t\t\t\t} else {\n\t\t\t\t\t// Skip over the rest of this option\n\t\t\t\t\t_dhcpUdpSocket.read((uint8_t *)NULL, opt_len);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase dhcpT1value :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t_dhcpUdpSocket.read((uint8_t*)&_dhcpT1, sizeof(_dhcpT1));\n\t\t\t\t_dhcpT1 = ntohl(_dhcpT1);\n\t\t\t\tbreak;\n\n\t\t\tcase dhcpT2value :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t_dhcpUdpSocket.read((uint8_t*)&_dhcpT2, sizeof(_dhcpT2));\n\t\t\t\t_dhcpT2 = ntohl(_dhcpT2);\n\t\t\t\tbreak;\n\n\t\t\tcase dhcpIPaddrLeaseTime :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t_dhcpUdpSocket.read((uint8_t*)&_dhcpLeaseTime, sizeof(_dhcpLeaseTime));\n\t\t\t\t_dhcpLeaseTime = ntohl(_dhcpLeaseTime);\n\t\t\t\t_renewInSec = _dhcpLeaseTime;\n\t\t\t\tbreak;\n\n\t\t\tdefault :\n\t\t\t\topt_len = _dhcpUdpSocket.read();\n\t\t\t\t// Skip over the rest of this option\n\t\t\t\t_dhcpUdpSocket.read((uint8_t *)NULL, opt_len);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Need to skip to end of the packet regardless here\n\t_dhcpUdpSocket.flush(); // FIXME\n\n\treturn type;\n}\n\n\n/*\n returns:\n 0/DHCP_CHECK_NONE: nothing happened\n 1/DHCP_CHECK_RENEW_FAIL: renew failed\n 2/DHCP_CHECK_RENEW_OK: renew success\n 3/DHCP_CHECK_REBIND_FAIL: rebind fail\n 4/DHCP_CHECK_REBIND_OK: rebind success\n*/\nint DhcpClass::checkLease()\n{\n\tint rc = DHCP_CHECK_NONE;\n\n\tunsigned long now = millis();\n\tunsigned long elapsed = now - _lastCheckLeaseMillis;\n\n\t// if more then one sec passed, reduce the counters accordingly\n\tif (elapsed >= 1000) {\n\t\t// set the new timestamps\n\t\t_lastCheckLeaseMillis = now - (elapsed % 1000);\n\t\telapsed = elapsed / 1000;\n\n\t\t// decrease the counters by elapsed seconds\n\t\t// we assume that the cycle time (elapsed) is fairly constant\n\t\t// if the remainder is less than cycle time * 2\n\t\t// do it early instead of late\n\t\tif (_renewInSec < elapsed * 2) {\n\t\t\t_renewInSec = 0;\n\t\t} else {\n\t\t\t_renewInSec -= elapsed;\n\t\t}\n\t\tif (_rebindInSec < elapsed * 2) {\n\t\t\t_rebindInSec = 0;\n\t\t} else {\n\t\t\t_rebindInSec -= elapsed;\n\t\t}\n\t}\n\n\t// if we have a lease but should renew, do it\n\tif (_renewInSec == 0 &&_dhcp_state == STATE_DHCP_LEASED) {\n\t\t_dhcp_state = STATE_DHCP_REREQUEST;\n\t\trc = 1 + request_DHCP_lease();\n\t}\n\n\t// if we have a lease or is renewing but should bind, do it\n\tif (_rebindInSec == 0 && (_dhcp_state == STATE_DHCP_LEASED ||\n\t _dhcp_state == STATE_DHCP_START)) {\n\t\t// this should basically restart completely\n\t\t_dhcp_state = STATE_DHCP_START;\n\t\treset_DHCP_lease();\n\t\trc = 3 + request_DHCP_lease();\n\t}\n\treturn rc;\n}\n\nIPAddress DhcpClass::getLocalIp()\n{\n\treturn IPAddress(_dhcpLocalIp);\n}\n\nIPAddress DhcpClass::getSubnetMask()\n{\n\treturn IPAddress(_dhcpSubnetMask);\n}\n\nIPAddress DhcpClass::getGatewayIp()\n{\n\treturn IPAddress(_dhcpGatewayIp);\n}\n\nIPAddress DhcpClass::getDhcpServerIp()\n{\n\treturn IPAddress(_dhcpDhcpServerIp);\n}\n\nIPAddress DhcpClass::getDnsServerIp()\n{\n\treturn IPAddress(_dhcpDnsServerIp);\n}\n\nvoid DhcpClass::printByte(char * buf, uint8_t n )\n{\n\tchar *str = &buf[1];\n\tbuf[0]='0';\n\tdo {\n\t\tunsigned long m = n;\n\t\tn /= 16;\n\t\tchar c = m - 16 * n;\n\t\t*str-- = c < 10 ? c + '0' : c + 'A' - 10;\n\t} while(n);\n}\n" }, { "name": "src/Dhcp.h", "url": "src/Dhcp.h", "fileData": "// DHCP Library v0.3 - April 25, 2009\n// Author: Jordan Terrell - blog.jordanterrell.com\n\n#ifndef Dhcp_h\n#define Dhcp_h\n\n/* DHCP state machine. */\n#define STATE_DHCP_START\t0\n#define\tSTATE_DHCP_DISCOVER\t1\n#define\tSTATE_DHCP_REQUEST\t2\n#define\tSTATE_DHCP_LEASED\t3\n#define\tSTATE_DHCP_REREQUEST\t4\n#define\tSTATE_DHCP_RELEASE\t5\n\n#define DHCP_FLAGSBROADCAST\t0x8000\n\n/* UDP port numbers for DHCP */\n#define\tDHCP_SERVER_PORT\t67\t/* from server to client */\n#define DHCP_CLIENT_PORT\t68\t/* from client to server */\n\n/* DHCP message OP code */\n#define DHCP_BOOTREQUEST\t1\n#define DHCP_BOOTREPLY\t\t2\n\n/* DHCP message type */\n#define\tDHCP_DISCOVER\t\t1\n#define DHCP_OFFER\t\t2\n#define\tDHCP_REQUEST\t\t3\n#define\tDHCP_DECLINE\t\t4\n#define\tDHCP_ACK\t\t5\n#define DHCP_NAK\t\t6\n#define\tDHCP_RELEASE\t\t7\n#define DHCP_INFORM\t\t8\n\n#define DHCP_HTYPE10MB\t\t1\n#define DHCP_HTYPE100MB\t\t2\n\n#define DHCP_HLENETHERNET\t6\n#define DHCP_HOPS\t\t0\n#define DHCP_SECS\t\t0\n\n#define MAGIC_COOKIE\t\t0x63825363\n#define MAX_DHCP_OPT\t\t16\n\n#define HOST_NAME \"WIZnet\"\n#define DEFAULT_LEASE\t(900) //default lease time in seconds\n\n#define DHCP_CHECK_NONE (0)\n#define DHCP_CHECK_RENEW_FAIL (1)\n#define DHCP_CHECK_RENEW_OK (2)\n#define DHCP_CHECK_REBIND_FAIL (3)\n#define DHCP_CHECK_REBIND_OK (4)\n\nenum\n{\n\tpadOption\t\t=\t0,\n\tsubnetMask\t\t=\t1,\n\ttimerOffset\t\t=\t2,\n\troutersOnSubnet\t\t=\t3,\n\t/* timeServer\t\t=\t4,\n\tnameServer\t\t=\t5,*/\n\tdns\t\t\t=\t6,\n\t/*logServer\t\t=\t7,\n\tcookieServer\t\t=\t8,\n\tlprServer\t\t=\t9,\n\timpressServer\t\t=\t10,\n\tresourceLocationServer\t=\t11,*/\n\thostName\t\t=\t12,\n\t/*bootFileSize\t\t=\t13,\n\tmeritDumpFile\t\t=\t14,*/\n\tdomainName\t\t=\t15,\n\t/*swapServer\t\t=\t16,\n\trootPath\t\t=\t17,\n\textentionsPath\t\t=\t18,\n\tIPforwarding\t\t=\t19,\n\tnonLocalSourceRouting\t=\t20,\n\tpolicyFilter\t\t=\t21,\n\tmaxDgramReasmSize\t=\t22,\n\tdefaultIPTTL\t\t=\t23,\n\tpathMTUagingTimeout\t=\t24,\n\tpathMTUplateauTable\t=\t25,\n\tifMTU\t\t\t=\t26,\n\tallSubnetsLocal\t\t=\t27,\n\tbroadcastAddr\t\t=\t28,\n\tperformMaskDiscovery\t=\t29,\n\tmaskSupplier\t\t=\t30,\n\tperformRouterDiscovery\t=\t31,\n\trouterSolicitationAddr\t=\t32,\n\tstaticRoute\t\t=\t33,\n\ttrailerEncapsulation\t=\t34,\n\tarpCacheTimeout\t\t=\t35,\n\tethernetEncapsulation\t=\t36,\n\ttcpDefaultTTL\t\t=\t37,\n\ttcpKeepaliveInterval\t=\t38,\n\ttcpKeepaliveGarbage\t=\t39,\n\tnisDomainName\t\t=\t40,\n\tnisServers\t\t=\t41,\n\tntpServers\t\t=\t42,\n\tvendorSpecificInfo\t=\t43,\n\tnetBIOSnameServer\t=\t44,\n\tnetBIOSdgramDistServer\t=\t45,\n\tnetBIOSnodeType\t\t=\t46,\n\tnetBIOSscope\t\t=\t47,\n\txFontServer\t\t=\t48,\n\txDisplayManager\t\t=\t49,*/\n\tdhcpRequestedIPaddr\t=\t50,\n\tdhcpIPaddrLeaseTime\t=\t51,\n\t/*dhcpOptionOverload\t=\t52,*/\n\tdhcpMessageType\t\t=\t53,\n\tdhcpServerIdentifier\t=\t54,\n\tdhcpParamRequest\t=\t55,\n\t/*dhcpMsg\t\t\t=\t56,\n\tdhcpMaxMsgSize\t\t=\t57,*/\n\tdhcpT1value\t\t=\t58,\n\tdhcpT2value\t\t=\t59,\n\t/*dhcpClassIdentifier\t=\t60,*/\n\tdhcpClientIdentifier\t=\t61,\n\tendOption\t\t=\t255\n};\n\ntypedef struct _RIP_MSG_FIXED\n{\n\tuint8_t op;\n\tuint8_t htype;\n\tuint8_t hlen;\n\tuint8_t hops;\n\tuint32_t xid;\n\tuint16_t secs;\n\tuint16_t flags;\n\tuint8_t ciaddr[4];\n\tuint8_t yiaddr[4];\n\tuint8_t siaddr[4];\n\tuint8_t giaddr[4];\n\tuint8_t chaddr[6];\n} RIP_MSG_FIXED;\n\n#endif\n" }, { "name": "src/Dns.cpp", "url": "src/Dns.cpp", "fileData": "// Arduino DNS client for WizNet5100-based Ethernet shield\n// (c) Copyright 2009-2010 MCQN Ltd.\n// Released under Apache License, version 2.0\n\n#include \n#include \"Ethernet.h\"\n#include \"Dns.h\"\n#include \"w5100.h\"\n\n\n#define SOCKET_NONE 255\n// Various flags and header field values for a DNS message\n#define UDP_HEADER_SIZE 8\n#define DNS_HEADER_SIZE 12\n#define TTL_SIZE 4\n#define QUERY_FLAG (0)\n#define RESPONSE_FLAG (1<<15)\n#define QUERY_RESPONSE_MASK (1<<15)\n#define OPCODE_STANDARD_QUERY (0)\n#define OPCODE_INVERSE_QUERY (1<<11)\n#define OPCODE_STATUS_REQUEST (2<<11)\n#define OPCODE_MASK (15<<11)\n#define AUTHORITATIVE_FLAG (1<<10)\n#define TRUNCATION_FLAG (1<<9)\n#define RECURSION_DESIRED_FLAG (1<<8)\n#define RECURSION_AVAILABLE_FLAG (1<<7)\n#define RESP_NO_ERROR (0)\n#define RESP_FORMAT_ERROR (1)\n#define RESP_SERVER_FAILURE (2)\n#define RESP_NAME_ERROR (3)\n#define RESP_NOT_IMPLEMENTED (4)\n#define RESP_REFUSED (5)\n#define RESP_MASK (15)\n#define TYPE_A (0x0001)\n#define CLASS_IN (0x0001)\n#define LABEL_COMPRESSION_MASK (0xC0)\n// Port number that DNS servers listen on\n#define DNS_PORT 53\n\n// Possible return codes from ProcessResponse\n#define SUCCESS 1\n#define TIMED_OUT -1\n#define INVALID_SERVER -2\n#define TRUNCATED -3\n#define INVALID_RESPONSE -4\n\nvoid DNSClient::begin(const IPAddress& aDNSServer)\n{\n\tiDNSServer = aDNSServer;\n\tiRequestId = 0;\n}\n\n\nint DNSClient::inet_aton(const char* address, IPAddress& result)\n{\n\tuint16_t acc = 0; // Accumulator\n\tuint8_t dots = 0;\n\n\twhile (*address) {\n\t\tchar c = *address++;\n\t\tif (c >= '0' && c <= '9') {\n\t\t\tacc = acc * 10 + (c - '0');\n\t\t\tif (acc > 255) {\n\t\t\t\t// Value out of [0..255] range\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t} else if (c == '.') {\n\t\t\tif (dots == 3) {\n\t\t\t\t// Too much dots (there must be 3 dots)\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tresult[dots++] = acc;\n\t\t\tacc = 0;\n\t\t} else {\n\t\t\t// Invalid char\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tif (dots != 3) {\n\t\t// Too few dots (there must be 3 dots)\n\t\treturn 0;\n\t}\n\tresult[3] = acc;\n\treturn 1;\n}\n\nint DNSClient::getHostByName(const char* aHostname, IPAddress& aResult, uint16_t timeout)\n{\n\tint ret = 0;\n\n\t// See if it's a numeric IP address\n\tif (inet_aton(aHostname, aResult)) {\n\t\t// It is, our work here is done\n\t\treturn 1;\n\t}\n\n\t// Check we've got a valid DNS server to use\n\tif (iDNSServer == INADDR_NONE) {\n\t\treturn INVALID_SERVER;\n\t}\n\t\n\t// Find a socket to use\n\tif (iUdp.begin(1024+(millis() & 0xF)) == 1) {\n\t\t// Try up to three times\n\t\tint retries = 0;\n\t\t// while ((retries < 3) && (ret <= 0)) {\n\t\t// Send DNS request\n\t\tret = iUdp.beginPacket(iDNSServer, DNS_PORT);\n\t\tif (ret != 0) {\n\t\t\t// Now output the request data\n\t\t\tret = BuildRequest(aHostname);\n\t\t\tif (ret != 0) {\n\t\t\t\t// And finally send the request\n\t\t\t\tret = iUdp.endPacket();\n\t\t\t\tif (ret != 0) {\n\t\t\t\t\t// Now wait for a response\n\t\t\t\t\tint wait_retries = 0;\n\t\t\t\t\tret = TIMED_OUT;\n\t\t\t\t\twhile ((wait_retries < 3) && (ret == TIMED_OUT)) {\n\t\t\t\t\t\tret = ProcessResponse(timeout, aResult);\n\t\t\t\t\t\twait_retries++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tretries++;\n\t\t//}\n\n\t\t// We're done with the socket now\n\t\tiUdp.stop();\n\t}\n\n\treturn ret;\n}\n\nuint16_t DNSClient::BuildRequest(const char* aName)\n{\n\t// Build header\n\t// 1 1 1 1 1 1\n\t// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// | ID |\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// |QR| Opcode |AA|TC|RD|RA| Z | RCODE |\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// | QDCOUNT |\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// | ANCOUNT |\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// | NSCOUNT |\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// | ARCOUNT |\n\t// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\t// As we only support one request at a time at present, we can simplify\n\t// some of this header\n\tiRequestId = millis(); // generate a random ID\n\tuint16_t twoByteBuffer;\n\n\t// FIXME We should also check that there's enough space available to write to, rather\n\t// FIXME than assume there's enough space (as the code does at present)\n\tiUdp.write((uint8_t*)&iRequestId, sizeof(iRequestId));\n\n\ttwoByteBuffer = htons(QUERY_FLAG | OPCODE_STANDARD_QUERY | RECURSION_DESIRED_FLAG);\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\n\ttwoByteBuffer = htons(1); // One question record\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\n\ttwoByteBuffer = 0; // Zero answer records\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\t// and zero additional records\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\n\t// Build question\n\tconst char* start =aName;\n\tconst char* end =start;\n\tuint8_t len;\n\t// Run through the name being requested\n\twhile (*end) {\n\t\t// Find out how long this section of the name is\n\t\tend = start;\n\t\twhile (*end && (*end != '.') ) {\n\t\t\tend++;\n\t\t}\n\n\t\tif (end-start > 0) {\n\t\t\t// Write out the size of this section\n\t\t\tlen = end-start;\n\t\t\tiUdp.write(&len, sizeof(len));\n\t\t\t// And then write out the section\n\t\t\tiUdp.write((uint8_t*)start, end-start);\n\t\t}\n\t\tstart = end+1;\n\t}\n\n\t// We've got to the end of the question name, so\n\t// terminate it with a zero-length section\n\tlen = 0;\n\tiUdp.write(&len, sizeof(len));\n\t// Finally the type and class of question\n\ttwoByteBuffer = htons(TYPE_A);\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\n\ttwoByteBuffer = htons(CLASS_IN); // Internet class of question\n\tiUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));\n\t// Success! Everything buffered okay\n\treturn 1;\n}\n\n\nuint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress)\n{\n\tuint32_t startTime = millis();\n\n\t// Wait for a response packet\n\twhile (iUdp.parsePacket() <= 0) {\n\t\tif ((millis() - startTime) > aTimeout) {\n\t\t\treturn TIMED_OUT;\n\t\t}\n\t\tdelay(50);\n\t}\n\n\t// We've had a reply!\n\t// Read the UDP header\n\t//uint8_t header[DNS_HEADER_SIZE]; // Enough space to reuse for the DNS header\n\tunion {\n\t\tuint8_t byte[DNS_HEADER_SIZE]; // Enough space to reuse for the DNS header\n\t\tuint16_t word[DNS_HEADER_SIZE/2];\n\t} header;\n\n\t// Check that it's a response from the right server and the right port\n\tif ( (iDNSServer != iUdp.remoteIP()) || (iUdp.remotePort() != DNS_PORT) ) {\n\t\t// It's not from who we expected\n\t\treturn INVALID_SERVER;\n\t}\n\n\t// Read through the rest of the response\n\tif (iUdp.available() < DNS_HEADER_SIZE) {\n\t\treturn TRUNCATED;\n\t}\n\tiUdp.read(header.byte, DNS_HEADER_SIZE);\n\n\tuint16_t header_flags = htons(header.word[1]);\n\t// Check that it's a response to this request\n\tif ((iRequestId != (header.word[0])) ||\n\t ((header_flags & QUERY_RESPONSE_MASK) != (uint16_t)RESPONSE_FLAG) ) {\n\t\t// Mark the entire packet as read\n\t\tiUdp.flush(); // FIXME\n\t\treturn INVALID_RESPONSE;\n\t}\n\t// Check for any errors in the response (or in our request)\n\t// although we don't do anything to get round these\n\tif ( (header_flags & TRUNCATION_FLAG) || (header_flags & RESP_MASK) ) {\n\t\t// Mark the entire packet as read\n\t\tiUdp.flush(); // FIXME\n\t\treturn -5; //INVALID_RESPONSE;\n\t}\n\n\t// And make sure we've got (at least) one answer\n\tuint16_t answerCount = htons(header.word[3]);\n\tif (answerCount == 0) {\n\t\t// Mark the entire packet as read\n\t\tiUdp.flush(); // FIXME\n\t\treturn -6; //INVALID_RESPONSE;\n\t}\n\n\t// Skip over any questions\n\tfor (uint16_t i=0; i < htons(header.word[2]); i++) {\n\t\t// Skip over the name\n\t\tuint8_t len;\n\t\tdo {\n\t\t\tiUdp.read(&len, sizeof(len));\n\t\t\tif (len > 0) {\n\t\t\t\t// Don't need to actually read the data out for the string, just\n\t\t\t\t// advance ptr to beyond it\n\t\t\t\tiUdp.read((uint8_t *)NULL, (size_t)len);\n\t\t\t}\n\t\t} while (len != 0);\n\n\t\t// Now jump over the type and class\n\t\tiUdp.read((uint8_t *)NULL, 4);\n\t}\n\n\t// Now we're up to the bit we're interested in, the answer\n\t// There might be more than one answer (although we'll just use the first\n\t// type A answer) and some authority and additional resource records but\n\t// we're going to ignore all of them.\n\n\tfor (uint16_t i=0; i < answerCount; i++) {\n\t\t// Skip the name\n\t\tuint8_t len;\n\t\tdo {\n\t\t\tiUdp.read(&len, sizeof(len));\n\t\t\tif ((len & LABEL_COMPRESSION_MASK) == 0) {\n\t\t\t\t// It's just a normal label\n\t\t\t\tif (len > 0) {\n\t\t\t\t\t// And it's got a length\n\t\t\t\t\t// Don't need to actually read the data out for the string,\n\t\t\t\t\t// just advance ptr to beyond it\n\t\t\t\t\tiUdp.read((uint8_t *)NULL, len);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// This is a pointer to a somewhere else in the message for the\n\t\t\t\t// rest of the name. We don't care about the name, and RFC1035\n\t\t\t\t// says that a name is either a sequence of labels ended with a\n\t\t\t\t// 0 length octet or a pointer or a sequence of labels ending in\n\t\t\t\t// a pointer. Either way, when we get here we're at the end of\n\t\t\t\t// the name\n\t\t\t\t// Skip over the pointer\n\t\t\t\tiUdp.read((uint8_t *)NULL, 1); // we don't care about the byte\n\t\t\t\t// And set len so that we drop out of the name loop\n\t\t\t\tlen = 0;\n\t\t\t}\n\t\t} while (len != 0);\n\n\t\t// Check the type and class\n\t\tuint16_t answerType;\n\t\tuint16_t answerClass;\n\t\tiUdp.read((uint8_t*)&answerType, sizeof(answerType));\n\t\tiUdp.read((uint8_t*)&answerClass, sizeof(answerClass));\n\n\t\t// Ignore the Time-To-Live as we don't do any caching\n\t\tiUdp.read((uint8_t *)NULL, TTL_SIZE); // don't care about the returned bytes\n\n\t\t// And read out the length of this answer\n\t\t// Don't need header_flags anymore, so we can reuse it here\n\t\tiUdp.read((uint8_t*)&header_flags, sizeof(header_flags));\n\n\t\tif ( (htons(answerType) == TYPE_A) && (htons(answerClass) == CLASS_IN) ) {\n\t\t\tif (htons(header_flags) != 4) {\n\t\t\t\t// It's a weird size\n\t\t\t\t// Mark the entire packet as read\n\t\t\t\tiUdp.flush(); // FIXME\n\t\t\t\treturn -9;//INVALID_RESPONSE;\n\t\t\t}\n\t\t\t// FIXME: seeems to lock up here on ESP8266, but why??\n\t\t\tiUdp.read(aAddress.raw_address(), 4);\n\t\t\treturn SUCCESS;\n\t\t} else {\n\t\t\t// This isn't an answer type we're after, move onto the next one\n\t\t\tiUdp.read((uint8_t *)NULL, htons(header_flags));\n\t\t}\n\t}\n\n\t// Mark the entire packet as read\n\tiUdp.flush(); // FIXME\n\n\t// If we get here then we haven't found an answer\n\treturn -10; //INVALID_RESPONSE;\n}\n\n" }, { "name": "src/Dns.h", "url": "src/Dns.h", "fileData": "// Arduino DNS client for WizNet5100-based Ethernet shield\n// (c) Copyright 2009-2010 MCQN Ltd.\n// Released under Apache License, version 2.0\n\n#ifndef DNSClient_h\n#define DNSClient_h\n\n#include \"Ethernet.h\"\n\nclass DNSClient\n{\npublic:\n\tvoid begin(const IPAddress& aDNSServer);\n\n\t/** Convert a numeric IP address string into a four-byte IP address.\n\t @param aIPAddrString IP address to convert\n\t @param aResult IPAddress structure to store the returned IP address\n\t @result 1 if aIPAddrString was successfully converted to an IP address,\n\t else error code\n\t*/\n\tint inet_aton(const char *aIPAddrString, IPAddress& aResult);\n\n\t/** Resolve the given hostname to an IP address.\n\t @param aHostname Name to be resolved\n\t @param aResult IPAddress structure to store the returned IP address\n\t @result 1 if aIPAddrString was successfully converted to an IP address,\n\t else error code\n\t*/\n\tint getHostByName(const char* aHostname, IPAddress& aResult, uint16_t timeout=5000);\n\nprotected:\n\tuint16_t BuildRequest(const char* aName);\n\tuint16_t ProcessResponse(uint16_t aTimeout, IPAddress& aAddress);\n\n\tIPAddress iDNSServer;\n\tuint16_t iRequestId;\n\tEthernetUDP iUdp;\n};\n\n#endif\n" }, { "name": "src/Ethernet.cpp", "url": "src/Ethernet.cpp", "fileData": "/* Copyright 2018 Paul Stoffregen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this\n * software and associated documentation files (the \"Software\"), to deal in the Software\n * without restriction, including without limitation the rights to use, copy, modify,\n * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \n#include \"Ethernet.h\"\n#include \"w5100.h\"\n#include \"Dhcp.h\"\n\nIPAddress EthernetClass::_dnsServerAddress;\nDhcpClass* EthernetClass::_dhcp = NULL;\n\nint EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)\n{\n\tstatic DhcpClass s_dhcp;\n\t_dhcp = &s_dhcp;\n\n\t// Initialise the basic info\n\tif (W5100.init() == 0) return 0;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.setMACAddress(mac);\n\tW5100.setIPAddress(IPAddress(0,0,0,0).raw_address());\n\tSPI.endTransaction();\n\n\t// Now try to get our config info from a DHCP server\n\tint ret = _dhcp->beginWithDHCP(mac, timeout, responseTimeout);\n\tif (ret == 1) {\n\t\t// We've successfully found a DHCP server and got our configuration\n\t\t// info, so set things accordingly\n\t\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\t\tW5100.setIPAddress(_dhcp->getLocalIp().raw_address());\n\t\tW5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());\n\t\tW5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());\n\t\tSPI.endTransaction();\n\t\t_dnsServerAddress = _dhcp->getDnsServerIp();\n\t\tsocketPortRand(micros());\n\t}\n\treturn ret;\n}\n\nvoid EthernetClass::begin(uint8_t *mac, IPAddress ip)\n{\n\t// Assume the DNS server will be the machine on the same network as the local IP\n\t// but with last octet being '1'\n\tIPAddress dns = ip;\n\tdns[3] = 1;\n\tbegin(mac, ip, dns);\n}\n\nvoid EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns)\n{\n\t// Assume the gateway will be the machine on the same network as the local IP\n\t// but with last octet being '1'\n\tIPAddress gateway = ip;\n\tgateway[3] = 1;\n\tbegin(mac, ip, dns, gateway);\n}\n\nvoid EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway)\n{\n\tIPAddress subnet(255, 255, 255, 0);\n\tbegin(mac, ip, dns, gateway, subnet);\n}\n\nvoid EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)\n{\n\tif (W5100.init() == 0) return;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.setMACAddress(mac);\n#if ARDUINO > 106 || TEENSYDUINO > 121\n\tW5100.setIPAddress(ip._address.bytes);\n\tW5100.setGatewayIp(gateway._address.bytes);\n\tW5100.setSubnetMask(subnet._address.bytes);\n#else\n\tW5100.setIPAddress(ip._address);\n\tW5100.setGatewayIp(gateway._address);\n\tW5100.setSubnetMask(subnet._address);\n#endif\n\tSPI.endTransaction();\n\t_dnsServerAddress = dns;\n}\n\nvoid EthernetClass::init(uint8_t sspin)\n{\n\tW5100.setSS(sspin);\n}\n\nEthernetLinkStatus EthernetClass::linkStatus()\n{\n\tswitch (W5100.getLinkStatus()) {\n\t\tcase UNKNOWN: return Unknown;\n\t\tcase LINK_ON: return LinkON;\n\t\tcase LINK_OFF: return LinkOFF;\n\t\tdefault: return Unknown;\n\t}\n}\n\nEthernetHardwareStatus EthernetClass::hardwareStatus()\n{\n\tswitch (W5100.getChip()) {\n\t\tcase 51: return EthernetW5100;\n\t\tcase 52: return EthernetW5200;\n\t\tcase 55: return EthernetW5500;\n\t\tdefault: return EthernetNoHardware;\n\t}\n}\n\nint EthernetClass::maintain()\n{\n\tint rc = DHCP_CHECK_NONE;\n\tif (_dhcp != NULL) {\n\t\t// we have a pointer to dhcp, use it\n\t\trc = _dhcp->checkLease();\n\t\tswitch (rc) {\n\t\tcase DHCP_CHECK_NONE:\n\t\t\t//nothing done\n\t\t\tbreak;\n\t\tcase DHCP_CHECK_RENEW_OK:\n\t\tcase DHCP_CHECK_REBIND_OK:\n\t\t\t//we might have got a new IP.\n\t\t\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\t\t\tW5100.setIPAddress(_dhcp->getLocalIp().raw_address());\n\t\t\tW5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());\n\t\t\tW5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());\n\t\t\tSPI.endTransaction();\n\t\t\t_dnsServerAddress = _dhcp->getDnsServerIp();\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t//this is actually an error, it will retry though\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn rc;\n}\n\n\nvoid EthernetClass::MACAddress(uint8_t *mac_address)\n{\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.getMACAddress(mac_address);\n\tSPI.endTransaction();\n}\n\nIPAddress EthernetClass::localIP()\n{\n\tIPAddress ret;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.getIPAddress(ret.raw_address());\n\tSPI.endTransaction();\n\treturn ret;\n}\n\nIPAddress EthernetClass::subnetMask()\n{\n\tIPAddress ret;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.getSubnetMask(ret.raw_address());\n\tSPI.endTransaction();\n\treturn ret;\n}\n\nIPAddress EthernetClass::gatewayIP()\n{\n\tIPAddress ret;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.getGatewayIp(ret.raw_address());\n\tSPI.endTransaction();\n\treturn ret;\n}\n\nvoid EthernetClass::setMACAddress(const uint8_t *mac_address)\n{\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.setMACAddress(mac_address);\n\tSPI.endTransaction();\n}\n\nvoid EthernetClass::setLocalIP(const IPAddress local_ip)\n{\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tIPAddress ip = local_ip;\n\tW5100.setIPAddress(ip.raw_address());\n\tSPI.endTransaction();\n}\n\nvoid EthernetClass::setSubnetMask(const IPAddress subnet)\n{\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tIPAddress ip = subnet;\n\tW5100.setSubnetMask(ip.raw_address());\n\tSPI.endTransaction();\n}\n\nvoid EthernetClass::setGatewayIP(const IPAddress gateway)\n{\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tIPAddress ip = gateway;\n\tW5100.setGatewayIp(ip.raw_address());\n\tSPI.endTransaction();\n}\n\nvoid EthernetClass::setRetransmissionTimeout(uint16_t milliseconds)\n{\n\tif (milliseconds > 6553) milliseconds = 6553;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.setRetransmissionTime(milliseconds * 10);\n\tSPI.endTransaction();\n}\n\nvoid EthernetClass::setRetransmissionCount(uint8_t num)\n{\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.setRetransmissionCount(num);\n\tSPI.endTransaction();\n}\n\n\n\n\n\n\n\n\n\n\nEthernetClass Ethernet;\n" }, { "name": "src/Ethernet.h", "url": "src/Ethernet.h", "fileData": "/* Copyright 2018 Paul Stoffregen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this\n * software and associated documentation files (the \"Software\"), to deal in the Software\n * without restriction, including without limitation the rights to use, copy, modify,\n * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef ethernet_h_\n#define ethernet_h_\n\n// All symbols exposed to Arduino sketches are contained in this header file\n//\n// Older versions had much of this stuff in EthernetClient.h, EthernetServer.h,\n// and socket.h. Including headers in different order could cause trouble, so\n// these \"friend\" classes are now defined in the same header file. socket.h\n// was removed to avoid possible conflict with the C library header files.\n\n\n// Configure the maximum number of sockets to support. W5100 chips can have\n// up to 4 sockets. W5200 & W5500 can have up to 8 sockets. Several bytes\n// of RAM are used for each socket. Reducing the maximum can save RAM, but\n// you are limited to fewer simultaneous connections.\n#if defined(RAMEND) && defined(RAMSTART) && ((RAMEND - RAMSTART) <= 2048)\n#define MAX_SOCK_NUM 4\n#else\n#define MAX_SOCK_NUM 8\n#endif\n\n// By default, each socket uses 2K buffers inside the Wiznet chip. If\n// MAX_SOCK_NUM is set to fewer than the chip's maximum, uncommenting\n// this will use larger buffers within the Wiznet chip. Large buffers\n// can really help with UDP protocols like Artnet. In theory larger\n// buffers should allow faster TCP over high-latency links, but this\n// does not always seem to work in practice (maybe Wiznet bugs?)\n//#define ETHERNET_LARGE_BUFFERS\n\n\n#include \n#include \"Client.h\"\n#include \"Server.h\"\n#include \"Udp.h\"\n\nenum EthernetLinkStatus {\n\tUnknown,\n\tLinkON,\n\tLinkOFF\n};\n\nenum EthernetHardwareStatus {\n\tEthernetNoHardware,\n\tEthernetW5100,\n\tEthernetW5200,\n\tEthernetW5500\n};\n\nclass EthernetUDP;\nclass EthernetClient;\nclass EthernetServer;\nclass DhcpClass;\n\nclass EthernetClass {\nprivate:\n\tstatic IPAddress _dnsServerAddress;\n\tstatic DhcpClass* _dhcp;\npublic:\n\t// Initialise the Ethernet shield to use the provided MAC address and\n\t// gain the rest of the configuration through DHCP.\n\t// Returns 0 if the DHCP configuration failed, and 1 if it succeeded\n\tstatic int begin(uint8_t *mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);\n\tstatic int maintain();\n\tstatic EthernetLinkStatus linkStatus();\n\tstatic EthernetHardwareStatus hardwareStatus();\n\n\t// Manaul configuration\n\tstatic void begin(uint8_t *mac, IPAddress ip);\n\tstatic void begin(uint8_t *mac, IPAddress ip, IPAddress dns);\n\tstatic void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway);\n\tstatic void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);\n\tstatic void init(uint8_t sspin = 10);\n\n\tstatic void MACAddress(uint8_t *mac_address);\n\tstatic IPAddress localIP();\n\tstatic IPAddress subnetMask();\n\tstatic IPAddress gatewayIP();\n\tstatic IPAddress dnsServerIP() { return _dnsServerAddress; }\n\n\tvoid setMACAddress(const uint8_t *mac_address);\n\tvoid setLocalIP(const IPAddress local_ip);\n\tvoid setSubnetMask(const IPAddress subnet);\n\tvoid setGatewayIP(const IPAddress gateway);\n\tvoid setDnsServerIP(const IPAddress dns_server) { _dnsServerAddress = dns_server; }\n\tvoid setRetransmissionTimeout(uint16_t milliseconds);\n\tvoid setRetransmissionCount(uint8_t num);\n\n\tfriend class EthernetClient;\n\tfriend class EthernetServer;\n\tfriend class EthernetUDP;\nprivate:\n\t// Opens a socket(TCP or UDP or IP_RAW mode)\n\tstatic uint8_t socketBegin(uint8_t protocol, uint16_t port);\n\tstatic uint8_t socketBeginMulticast(uint8_t protocol, IPAddress ip,uint16_t port);\n\tstatic uint8_t socketStatus(uint8_t s);\n\t// Close socket\n\tstatic void socketClose(uint8_t s);\n\t// Establish TCP connection (Active connection)\n\tstatic void socketConnect(uint8_t s, uint8_t * addr, uint16_t port);\n\t// disconnect the connection\n\tstatic void socketDisconnect(uint8_t s);\n\t// Establish TCP connection (Passive connection)\n\tstatic uint8_t socketListen(uint8_t s);\n\t// Send data (TCP)\n\tstatic uint16_t socketSend(uint8_t s, const uint8_t * buf, uint16_t len);\n\tstatic uint16_t socketSendAvailable(uint8_t s);\n\t// Receive data (TCP)\n\tstatic int socketRecv(uint8_t s, uint8_t * buf, int16_t len);\n\tstatic uint16_t socketRecvAvailable(uint8_t s);\n\tstatic uint8_t socketPeek(uint8_t s);\n\t// sets up a UDP datagram, the data for which will be provided by one\n\t// or more calls to bufferData and then finally sent with sendUDP.\n\t// return true if the datagram was successfully set up, or false if there was an error\n\tstatic bool socketStartUDP(uint8_t s, uint8_t* addr, uint16_t port);\n\t// copy up to len bytes of data from buf into a UDP datagram to be\n\t// sent later by sendUDP. Allows datagrams to be built up from a series of bufferData calls.\n\t// return Number of bytes successfully buffered\n\tstatic uint16_t socketBufferData(uint8_t s, uint16_t offset, const uint8_t* buf, uint16_t len);\n\t// Send a UDP datagram built up from a sequence of startUDP followed by one or more\n\t// calls to bufferData.\n\t// return true if the datagram was successfully sent, or false if there was an error\n\tstatic bool socketSendUDP(uint8_t s);\n\t// Initialize the \"random\" source port number\n\tstatic void socketPortRand(uint16_t n);\n};\n\nextern EthernetClass Ethernet;\n\n\n#define UDP_TX_PACKET_MAX_SIZE 24\n\nclass EthernetUDP : public UDP {\nprivate:\n\tuint16_t _port; // local port to listen on\n\tIPAddress _remoteIP; // remote IP address for the incoming packet whilst it's being processed\n\tuint16_t _remotePort; // remote port for the incoming packet whilst it's being processed\n\tuint16_t _offset; // offset into the packet being sent\n\nprotected:\n\tuint8_t sockindex;\n\tuint16_t _remaining; // remaining bytes of incoming packet yet to be processed\n\npublic:\n\tEthernetUDP() : sockindex(MAX_SOCK_NUM) {} // Constructor\n\tvirtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use\n\tvirtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use\n\tvirtual void stop(); // Finish with the UDP socket\n\n\t// Sending UDP packets\n\n\t// Start building up a packet to send to the remote host specific in ip and port\n\t// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port\n\tvirtual int beginPacket(IPAddress ip, uint16_t port);\n\t// Start building up a packet to send to the remote host specific in host and port\n\t// Returns 1 if successful, 0 if there was a problem resolving the hostname or port\n\tvirtual int beginPacket(const char *host, uint16_t port);\n\t// Finish off this packet and send it\n\t// Returns 1 if the packet was sent successfully, 0 if there was an error\n\tvirtual int endPacket();\n\t// Write a single byte into the packet\n\tvirtual size_t write(uint8_t);\n\t// Write size bytes from buffer into the packet\n\tvirtual size_t write(const uint8_t *buffer, size_t size);\n\n\tusing Print::write;\n\n\t// Start processing the next available incoming packet\n\t// Returns the size of the packet in bytes, or 0 if no packets are available\n\tvirtual int parsePacket();\n\t// Number of bytes remaining in the current packet\n\tvirtual int available();\n\t// Read a single byte from the current packet\n\tvirtual int read();\n\t// Read up to len bytes from the current packet and place them into buffer\n\t// Returns the number of bytes read, or 0 if none are available\n\tvirtual int read(unsigned char* buffer, size_t len);\n\t// Read up to len characters from the current packet and place them into buffer\n\t// Returns the number of characters read, or 0 if none are available\n\tvirtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };\n\t// Return the next byte from the current packet without moving on to the next byte\n\tvirtual int peek();\n\tvirtual void flush(); // Finish reading the current packet\n\n\t// Return the IP address of the host who sent the current incoming packet\n\tvirtual IPAddress remoteIP() { return _remoteIP; };\n\t// Return the port of the host who sent the current incoming packet\n\tvirtual uint16_t remotePort() { return _remotePort; };\n\tvirtual uint16_t localPort() { return _port; }\n};\n\n\n\n\nclass EthernetClient : public Client {\npublic:\n\tEthernetClient() : sockindex(MAX_SOCK_NUM), _timeout(1000) { }\n\tEthernetClient(uint8_t s) : sockindex(s), _timeout(1000) { }\n\n\tuint8_t status();\n\tvirtual int connect(IPAddress ip, uint16_t port);\n\tvirtual int connect(const char *host, uint16_t port);\n\tvirtual int availableForWrite(void);\n\tvirtual size_t write(uint8_t);\n\tvirtual size_t write(const uint8_t *buf, size_t size);\n\tvirtual int available();\n\tvirtual int read();\n\tvirtual int read(uint8_t *buf, size_t size);\n\tvirtual int peek();\n\tvirtual void flush();\n\tvirtual void stop();\n\tvirtual uint8_t connected();\n\tvirtual operator bool() { return sockindex < MAX_SOCK_NUM; }\n\tvirtual bool operator==(const bool value) { return bool() == value; }\n\tvirtual bool operator!=(const bool value) { return bool() != value; }\n\tvirtual bool operator==(const EthernetClient&);\n\tvirtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); }\n\tuint8_t getSocketNumber() const { return sockindex; }\n\tvirtual uint16_t localPort();\n\tvirtual IPAddress remoteIP();\n\tvirtual uint16_t remotePort();\n\tvirtual void setConnectionTimeout(uint16_t timeout) { _timeout = timeout; }\n\n\tfriend class EthernetServer;\n\n\tusing Print::write;\n\nprivate:\n\tuint8_t sockindex; // MAX_SOCK_NUM means client not in use\n\tuint16_t _timeout;\n};\n\n\nclass EthernetServer : public Server {\nprivate:\n\tuint16_t _port;\npublic:\n\tEthernetServer(uint16_t port) : _port(port) { }\n\tEthernetClient available();\n\tEthernetClient accept();\n\tvirtual void begin();\n\tvirtual size_t write(uint8_t);\n\tvirtual size_t write(const uint8_t *buf, size_t size);\n\tvirtual operator bool();\n\tusing Print::write;\n\t//void statusreport();\n\n\t// TODO: make private when socket allocation moves to EthernetClass\n\tstatic uint16_t server_port[MAX_SOCK_NUM];\n};\n\n\nclass DhcpClass {\nprivate:\n\tuint32_t _dhcpInitialTransactionId;\n\tuint32_t _dhcpTransactionId;\n\tuint8_t _dhcpMacAddr[6];\n#ifdef __arm__\n\tuint8_t _dhcpLocalIp[4] __attribute__((aligned(4)));\n\tuint8_t _dhcpSubnetMask[4] __attribute__((aligned(4)));\n\tuint8_t _dhcpGatewayIp[4] __attribute__((aligned(4)));\n\tuint8_t _dhcpDhcpServerIp[4] __attribute__((aligned(4)));\n\tuint8_t _dhcpDnsServerIp[4] __attribute__((aligned(4)));\n#else\n\tuint8_t _dhcpLocalIp[4];\n\tuint8_t _dhcpSubnetMask[4];\n\tuint8_t _dhcpGatewayIp[4];\n\tuint8_t _dhcpDhcpServerIp[4];\n\tuint8_t _dhcpDnsServerIp[4];\n#endif\n\tuint32_t _dhcpLeaseTime;\n\tuint32_t _dhcpT1, _dhcpT2;\n\tuint32_t _renewInSec;\n\tuint32_t _rebindInSec;\n\tunsigned long _timeout;\n\tunsigned long _responseTimeout;\n\tunsigned long _lastCheckLeaseMillis;\n\tuint8_t _dhcp_state;\n\tEthernetUDP _dhcpUdpSocket;\n\n\tint request_DHCP_lease();\n\tvoid reset_DHCP_lease();\n\tvoid presend_DHCP();\n\tvoid send_DHCP_MESSAGE(uint8_t, uint16_t);\n\tvoid printByte(char *, uint8_t);\n\n\tuint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId);\npublic:\n\tIPAddress getLocalIp();\n\tIPAddress getSubnetMask();\n\tIPAddress getGatewayIp();\n\tIPAddress getDhcpServerIp();\n\tIPAddress getDnsServerIp();\n\n\tint beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000);\n\tint checkLease();\n};\n\n\n\n\n\n#endif\n" }, { "name": "src/EthernetClient.cpp", "url": "src/EthernetClient.cpp", "fileData": "/* Copyright 2018 Paul Stoffregen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this\n * software and associated documentation files (the \"Software\"), to deal in the Software\n * without restriction, including without limitation the rights to use, copy, modify,\n * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \n#include \"Ethernet.h\"\n#include \"Dns.h\"\n#include \"w5100.h\"\n\nint EthernetClient::connect(const char * host, uint16_t port)\n{\n\tDNSClient dns; // Look up the host first\n\tIPAddress remote_addr;\n\n\tif (sockindex < MAX_SOCK_NUM) {\n\t\tif (Ethernet.socketStatus(sockindex) != SnSR::CLOSED) {\n\t\t\tEthernet.socketDisconnect(sockindex); // TODO: should we call stop()?\n\t\t}\n\t\tsockindex = MAX_SOCK_NUM;\n\t}\n\tdns.begin(Ethernet.dnsServerIP());\n\tif (!dns.getHostByName(host, remote_addr)) return 0; // TODO: use _timeout\n\treturn connect(remote_addr, port);\n}\n\nint EthernetClient::connect(IPAddress ip, uint16_t port)\n{\n\tif (sockindex < MAX_SOCK_NUM) {\n\t\tif (Ethernet.socketStatus(sockindex) != SnSR::CLOSED) {\n\t\t\tEthernet.socketDisconnect(sockindex); // TODO: should we call stop()?\n\t\t}\n\t\tsockindex = MAX_SOCK_NUM;\n\t}\n#if defined(ESP8266) || defined(ESP32)\n\tif (ip == IPAddress((uint32_t)0) || ip == IPAddress(0xFFFFFFFFul)) return 0;\n#else\n\tif (ip == IPAddress(0ul) || ip == IPAddress(0xFFFFFFFFul)) return 0;\n#endif\n\tsockindex = Ethernet.socketBegin(SnMR::TCP, 0);\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\tEthernet.socketConnect(sockindex, rawIPAddress(ip), port);\n\tuint32_t start = millis();\n\twhile (1) {\n\t\tuint8_t stat = Ethernet.socketStatus(sockindex);\n\t\tif (stat == SnSR::ESTABLISHED) return 1;\n\t\tif (stat == SnSR::CLOSE_WAIT) return 1;\n\t\tif (stat == SnSR::CLOSED) return 0;\n\t\tif (millis() - start > _timeout) break;\n\t\tdelay(1);\n\t}\n\tEthernet.socketClose(sockindex);\n\tsockindex = MAX_SOCK_NUM;\n\treturn 0;\n}\n\nint EthernetClient::availableForWrite(void)\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\treturn Ethernet.socketSendAvailable(sockindex);\n}\n\nsize_t EthernetClient::write(uint8_t b)\n{\n\treturn write(&b, 1);\n}\n\nsize_t EthernetClient::write(const uint8_t *buf, size_t size)\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\tif (Ethernet.socketSend(sockindex, buf, size)) return size;\n\tsetWriteError();\n\treturn 0;\n}\n\nint EthernetClient::available()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\treturn Ethernet.socketRecvAvailable(sockindex);\n\t// TODO: do the Wiznet chips automatically retransmit TCP ACK\n\t// packets if they are lost by the network? Someday this should\n\t// be checked by a man-in-the-middle test which discards certain\n\t// packets. If ACKs aren't resent, we would need to check for\n\t// returning 0 here and after a timeout do another Sock_RECV\n\t// command to cause the Wiznet chip to resend the ACK packet.\n}\n\nint EthernetClient::read(uint8_t *buf, size_t size)\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\treturn Ethernet.socketRecv(sockindex, buf, size);\n}\n\nint EthernetClient::peek()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return -1;\n\tif (!available()) return -1;\n\treturn Ethernet.socketPeek(sockindex);\n}\n\nint EthernetClient::read()\n{\n\tuint8_t b;\n\tif (Ethernet.socketRecv(sockindex, &b, 1) > 0) return b;\n\treturn -1;\n}\n\nvoid EthernetClient::flush()\n{\n\twhile (sockindex < MAX_SOCK_NUM) {\n\t\tuint8_t stat = Ethernet.socketStatus(sockindex);\n\t\tif (stat != SnSR::ESTABLISHED && stat != SnSR::CLOSE_WAIT) return;\n\t\tif (Ethernet.socketSendAvailable(sockindex) >= W5100.SSIZE) return;\n\t}\n}\n\nvoid EthernetClient::stop()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return;\n\n\t// attempt to close the connection gracefully (send a FIN to other side)\n\tEthernet.socketDisconnect(sockindex);\n\tunsigned long start = millis();\n\n\t// wait up to a second for the connection to close\n\tdo {\n\t\tif (Ethernet.socketStatus(sockindex) == SnSR::CLOSED) {\n\t\t\tsockindex = MAX_SOCK_NUM;\n\t\t\treturn; // exit the loop\n\t\t}\n\t\tdelay(1);\n\t} while (millis() - start < _timeout);\n\n\t// if it hasn't closed, close it forcefully\n\tEthernet.socketClose(sockindex);\n\tsockindex = MAX_SOCK_NUM;\n}\n\nuint8_t EthernetClient::connected()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\n\tuint8_t s = Ethernet.socketStatus(sockindex);\n\treturn !(s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::FIN_WAIT ||\n\t\t(s == SnSR::CLOSE_WAIT && !available()));\n}\n\nuint8_t EthernetClient::status()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return SnSR::CLOSED;\n\treturn Ethernet.socketStatus(sockindex);\n}\n\n// the next function allows us to use the client returned by\n// EthernetServer::available() as the condition in an if-statement.\nbool EthernetClient::operator==(const EthernetClient& rhs)\n{\n\tif (sockindex != rhs.sockindex) return false;\n\tif (sockindex >= MAX_SOCK_NUM) return false;\n\tif (rhs.sockindex >= MAX_SOCK_NUM) return false;\n\treturn true;\n}\n\n// https://github.com/per1234/EthernetMod\n// from: https://github.com/ntruchsess/Arduino-1/commit/937bce1a0bb2567f6d03b15df79525569377dabd\nuint16_t EthernetClient::localPort()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\tuint16_t port;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tport = W5100.readSnPORT(sockindex);\n\tSPI.endTransaction();\n\treturn port;\n}\n\n// https://github.com/per1234/EthernetMod\n// returns the remote IP address: http://forum.arduino.cc/index.php?topic=82416.0\nIPAddress EthernetClient::remoteIP()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return IPAddress((uint32_t)0);\n\tuint8_t remoteIParray[4];\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tW5100.readSnDIPR(sockindex, remoteIParray);\n\tSPI.endTransaction();\n\treturn IPAddress(remoteIParray);\n}\n\n// https://github.com/per1234/EthernetMod\n// from: https://github.com/ntruchsess/Arduino-1/commit/ca37de4ba4ecbdb941f14ac1fe7dd40f3008af75\nuint16_t EthernetClient::remotePort()\n{\n\tif (sockindex >= MAX_SOCK_NUM) return 0;\n\tuint16_t port;\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\tport = W5100.readSnDPORT(sockindex);\n\tSPI.endTransaction();\n\treturn port;\n}\n\n\n" }, { "name": "src/EthernetClient.h", "url": "src/EthernetClient.h", "fileData": "// This file is in the public domain. No copyright is claimed.\n\n#include \"Ethernet.h\"\n" }, { "name": "src/EthernetServer.cpp", "url": "src/EthernetServer.cpp", "fileData": "/* Copyright 2018 Paul Stoffregen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this\n * software and associated documentation files (the \"Software\"), to deal in the Software\n * without restriction, including without limitation the rights to use, copy, modify,\n * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \n#include \"Ethernet.h\"\n#include \"w5100.h\"\n\nuint16_t EthernetServer::server_port[MAX_SOCK_NUM];\n\n\nvoid EthernetServer::begin()\n{\n\tuint8_t sockindex = Ethernet.socketBegin(SnMR::TCP, _port);\n\tif (sockindex < MAX_SOCK_NUM) {\n\t\tif (Ethernet.socketListen(sockindex)) {\n\t\t\tserver_port[sockindex] = _port;\n\t\t} else {\n\t\t\tEthernet.socketDisconnect(sockindex);\n\t\t}\n\t}\n}\n\nEthernetClient EthernetServer::available()\n{\n\tbool listening = false;\n\tuint8_t sockindex = MAX_SOCK_NUM;\n\tuint8_t chip, maxindex=MAX_SOCK_NUM;\n\n\tchip = W5100.getChip();\n\tif (!chip) return EthernetClient(MAX_SOCK_NUM);\n#if MAX_SOCK_NUM > 4\n\tif (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets\n#endif\n\tfor (uint8_t i=0; i < maxindex; i++) {\n\t\tif (server_port[i] == _port) {\n\t\t\tuint8_t stat = Ethernet.socketStatus(i);\n\t\t\tif (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT) {\n\t\t\t\tif (Ethernet.socketRecvAvailable(i) > 0) {\n\t\t\t\t\tsockindex = i;\n\t\t\t\t} else {\n\t\t\t\t\t// remote host closed connection, our end still open\n\t\t\t\t\tif (stat == SnSR::CLOSE_WAIT) {\n\t\t\t\t\t\tEthernet.socketDisconnect(i);\n\t\t\t\t\t\t// status becomes LAST_ACK for short time\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (stat == SnSR::LISTEN) {\n\t\t\t\tlistening = true;\n\t\t\t} else if (stat == SnSR::CLOSED) {\n\t\t\t\tserver_port[i] = 0;\n\t\t\t}\n\t\t}\n\t}\n\tif (!listening) begin();\n\treturn EthernetClient(sockindex);\n}\n\nEthernetClient EthernetServer::accept()\n{\n\tbool listening = false;\n\tuint8_t sockindex = MAX_SOCK_NUM;\n\tuint8_t chip, maxindex=MAX_SOCK_NUM;\n\n\tchip = W5100.getChip();\n\tif (!chip) return EthernetClient(MAX_SOCK_NUM);\n#if MAX_SOCK_NUM > 4\n\tif (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets\n#endif\n\tfor (uint8_t i=0; i < maxindex; i++) {\n\t\tif (server_port[i] == _port) {\n\t\t\tuint8_t stat = Ethernet.socketStatus(i);\n\t\t\tif (sockindex == MAX_SOCK_NUM &&\n\t\t\t (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT)) {\n\t\t\t\t// Return the connected client even if no data received.\n\t\t\t\t// Some protocols like FTP expect the server to send the\n\t\t\t\t// first data.\n\t\t\t\tsockindex = i;\n\t\t\t\tserver_port[i] = 0; // only return the client once\n\t\t\t} else if (stat == SnSR::LISTEN) {\n\t\t\t\tlistening = true;\n\t\t\t} else if (stat == SnSR::CLOSED) {\n\t\t\t\tserver_port[i] = 0;\n\t\t\t}\n\t\t}\n\t}\n\tif (!listening) begin();\n\treturn EthernetClient(sockindex);\n}\n\nEthernetServer::operator bool()\n{\n\tuint8_t maxindex=MAX_SOCK_NUM;\n#if MAX_SOCK_NUM > 4\n\tif (W5100.getChip() == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets\n#endif\n\tfor (uint8_t i=0; i < maxindex; i++) {\n\t\tif (server_port[i] == _port) {\n\t\t\tif (Ethernet.socketStatus(i) == SnSR::LISTEN) {\n\t\t\t\treturn true; // server is listening for incoming clients\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n\n#if 0\nvoid EthernetServer::statusreport()\n{\n\tSerial.printf(\"EthernetServer, port=%d\\n\", _port);\n\tfor (uint8_t i=0; i < MAX_SOCK_NUM; i++) {\n\t\tuint16_t port = server_port[i];\n\t\tuint8_t stat = Ethernet.socketStatus(i);\n\t\tconst char *name;\n\t\tswitch (stat) {\n\t\t\tcase 0x00: name = \"CLOSED\"; break;\n\t\t\tcase 0x13: name = \"INIT\"; break;\n\t\t\tcase 0x14: name = \"LISTEN\"; break;\n\t\t\tcase 0x15: name = \"SYNSENT\"; break;\n\t\t\tcase 0x16: name = \"SYNRECV\"; break;\n\t\t\tcase 0x17: name = \"ESTABLISHED\"; break;\n\t\t\tcase 0x18: name = \"FIN_WAIT\"; break;\n\t\t\tcase 0x1A: name = \"CLOSING\"; break;\n\t\t\tcase 0x1B: name = \"TIME_WAIT\"; break;\n\t\t\tcase 0x1C: name = \"CLOSE_WAIT\"; break;\n\t\t\tcase 0x1D: name = \"LAST_ACK\"; break;\n\t\t\tcase 0x22: name = \"UDP\"; break;\n\t\t\tcase 0x32: name = \"IPRAW\"; break;\n\t\t\tcase 0x42: name = \"MACRAW\"; break;\n\t\t\tcase 0x5F: name = \"PPPOE\"; break;\n\t\t\tdefault: name = \"???\";\n\t\t}\n\t\tint avail = Ethernet.socketRecvAvailable(i);\n\t\tSerial.printf(\" %d: port=%d, status=%s (0x%02X), avail=%d\\n\",\n\t\t\ti, port, name, stat, avail);\n\t}\n}\n#endif\n\nsize_t EthernetServer::write(uint8_t b)\n{\n\treturn write(&b, 1);\n}\n\nsize_t EthernetServer::write(const uint8_t *buffer, size_t size)\n{\n\tuint8_t chip, maxindex=MAX_SOCK_NUM;\n\n\tchip = W5100.getChip();\n\tif (!chip) return 0;\n#if MAX_SOCK_NUM > 4\n\tif (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets\n#endif\n\tavailable();\n\tfor (uint8_t i=0; i < maxindex; i++) {\n\t\tif (server_port[i] == _port) {\n\t\t\tif (Ethernet.socketStatus(i) == SnSR::ESTABLISHED) {\n\t\t\t\tEthernet.socketSend(i, buffer, size);\n\t\t\t}\n\t\t}\n\t}\n\treturn size;\n}\n" }, { "name": "src/EthernetServer.h", "url": "src/EthernetServer.h", "fileData": "// This file is in the public domain. No copyright is claimed.\n\n#include \"Ethernet.h\"\n" }, { "name": "src/SPI.cpp", "url": "src/SPI.cpp", "fileData": "/*\n * Copyright (c) 2010 by Cristian Maglie \n * Copyright (c) 2014 by Paul Stoffregen (Transaction API)\n * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR)\n * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes)\n * SPI Master library for arduino.\n *\n * This file is free software; you can redistribute it and/or modify\n * it under the terms of either the GNU General Public License version 2\n * or the GNU Lesser General Public License version 2.1, both as\n * published by the Free Software Foundation.\n */\n\n#include \"SPI.h\"\n\nSPIClass SPI;\n\nuint8_t SPIClass::initialized = 0;\nuint8_t SPIClass::interruptMode = 0;\nuint8_t SPIClass::interruptMask = 0;\nuint8_t SPIClass::interruptSave = 0;\n#ifdef SPI_TRANSACTION_MISMATCH_LED\nuint8_t SPIClass::inTransactionFlag = 0;\n#endif\n\nvoid SPIClass::begin()\n{\n uint8_t sreg = SREG;\n noInterrupts(); // Protect from a scheduler and prevent transactionBegin\n if (!initialized) {\n // Set SS to high so a connected chip will be \"deselected\" by default\n uint8_t port = digitalPinToPort(SS);\n uint8_t bit = digitalPinToBitMask(SS);\n volatile uint8_t *reg = portModeRegister(port);\n\n // if the SS pin is not already configured as an output\n // then set it high (to enable the internal pull-up resistor)\n if(!(*reg & bit)){\n digitalWrite(SS, HIGH);\n }\n\n // When the SS pin is set as OUTPUT, it can be used as\n // a general purpose output port (it doesn't influence\n // SPI operations).\n pinMode(SS, OUTPUT);\n\n // Warning: if the SS pin ever becomes a LOW INPUT then SPI\n // automatically switches to Slave, so the data direction of\n // the SS pin MUST be kept as OUTPUT.\n SPCR |= _BV(MSTR);\n SPCR |= _BV(SPE);\n\n // Set direction register for SCK and MOSI pin.\n // MISO pin automatically overrides to INPUT.\n // By doing this AFTER enabling SPI, we avoid accidentally\n // clocking in a single bit since the lines go directly\n // from \"input\" to SPI control.\n // http://code.google.com/p/arduino/issues/detail?id=888\n pinMode(SCK, OUTPUT);\n pinMode(MOSI, OUTPUT);\n }\n initialized++; // reference count\n SREG = sreg;\n}\n\nvoid SPIClass::end() {\n uint8_t sreg = SREG;\n noInterrupts(); // Protect from a scheduler and prevent transactionBegin\n // Decrease the reference counter\n if (initialized)\n initialized--;\n // If there are no more references disable SPI\n if (!initialized) {\n SPCR &= ~_BV(SPE);\n interruptMode = 0;\n #ifdef SPI_TRANSACTION_MISMATCH_LED\n inTransactionFlag = 0;\n #endif\n }\n SREG = sreg;\n}\n\n// mapping of interrupt numbers to bits within SPI_AVR_EIMSK\n#if defined(__AVR_ATmega32U4__)\n #define SPI_INT0_MASK (1<\n * Copyright (c) 2014 by Paul Stoffregen (Transaction API)\n * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR)\n * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes)\n * SPI Master library for arduino.\n *\n * This file is free software; you can redistribute it and/or modify\n * it under the terms of either the GNU General Public License version 2\n * or the GNU Lesser General Public License version 2.1, both as\n * published by the Free Software Foundation.\n */\n\n#ifndef _SPI_H_INCLUDED\n#define _SPI_H_INCLUDED\n\n#include \n\n// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),\n// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)\n#define SPI_HAS_TRANSACTION 1\n\n// SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method\n#define SPI_HAS_NOTUSINGINTERRUPT 1\n\n// SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version.\n// This way when there is a bug fix you can check this define to alert users\n// of your code if it uses better version of this library.\n// This also implies everything that SPI_HAS_TRANSACTION as documented above is\n// available too.\n#define SPI_ATOMIC_VERSION 1\n\n// Uncomment this line to add detection of mismatched begin/end transactions.\n// A mismatch occurs if other libraries fail to use SPI.endTransaction() for\n// each SPI.beginTransaction(). Connect an LED to this pin. The LED will turn\n// on if any mismatch is ever detected.\n//#define SPI_TRANSACTION_MISMATCH_LED 5\n\n#ifndef LSBFIRST\n#define LSBFIRST 0\n#endif\n#ifndef MSBFIRST\n#define MSBFIRST 1\n#endif\n\n#define SPI_CLOCK_DIV4 0x00\n#define SPI_CLOCK_DIV16 0x01\n#define SPI_CLOCK_DIV64 0x02\n#define SPI_CLOCK_DIV128 0x03\n#define SPI_CLOCK_DIV2 0x04\n#define SPI_CLOCK_DIV8 0x05\n#define SPI_CLOCK_DIV32 0x06\n\n#define SPI_MODE0 0x00\n#define SPI_MODE1 0x04\n#define SPI_MODE2 0x08\n#define SPI_MODE3 0x0C\n\n#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR\n#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR\n#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR\n\n// define SPI_AVR_EIMSK for AVR boards with external interrupt pins\n#if defined(EIMSK)\n #define SPI_AVR_EIMSK EIMSK\n#elif defined(GICR)\n #define SPI_AVR_EIMSK GICR\n#elif defined(GIMSK)\n #define SPI_AVR_EIMSK GIMSK\n#endif\n\nclass SPISettings {\npublic:\n SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {\n if (__builtin_constant_p(clock)) {\n init_AlwaysInline(clock, bitOrder, dataMode);\n } else {\n init_MightInline(clock, bitOrder, dataMode);\n }\n }\n SPISettings() {\n init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);\n }\nprivate:\n void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {\n init_AlwaysInline(clock, bitOrder, dataMode);\n }\n void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)\n __attribute__((__always_inline__)) {\n // Clock settings are defined as follows. Note that this shows SPI2X\n // inverted, so the bits form increasing numbers. Also note that\n // fosc/64 appears twice\n // SPR1 SPR0 ~SPI2X Freq\n // 0 0 0 fosc/2\n // 0 0 1 fosc/4\n // 0 1 0 fosc/8\n // 0 1 1 fosc/16\n // 1 0 0 fosc/32\n // 1 0 1 fosc/64\n // 1 1 0 fosc/64\n // 1 1 1 fosc/128\n\n // We find the fastest clock that is less than or equal to the\n // given clock rate. The clock divider that results in clock_setting\n // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the\n // slowest (128 == 2 ^^ 7, so clock_div = 6).\n uint8_t clockDiv;\n\n // When the clock is known at compile time, use this if-then-else\n // cascade, which the compiler knows how to completely optimize\n // away. When clock is not known, use a loop instead, which generates\n // shorter code.\n if (__builtin_constant_p(clock)) {\n if (clock >= F_CPU / 2) {\n clockDiv = 0;\n } else if (clock >= F_CPU / 4) {\n clockDiv = 1;\n } else if (clock >= F_CPU / 8) {\n clockDiv = 2;\n } else if (clock >= F_CPU / 16) {\n clockDiv = 3;\n } else if (clock >= F_CPU / 32) {\n clockDiv = 4;\n } else if (clock >= F_CPU / 64) {\n clockDiv = 5;\n } else {\n clockDiv = 6;\n }\n } else {\n uint32_t clockSetting = F_CPU / 2;\n clockDiv = 0;\n while (clockDiv < 6 && clock < clockSetting) {\n clockSetting /= 2;\n clockDiv++;\n }\n }\n\n // Compensate for the duplicate fosc/64\n if (clockDiv == 6)\n clockDiv = 7;\n\n // Invert the SPI2X bit\n clockDiv ^= 0x1;\n\n // Pack into the SPISettings class\n spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) |\n (dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK);\n spsr = clockDiv & SPI_2XCLOCK_MASK;\n }\n uint8_t spcr;\n uint8_t spsr;\n friend class SPIClass;\n};\n\n\nclass SPIClass {\npublic:\n // Initialize the SPI library\n static void begin();\n\n // If SPI is used from within an interrupt, this function registers\n // that interrupt with the SPI library, so beginTransaction() can\n // prevent conflicts. The input interruptNumber is the number used\n // with attachInterrupt. If SPI is used from a different interrupt\n // (eg, a timer), interruptNumber should be 255.\n static void usingInterrupt(uint8_t interruptNumber);\n // And this does the opposite.\n static void notUsingInterrupt(uint8_t interruptNumber);\n // Note: the usingInterrupt and notUsingInterrupt functions should\n // not to be called from ISR context or inside a transaction.\n // For details see:\n // https://github.com/arduino/Arduino/pull/2381\n // https://github.com/arduino/Arduino/pull/2449\n\n // Before using SPI.transfer() or asserting chip select pins,\n // this function is used to gain exclusive access to the SPI bus\n // and configure the correct settings.\n inline static void beginTransaction(SPISettings settings) {\n if (interruptMode > 0) {\n uint8_t sreg = SREG;\n noInterrupts();\n\n #ifdef SPI_AVR_EIMSK\n if (interruptMode == 1) {\n interruptSave = SPI_AVR_EIMSK;\n SPI_AVR_EIMSK &= ~interruptMask;\n SREG = sreg;\n } else\n #endif\n {\n interruptSave = sreg;\n }\n }\n\n #ifdef SPI_TRANSACTION_MISMATCH_LED\n if (inTransactionFlag) {\n pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);\n digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);\n }\n inTransactionFlag = 1;\n #endif\n\n SPCR = settings.spcr;\n SPSR = settings.spsr;\n }\n\n // Write to the SPI bus (MOSI pin) and also receive (MISO pin)\n inline static uint8_t transfer(uint8_t data) {\n SPDR = data;\n /*\n * The following NOP introduces a small delay that can prevent the wait\n * loop form iterating when running at the maximum speed. This gives\n * about 10% more speed, even if it seems counter-intuitive. At lower\n * speeds it is unnoticed.\n */\n asm volatile(\"nop\");\n while (!(SPSR & _BV(SPIF))) ; // wait\n return SPDR;\n }\n inline static uint16_t transfer16(uint16_t data) {\n union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;\n in.val = data;\n if (!(SPCR & _BV(DORD))) {\n SPDR = in.msb;\n asm volatile(\"nop\"); // See transfer(uint8_t) function\n while (!(SPSR & _BV(SPIF))) ;\n out.msb = SPDR;\n SPDR = in.lsb;\n asm volatile(\"nop\");\n while (!(SPSR & _BV(SPIF))) ;\n out.lsb = SPDR;\n } else {\n SPDR = in.lsb;\n asm volatile(\"nop\");\n while (!(SPSR & _BV(SPIF))) ;\n out.lsb = SPDR;\n SPDR = in.msb;\n asm volatile(\"nop\");\n while (!(SPSR & _BV(SPIF))) ;\n out.msb = SPDR;\n }\n return out.val;\n }\n inline static void transfer(void *buf, size_t count) {\n if (count == 0) return;\n uint8_t *p = (uint8_t *)buf;\n SPDR = *p;\n while (--count > 0) {\n uint8_t out = *(p + 1);\n while (!(SPSR & _BV(SPIF))) ;\n uint8_t in = SPDR;\n SPDR = out;\n *p++ = in;\n }\n while (!(SPSR & _BV(SPIF))) ;\n *p = SPDR;\n }\n // After performing a group of transfers and releasing the chip select\n // signal, this function allows others to access the SPI bus\n inline static void endTransaction(void) {\n #ifdef SPI_TRANSACTION_MISMATCH_LED\n if (!inTransactionFlag) {\n pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);\n digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);\n }\n inTransactionFlag = 0;\n #endif\n\n if (interruptMode > 0) {\n #ifdef SPI_AVR_EIMSK\n uint8_t sreg = SREG;\n #endif\n noInterrupts();\n #ifdef SPI_AVR_EIMSK\n if (interruptMode == 1) {\n SPI_AVR_EIMSK = interruptSave;\n SREG = sreg;\n } else\n #endif\n {\n SREG = interruptSave;\n }\n }\n }\n\n // Disable the SPI bus\n static void end();\n\n // This function is deprecated. New applications should use\n // beginTransaction() to configure SPI settings.\n inline static void setBitOrder(uint8_t bitOrder) {\n if (bitOrder == LSBFIRST) SPCR |= _BV(DORD);\n else SPCR &= ~(_BV(DORD));\n }\n // This function is deprecated. New applications should use\n // beginTransaction() to configure SPI settings.\n inline static void setDataMode(uint8_t dataMode) {\n SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;\n }\n // This function is deprecated. New applications should use\n // beginTransaction() to configure SPI settings.\n inline static void setClockDivider(uint8_t clockDiv) {\n SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK);\n SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK);\n }\n // These undocumented functions should not be used. SPI.transfer()\n // polls the hardware flag which is automatically cleared as the\n // AVR responds to SPI's interrupt\n inline static void attachInterrupt() { SPCR |= _BV(SPIE); }\n inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); }\n\nprivate:\n static uint8_t initialized;\n static uint8_t interruptMode; // 0=none, 1=mask, 2=global\n static uint8_t interruptMask; // which interrupts to mask\n static uint8_t interruptSave; // temp storage, to restore state\n #ifdef SPI_TRANSACTION_MISMATCH_LED\n static uint8_t inTransactionFlag;\n #endif\n};\n\nextern SPIClass SPI;\n\n#endif\n" }, { "name": "src/w5100.cpp", "url": "src/w5100.cpp", "fileData": "/*\n * Copyright 2018 Paul Stoffregen\n * Copyright (c) 2010 by Cristian Maglie \n *\n * This file is free software; you can redistribute it and/or modify\n * it under the terms of either the GNU General Public License version 2\n * or the GNU Lesser General Public License version 2.1, both as\n * published by the Free Software Foundation.\n */\n\n#include \n#include \"Ethernet.h\"\n#include \"w5100.h\"\n\n\n/***************************************************/\n/** Default SS pin setting **/\n/***************************************************/\n\n// If variant.h or other headers specifically define the\n// default SS pin for ethernet, use it.\n#if defined(PIN_SPI_SS_ETHERNET_LIB)\n#define SS_PIN_DEFAULT PIN_SPI_SS_ETHERNET_LIB\n\n// MKR boards default to pin 5 for MKR ETH\n// Pins 8-10 are MOSI/SCK/MISO on MRK, so don't use pin 10\n#elif defined(USE_ARDUINO_MKR_PIN_LAYOUT) || defined(ARDUINO_SAMD_MKRZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWAN1300)\n#define SS_PIN_DEFAULT 5\n\n// For boards using AVR, assume shields with SS on pin 10\n// will be used. This allows for Arduino Mega (where\n// SS is pin 53) and Arduino Leonardo (where SS is pin 17)\n// to work by default with Arduino Ethernet Shield R2 & R3.\n#elif defined(__AVR__)\n#define SS_PIN_DEFAULT 10\n\n// If variant.h or other headers define these names\n// use them if none of the other cases match\n#elif defined(PIN_SPI_SS)\n#define SS_PIN_DEFAULT PIN_SPI_SS\n#elif defined(CORE_SS0_PIN)\n#define SS_PIN_DEFAULT CORE_SS0_PIN\n\n// As a final fallback, use pin 10\n#else\n#define SS_PIN_DEFAULT 10\n#endif\n\n\n\n\n// W5100 controller instance\nuint8_t W5100Class::chip = 0;\nuint8_t W5100Class::CH_BASE_MSB;\nuint8_t W5100Class::ss_pin = SS_PIN_DEFAULT;\n#ifdef ETHERNET_LARGE_BUFFERS\nuint16_t W5100Class::SSIZE = 2048;\nuint16_t W5100Class::SMASK = 0x07FF;\n#endif\nW5100Class W5100;\n\n// pointers and bitmasks for optimized SS pin\n#if defined(__AVR__)\n volatile uint8_t * W5100Class::ss_pin_reg;\n uint8_t W5100Class::ss_pin_mask;\n#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)\n volatile uint8_t * W5100Class::ss_pin_reg;\n#elif defined(__MKL26Z64__)\n volatile uint8_t * W5100Class::ss_pin_reg;\n uint8_t W5100Class::ss_pin_mask;\n#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)\n volatile uint32_t * W5100Class::ss_pin_reg;\n uint32_t W5100Class::ss_pin_mask;\n#elif defined(__PIC32MX__)\n volatile uint32_t * W5100Class::ss_pin_reg;\n uint32_t W5100Class::ss_pin_mask;\n#elif defined(ARDUINO_ARCH_ESP8266)\n volatile uint32_t * W5100Class::ss_pin_reg;\n uint32_t W5100Class::ss_pin_mask;\n#elif defined(__SAMD21G18A__)\n volatile uint32_t * W5100Class::ss_pin_reg;\n uint32_t W5100Class::ss_pin_mask;\n#endif\n\n\nuint8_t W5100Class::init(void)\n{\n\tstatic bool initialized = false;\n\tuint8_t i;\n\n\tif (initialized) return 1;\n\n\t// Many Ethernet shields have a CAT811 or similar reset chip\n\t// connected to W5100 or W5200 chips. The W5200 will not work at\n\t// all, and may even drive its MISO pin, until given an active low\n\t// reset pulse! The CAT811 has a 240 ms typical pulse length, and\n\t// a 400 ms worst case maximum pulse length. MAX811 has a worst\n\t// case maximum 560 ms pulse length. This delay is meant to wait\n\t// until the reset pulse is ended. If your hardware has a shorter\n\t// reset time, this can be edited or removed.\n\tdelay(560);\n\t//Serial.println(\"w5100 init\");\n\n\tSPI.begin();\n\tinitSS();\n\tresetSS();\n\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\n\t// Attempt W5200 detection first, because W5200 does not properly\n\t// reset its SPI state when CS goes high (inactive). Communication\n\t// from detecting the other chips can leave the W5200 in a state\n\t// where it won't recover, unless given a reset pulse.\n\tif (isW5200()) {\n\t\tCH_BASE_MSB = 0x40;\n#ifdef ETHERNET_LARGE_BUFFERS\n#if MAX_SOCK_NUM <= 1\n\t\tSSIZE = 16384;\n#elif MAX_SOCK_NUM <= 2\n\t\tSSIZE = 8192;\n#elif MAX_SOCK_NUM <= 4\n\t\tSSIZE = 4096;\n#else\n\t\tSSIZE = 2048;\n#endif\n\t\tSMASK = SSIZE - 1;\n#endif\n\t\tfor (i=0; i> 10);\n\t\t\twriteSnTX_SIZE(i, SSIZE >> 10);\n\t\t}\n\t\tfor (; i<8; i++) {\n\t\t\twriteSnRX_SIZE(i, 0);\n\t\t\twriteSnTX_SIZE(i, 0);\n\t\t}\n\t// Try W5500 next. Wiznet finally seems to have implemented\n\t// SPI well with this chip. It appears to be very resilient,\n\t// so try it after the fragile W5200\n\t} else if (isW5500()) {\n\t\tCH_BASE_MSB = 0x10;\n#ifdef ETHERNET_LARGE_BUFFERS\n#if MAX_SOCK_NUM <= 1\n\t\tSSIZE = 16384;\n#elif MAX_SOCK_NUM <= 2\n\t\tSSIZE = 8192;\n#elif MAX_SOCK_NUM <= 4\n\t\tSSIZE = 4096;\n#else\n\t\tSSIZE = 2048;\n#endif\n\t\tSMASK = SSIZE - 1;\n\t\tfor (i=0; i> 10);\n\t\t\twriteSnTX_SIZE(i, SSIZE >> 10);\n\t\t}\n\t\tfor (; i<8; i++) {\n\t\t\twriteSnRX_SIZE(i, 0);\n\t\t\twriteSnTX_SIZE(i, 0);\n\t\t}\n#endif\n\t// Try W5100 last. This simple chip uses fixed 4 byte frames\n\t// for every 8 bit access. Terribly inefficient, but so simple\n\t// it recovers from \"hearing\" unsuccessful W5100 or W5200\n\t// communication. W5100 is also the only chip without a VERSIONR\n\t// register for identification, so we check this last.\n\t} else if (isW5100()) {\n\t\tCH_BASE_MSB = 0x04;\n#ifdef ETHERNET_LARGE_BUFFERS\n#if MAX_SOCK_NUM <= 1\n\t\tSSIZE = 8192;\n\t\twriteTMSR(0x03);\n\t\twriteRMSR(0x03);\n#elif MAX_SOCK_NUM <= 2\n\t\tSSIZE = 4096;\n\t\twriteTMSR(0x0A);\n\t\twriteRMSR(0x0A);\n#else\n\t\tSSIZE = 2048;\n\t\twriteTMSR(0x55);\n\t\twriteRMSR(0x55);\n#endif\n\t\tSMASK = SSIZE - 1;\n#else\n\t\twriteTMSR(0x55);\n\t\twriteRMSR(0x55);\n#endif\n\t// No hardware seems to be present. Or it could be a W5200\n\t// that's heard other SPI communication if its chip select\n\t// pin wasn't high when a SD card or other SPI chip was used.\n\t} else {\n\t\t//Serial.println(\"no chip :-(\");\n\t\tchip = 0;\n\t\tSPI.endTransaction();\n\t\treturn 0; // no known chip is responding :-(\n\t}\n\tSPI.endTransaction();\n\tinitialized = true;\n\treturn 1; // successful init\n}\n\n// Soft reset the Wiznet chip, by writing to its MR register reset bit\nuint8_t W5100Class::softReset(void)\n{\n\tuint16_t count=0;\n\n\t//Serial.println(\"Wiznet soft reset\");\n\t// write to reset bit\n\twriteMR(0x80);\n\t// then wait for soft reset to complete\n\tdo {\n\t\tuint8_t mr = readMR();\n\t\t//Serial.print(\"mr=\");\n\t\t//Serial.println(mr, HEX);\n\t\tif (mr == 0) return 1;\n\t\tdelay(1);\n\t} while (++count < 20);\n\treturn 0;\n}\n\nuint8_t W5100Class::isW5100(void)\n{\n\tchip = 51;\n\t//Serial.println(\"w5100.cpp: detect W5100 chip\");\n\tif (!softReset()) return 0;\n\twriteMR(0x10);\n\tif (readMR() != 0x10) return 0;\n\twriteMR(0x12);\n\tif (readMR() != 0x12) return 0;\n\twriteMR(0x00);\n\tif (readMR() != 0x00) return 0;\n\t//Serial.println(\"chip is W5100\");\n\treturn 1;\n}\n\nuint8_t W5100Class::isW5200(void)\n{\n\tchip = 52;\n\t//Serial.println(\"w5100.cpp: detect W5200 chip\");\n\tif (!softReset()) return 0;\n\twriteMR(0x08);\n\tif (readMR() != 0x08) return 0;\n\twriteMR(0x10);\n\tif (readMR() != 0x10) return 0;\n\twriteMR(0x00);\n\tif (readMR() != 0x00) return 0;\n\tint ver = readVERSIONR_W5200();\n\t//Serial.print(\"version=\");\n\t//Serial.println(ver);\n\tif (ver != 3) return 0;\n\t//Serial.println(\"chip is W5200\");\n\treturn 1;\n}\n\nuint8_t W5100Class::isW5500(void)\n{\n\tchip = 55;\n\t//Serial.println(\"w5100.cpp: detect W5500 chip\");\n\tif (!softReset()) return 0;\n\twriteMR(0x08);\n\tif (readMR() != 0x08) return 0;\n\twriteMR(0x10);\n\tif (readMR() != 0x10) return 0;\n\twriteMR(0x00);\n\tif (readMR() != 0x00) return 0;\n\tint ver = readVERSIONR_W5500();\n\t//Serial.print(\"version=\");\n\t//Serial.println(ver);\n\tif (ver != 4) return 0;\n\t//Serial.println(\"chip is W5500\");\n\treturn 1;\n}\n\nW5100Linkstatus W5100Class::getLinkStatus()\n{\n\tuint8_t phystatus;\n\n\tif (!init()) return UNKNOWN;\n\tswitch (chip) {\n\t case 52:\n\t\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\t\tphystatus = readPSTATUS_W5200();\n\t\tSPI.endTransaction();\n\t\tif (phystatus & 0x20) return LINK_ON;\n\t\treturn LINK_OFF;\n\t case 55:\n\t\tSPI.beginTransaction(SPI_ETHERNET_SETTINGS);\n\t\tphystatus = readPHYCFGR_W5500();\n\t\tSPI.endTransaction();\n\t\tif (phystatus & 0x01) return LINK_ON;\n\t\treturn LINK_OFF;\n\t default:\n\t\treturn UNKNOWN;\n\t}\n}\n\nuint16_t W5100Class::write(uint16_t addr, const uint8_t *buf, uint16_t len)\n{\n\tuint8_t cmd[8];\n\n\tif (chip == 51) {\n\t\tfor (uint16_t i=0; i> 8);\n\t\t\tSPI.transfer(addr & 0xFF);\n\t\t\taddr++;\n\t\t\tSPI.transfer(buf[i]);\n\t\t\tresetSS();\n\t\t}\n\t} else if (chip == 52) {\n\t\tsetSS();\n\t\tcmd[0] = addr >> 8;\n\t\tcmd[1] = addr & 0xFF;\n\t\tcmd[2] = ((len >> 8) & 0x7F) | 0x80;\n\t\tcmd[3] = len & 0xFF;\n\t\tSPI.transfer(cmd, 4);\n#ifdef SPI_HAS_TRANSFER_BUF\n\t\tSPI.transfer(buf, NULL, len);\n#else\n\t\t// TODO: copy 8 bytes at a time to cmd[] and block transfer\n\t\tfor (uint16_t i=0; i < len; i++) {\n\t\t\tSPI.transfer(buf[i]);\n\t\t}\n#endif\n\t\tresetSS();\n\t} else { // chip == 55\n\t\tsetSS();\n\t\tif (addr < 0x100) {\n\t\t\t// common registers 00nn\n\t\t\tcmd[0] = 0;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\tcmd[2] = 0x04;\n\t\t} else if (addr < 0x8000) {\n\t\t\t// socket registers 10nn, 11nn, 12nn, 13nn, etc\n\t\t\tcmd[0] = 0;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\tcmd[2] = ((addr >> 3) & 0xE0) | 0x0C;\n\t\t} else if (addr < 0xC000) {\n\t\t\t// transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc\n\t\t\t// 10## #nnn nnnn nnnn\n\t\t\tcmd[0] = addr >> 8;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\t#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1\n\t\t\tcmd[2] = 0x14; // 16K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2\n\t\t\tcmd[2] = ((addr >> 8) & 0x20) | 0x14; // 8K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4\n\t\t\tcmd[2] = ((addr >> 7) & 0x60) | 0x14; // 4K buffers\n\t\t\t#else\n\t\t\tcmd[2] = ((addr >> 6) & 0xE0) | 0x14; // 2K buffers\n\t\t\t#endif\n\t\t} else {\n\t\t\t// receive buffers\n\t\t\tcmd[0] = addr >> 8;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\t#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1\n\t\t\tcmd[2] = 0x1C; // 16K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2\n\t\t\tcmd[2] = ((addr >> 8) & 0x20) | 0x1C; // 8K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4\n\t\t\tcmd[2] = ((addr >> 7) & 0x60) | 0x1C; // 4K buffers\n\t\t\t#else\n\t\t\tcmd[2] = ((addr >> 6) & 0xE0) | 0x1C; // 2K buffers\n\t\t\t#endif\n\t\t}\n\t\tif (len <= 5) {\n\t\t\tfor (uint8_t i=0; i < len; i++) {\n\t\t\t\tcmd[i + 3] = buf[i];\n\t\t\t}\n\t\t\tSPI.transfer(cmd, len + 3);\n\t\t} else {\n\t\t\tSPI.transfer(cmd, 3);\n#ifdef SPI_HAS_TRANSFER_BUF\n\t\t\tSPI.transfer(buf, NULL, len);\n#else\n\t\t\t// TODO: copy 8 bytes at a time to cmd[] and block transfer\n\t\t\tfor (uint16_t i=0; i < len; i++) {\n\t\t\t\tSPI.transfer(buf[i]);\n\t\t\t}\n#endif\n\t\t}\n\t\tresetSS();\n\t}\n\treturn len;\n}\n\nuint16_t W5100Class::read(uint16_t addr, uint8_t *buf, uint16_t len)\n{\n\tuint8_t cmd[4];\n\n\tif (chip == 51) {\n\t\tfor (uint16_t i=0; i < len; i++) {\n\t\t\tsetSS();\n\t\t\t#if 1\n\t\t\tSPI.transfer(0x0F);\n\t\t\tSPI.transfer(addr >> 8);\n\t\t\tSPI.transfer(addr & 0xFF);\n\t\t\taddr++;\n\t\t\tbuf[i] = SPI.transfer(0);\n\t\t\t#else\n\t\t\tcmd[0] = 0x0F;\n\t\t\tcmd[1] = addr >> 8;\n\t\t\tcmd[2] = addr & 0xFF;\n\t\t\tcmd[3] = 0;\n\t\t\tSPI.transfer(cmd, 4); // TODO: why doesn't this work?\n\t\t\tbuf[i] = cmd[3];\n\t\t\taddr++;\n\t\t\t#endif\n\t\t\tresetSS();\n\t\t}\n\t} else if (chip == 52) {\n\t\tsetSS();\n\t\tcmd[0] = addr >> 8;\n\t\tcmd[1] = addr & 0xFF;\n\t\tcmd[2] = (len >> 8) & 0x7F;\n\t\tcmd[3] = len & 0xFF;\n\t\tSPI.transfer(cmd, 4);\n\t\tmemset(buf, 0, len);\n\t\tSPI.transfer(buf, len);\n\t\tresetSS();\n\t} else { // chip == 55\n\t\tsetSS();\n\t\tif (addr < 0x100) {\n\t\t\t// common registers 00nn\n\t\t\tcmd[0] = 0;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\tcmd[2] = 0x00;\n\t\t} else if (addr < 0x8000) {\n\t\t\t// socket registers 10nn, 11nn, 12nn, 13nn, etc\n\t\t\tcmd[0] = 0;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\tcmd[2] = ((addr >> 3) & 0xE0) | 0x08;\n\t\t} else if (addr < 0xC000) {\n\t\t\t// transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc\n\t\t\t// 10## #nnn nnnn nnnn\n\t\t\tcmd[0] = addr >> 8;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\t#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1\n\t\t\tcmd[2] = 0x10; // 16K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2\n\t\t\tcmd[2] = ((addr >> 8) & 0x20) | 0x10; // 8K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4\n\t\t\tcmd[2] = ((addr >> 7) & 0x60) | 0x10; // 4K buffers\n\t\t\t#else\n\t\t\tcmd[2] = ((addr >> 6) & 0xE0) | 0x10; // 2K buffers\n\t\t\t#endif\n\t\t} else {\n\t\t\t// receive buffers\n\t\t\tcmd[0] = addr >> 8;\n\t\t\tcmd[1] = addr & 0xFF;\n\t\t\t#if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1\n\t\t\tcmd[2] = 0x18; // 16K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2\n\t\t\tcmd[2] = ((addr >> 8) & 0x20) | 0x18; // 8K buffers\n\t\t\t#elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4\n\t\t\tcmd[2] = ((addr >> 7) & 0x60) | 0x18; // 4K buffers\n\t\t\t#else\n\t\t\tcmd[2] = ((addr >> 6) & 0xE0) | 0x18; // 2K buffers\n\t\t\t#endif\n\t\t}\n\t\tSPI.transfer(cmd, 3);\n\t\tmemset(buf, 0, len);\n\t\tSPI.transfer(buf, len);\n\t\tresetSS();\n\t}\n\treturn len;\n}\n\nvoid W5100Class::execCmdSn(SOCKET s, SockCMD _cmd)\n{\n\t// Send command to socket\n\twriteSnCR(s, _cmd);\n\t// Wait for command to complete\n\twhile (readSnCR(s)) ;\n}\n" }, { "name": "src/w5100.h", "url": "src/w5100.h", "fileData": "/*\n * Copyright 2018 Paul Stoffregen\n * Copyright (c) 2010 by Cristian Maglie \n *\n * This file is free software; you can redistribute it and/or modify\n * it under the terms of either the GNU General Public License version 2\n * or the GNU Lesser General Public License version 2.1, both as\n * published by the Free Software Foundation.\n */\n\n// w5100.h contains private W5x00 hardware \"driver\" level definitions\n// which are not meant to be exposed to other libraries or Arduino users\n\n#ifndef\tW5100_H_INCLUDED\n#define\tW5100_H_INCLUDED\n\n#include \n#include \n\n// Safe for all chips\n#define SPI_ETHERNET_SETTINGS SPISettings(14000000, MSBFIRST, SPI_MODE0)\n\n// Safe for W5200 and W5500, but too fast for W5100\n// Uncomment this if you know you'll never need W5100 support.\n// Higher SPI clock only results in faster transfer to hosts on a LAN\n// or with very low packet latency. With ordinary internet latency,\n// the TCP window size & packet loss determine your overall speed.\n//#define SPI_ETHERNET_SETTINGS SPISettings(30000000, MSBFIRST, SPI_MODE0)\n\n\n// Require Ethernet.h, because we need MAX_SOCK_NUM\n#ifndef ethernet_h_\n#error \"Ethernet.h must be included before w5100.h\"\n#endif\n\n\n// Arduino 101's SPI can not run faster than 8 MHz.\n#if defined(ARDUINO_ARCH_ARC32)\n#undef SPI_ETHERNET_SETTINGS\n#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE0)\n#endif\n\n// Arduino Zero can't use W5100-based shields faster than 8 MHz\n// https://github.com/arduino-libraries/Ethernet/issues/37#issuecomment-408036848\n// W5500 does seem to work at 12 MHz. Delete this if only using W5500\n#if defined(__SAMD21G18A__)\n#undef SPI_ETHERNET_SETTINGS\n#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE0)\n#endif\n\n\ntypedef uint8_t SOCKET;\n\nclass SnMR {\npublic:\n static const uint8_t CLOSE = 0x00;\n static const uint8_t TCP = 0x21;\n static const uint8_t UDP = 0x02;\n static const uint8_t IPRAW = 0x03;\n static const uint8_t MACRAW = 0x04;\n static const uint8_t PPPOE = 0x05;\n static const uint8_t ND = 0x20;\n static const uint8_t MULTI = 0x80;\n};\n\nenum SockCMD {\n Sock_OPEN = 0x01,\n Sock_LISTEN = 0x02,\n Sock_CONNECT = 0x04,\n Sock_DISCON = 0x08,\n Sock_CLOSE = 0x10,\n Sock_SEND = 0x20,\n Sock_SEND_MAC = 0x21,\n Sock_SEND_KEEP = 0x22,\n Sock_RECV = 0x40\n};\n\nclass SnIR {\npublic:\n static const uint8_t SEND_OK = 0x10;\n static const uint8_t TIMEOUT = 0x08;\n static const uint8_t RECV = 0x04;\n static const uint8_t DISCON = 0x02;\n static const uint8_t CON = 0x01;\n};\n\nclass SnSR {\npublic:\n static const uint8_t CLOSED = 0x00;\n static const uint8_t INIT = 0x13;\n static const uint8_t LISTEN = 0x14;\n static const uint8_t SYNSENT = 0x15;\n static const uint8_t SYNRECV = 0x16;\n static const uint8_t ESTABLISHED = 0x17;\n static const uint8_t FIN_WAIT = 0x18;\n static const uint8_t CLOSING = 0x1A;\n static const uint8_t TIME_WAIT = 0x1B;\n static const uint8_t CLOSE_WAIT = 0x1C;\n static const uint8_t LAST_ACK = 0x1D;\n static const uint8_t UDP = 0x22;\n static const uint8_t IPRAW = 0x32;\n static const uint8_t MACRAW = 0x42;\n static const uint8_t PPPOE = 0x5F;\n};\n\nclass IPPROTO {\npublic:\n static const uint8_t IP = 0;\n static const uint8_t ICMP = 1;\n static const uint8_t IGMP = 2;\n static const uint8_t GGP = 3;\n static const uint8_t TCP = 6;\n static const uint8_t PUP = 12;\n static const uint8_t UDP = 17;\n static const uint8_t IDP = 22;\n static const uint8_t ND = 77;\n static const uint8_t RAW = 255;\n};\n\nenum W5100Linkstatus {\n UNKNOWN,\n LINK_ON,\n LINK_OFF\n};\n\nclass W5100Class {\n\npublic:\n static uint8_t init(void);\n\n inline void setGatewayIp(const uint8_t * addr) { writeGAR(addr); }\n inline void getGatewayIp(uint8_t * addr) { readGAR(addr); }\n\n inline void setSubnetMask(const uint8_t * addr) { writeSUBR(addr); }\n inline void getSubnetMask(uint8_t * addr) { readSUBR(addr); }\n\n inline void setMACAddress(const uint8_t * addr) { writeSHAR(addr); }\n inline void getMACAddress(uint8_t * addr) { readSHAR(addr); }\n\n inline void setIPAddress(const uint8_t * addr) { writeSIPR(addr); }\n inline void getIPAddress(uint8_t * addr) { readSIPR(addr); }\n\n inline void setRetransmissionTime(uint16_t timeout) { writeRTR(timeout); }\n inline void setRetransmissionCount(uint8_t retry) { writeRCR(retry); }\n\n static void execCmdSn(SOCKET s, SockCMD _cmd);\n\n\n // W5100 Registers\n // ---------------\n//private:\npublic:\n static uint16_t write(uint16_t addr, const uint8_t *buf, uint16_t len);\n static uint8_t write(uint16_t addr, uint8_t data) {\n return write(addr, &data, 1);\n }\n static uint16_t read(uint16_t addr, uint8_t *buf, uint16_t len);\n static uint8_t read(uint16_t addr) {\n uint8_t data;\n read(addr, &data, 1);\n return data;\n }\n\n#define __GP_REGISTER8(name, address) \\\n static inline void write##name(uint8_t _data) { \\\n write(address, _data); \\\n } \\\n static inline uint8_t read##name() { \\\n return read(address); \\\n }\n#define __GP_REGISTER16(name, address) \\\n static void write##name(uint16_t _data) { \\\n uint8_t buf[2]; \\\n buf[0] = _data >> 8; \\\n buf[1] = _data & 0xFF; \\\n write(address, buf, 2); \\\n } \\\n static uint16_t read##name() { \\\n uint8_t buf[2]; \\\n read(address, buf, 2); \\\n return (buf[0] << 8) | buf[1]; \\\n }\n#define __GP_REGISTER_N(name, address, size) \\\n static uint16_t write##name(const uint8_t *_buff) { \\\n return write(address, _buff, size); \\\n } \\\n static uint16_t read##name(uint8_t *_buff) { \\\n return read(address, _buff, size); \\\n }\n static W5100Linkstatus getLinkStatus();\n\npublic:\n __GP_REGISTER8 (MR, 0x0000); // Mode\n __GP_REGISTER_N(GAR, 0x0001, 4); // Gateway IP address\n __GP_REGISTER_N(SUBR, 0x0005, 4); // Subnet mask address\n __GP_REGISTER_N(SHAR, 0x0009, 6); // Source MAC address\n __GP_REGISTER_N(SIPR, 0x000F, 4); // Source IP address\n __GP_REGISTER8 (IR, 0x0015); // Interrupt\n __GP_REGISTER8 (IMR, 0x0016); // Interrupt Mask\n __GP_REGISTER16(RTR, 0x0017); // Timeout address\n __GP_REGISTER8 (RCR, 0x0019); // Retry count\n __GP_REGISTER8 (RMSR, 0x001A); // Receive memory size (W5100 only)\n __GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size (W5100 only)\n __GP_REGISTER8 (PATR, 0x001C); // Authentication type address in PPPoE mode\n __GP_REGISTER8 (PTIMER, 0x0028); // PPP LCP Request Timer\n __GP_REGISTER8 (PMAGIC, 0x0029); // PPP LCP Magic Number\n __GP_REGISTER_N(UIPR, 0x002A, 4); // Unreachable IP address in UDP mode (W5100 only)\n __GP_REGISTER16(UPORT, 0x002E); // Unreachable Port address in UDP mode (W5100 only)\n __GP_REGISTER8 (VERSIONR_W5200,0x001F); // Chip Version Register (W5200 only)\n __GP_REGISTER8 (VERSIONR_W5500,0x0039); // Chip Version Register (W5500 only)\n __GP_REGISTER8 (PSTATUS_W5200, 0x0035); // PHY Status\n __GP_REGISTER8 (PHYCFGR_W5500, 0x002E); // PHY Configuration register, default: 10111xxx\n\n\n#undef __GP_REGISTER8\n#undef __GP_REGISTER16\n#undef __GP_REGISTER_N\n\n // W5100 Socket registers\n // ----------------------\nprivate:\n static uint16_t CH_BASE(void) {\n //if (chip == 55) return 0x1000;\n //if (chip == 52) return 0x4000;\n //return 0x0400;\n return CH_BASE_MSB << 8;\n }\n static uint8_t CH_BASE_MSB; // 1 redundant byte, saves ~80 bytes code on AVR\n static const uint16_t CH_SIZE = 0x0100;\n\n static inline uint8_t readSn(SOCKET s, uint16_t addr) {\n return read(CH_BASE() + s * CH_SIZE + addr);\n }\n static inline uint8_t writeSn(SOCKET s, uint16_t addr, uint8_t data) {\n return write(CH_BASE() + s * CH_SIZE + addr, data);\n }\n static inline uint16_t readSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len) {\n return read(CH_BASE() + s * CH_SIZE + addr, buf, len);\n }\n static inline uint16_t writeSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len) {\n return write(CH_BASE() + s * CH_SIZE + addr, buf, len);\n }\n\n#define __SOCKET_REGISTER8(name, address) \\\n static inline void write##name(SOCKET _s, uint8_t _data) { \\\n writeSn(_s, address, _data); \\\n } \\\n static inline uint8_t read##name(SOCKET _s) { \\\n return readSn(_s, address); \\\n }\n#define __SOCKET_REGISTER16(name, address) \\\n static void write##name(SOCKET _s, uint16_t _data) { \\\n uint8_t buf[2]; \\\n buf[0] = _data >> 8; \\\n buf[1] = _data & 0xFF; \\\n writeSn(_s, address, buf, 2); \\\n } \\\n static uint16_t read##name(SOCKET _s) { \\\n uint8_t buf[2]; \\\n readSn(_s, address, buf, 2); \\\n return (buf[0] << 8) | buf[1]; \\\n }\n#define __SOCKET_REGISTER_N(name, address, size) \\\n static uint16_t write##name(SOCKET _s, uint8_t *_buff) { \\\n return writeSn(_s, address, _buff, size); \\\n } \\\n static uint16_t read##name(SOCKET _s, uint8_t *_buff) { \\\n return readSn(_s, address, _buff, size); \\\n }\n\npublic:\n __SOCKET_REGISTER8(SnMR, 0x0000) // Mode\n __SOCKET_REGISTER8(SnCR, 0x0001) // Command\n __SOCKET_REGISTER8(SnIR, 0x0002) // Interrupt\n __SOCKET_REGISTER8(SnSR, 0x0003) // Status\n __SOCKET_REGISTER16(SnPORT, 0x0004) // Source Port\n __SOCKET_REGISTER_N(SnDHAR, 0x0006, 6) // Destination Hardw Addr\n __SOCKET_REGISTER_N(SnDIPR, 0x000C, 4) // Destination IP Addr\n __SOCKET_REGISTER16(SnDPORT, 0x0010) // Destination Port\n __SOCKET_REGISTER16(SnMSSR, 0x0012) // Max Segment Size\n __SOCKET_REGISTER8(SnPROTO, 0x0014) // Protocol in IP RAW Mode\n __SOCKET_REGISTER8(SnTOS, 0x0015) // IP TOS\n __SOCKET_REGISTER8(SnTTL, 0x0016) // IP TTL\n __SOCKET_REGISTER8(SnRX_SIZE, 0x001E) // RX Memory Size (W5200 only)\n __SOCKET_REGISTER8(SnTX_SIZE, 0x001F) // RX Memory Size (W5200 only)\n __SOCKET_REGISTER16(SnTX_FSR, 0x0020) // TX Free Size\n __SOCKET_REGISTER16(SnTX_RD, 0x0022) // TX Read Pointer\n __SOCKET_REGISTER16(SnTX_WR, 0x0024) // TX Write Pointer\n __SOCKET_REGISTER16(SnRX_RSR, 0x0026) // RX Free Size\n __SOCKET_REGISTER16(SnRX_RD, 0x0028) // RX Read Pointer\n __SOCKET_REGISTER16(SnRX_WR, 0x002A) // RX Write Pointer (supported?)\n\n#undef __SOCKET_REGISTER8\n#undef __SOCKET_REGISTER16\n#undef __SOCKET_REGISTER_N\n\n\nprivate:\n static uint8_t chip;\n static uint8_t ss_pin;\n static uint8_t softReset(void);\n static uint8_t isW5100(void);\n static uint8_t isW5200(void);\n static uint8_t isW5500(void);\n\npublic:\n static uint8_t getChip(void) { return chip; }\n#ifdef ETHERNET_LARGE_BUFFERS\n static uint16_t SSIZE;\n static uint16_t SMASK;\n#else\n static const uint16_t SSIZE = 2048;\n static const uint16_t SMASK = 0x07FF;\n#endif\n static uint16_t SBASE(uint8_t socknum) {\n if (chip == 51) {\n return socknum * SSIZE + 0x4000;\n } else {\n return socknum * SSIZE + 0x8000;\n }\n }\n static uint16_t RBASE(uint8_t socknum) {\n if (chip == 51) {\n return socknum * SSIZE + 0x6000;\n } else {\n return socknum * SSIZE + 0xC000;\n }\n }\n\n static bool hasOffsetAddressMapping(void) {\n if (chip == 55) return true;\n return false;\n }\n static void setSS(uint8_t pin) { ss_pin = pin; }\n\nprivate:\n#if defined(__AVR__)\n\tstatic volatile uint8_t *ss_pin_reg;\n\tstatic uint8_t ss_pin_mask;\n\tinline static void initSS() {\n\t\tss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin));\n\t\tss_pin_mask = digitalPinToBitMask(ss_pin);\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\t*(ss_pin_reg) &= ~ss_pin_mask;\n\t}\n\tinline static void resetSS() {\n\t\t*(ss_pin_reg) |= ss_pin_mask;\n\t}\n#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__)\n\tstatic volatile uint8_t *ss_pin_reg;\n\tinline static void initSS() {\n\t\tss_pin_reg = portOutputRegister(ss_pin);\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\t*(ss_pin_reg+256) = 1;\n\t}\n\tinline static void resetSS() {\n\t\t*(ss_pin_reg+128) = 1;\n\t}\n#elif defined(__MKL26Z64__)\n\tstatic volatile uint8_t *ss_pin_reg;\n\tstatic uint8_t ss_pin_mask;\n\tinline static void initSS() {\n\t\tss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin));\n\t\tss_pin_mask = digitalPinToBitMask(ss_pin);\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\t*(ss_pin_reg+8) = ss_pin_mask;\n\t}\n\tinline static void resetSS() {\n\t\t*(ss_pin_reg+4) = ss_pin_mask;\n\t}\n#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__)\n\tstatic volatile uint32_t *ss_pin_reg;\n\tstatic uint32_t ss_pin_mask;\n\tinline static void initSS() {\n\t\tss_pin_reg = &(digitalPinToPort(ss_pin)->PIO_PER);\n\t\tss_pin_mask = digitalPinToBitMask(ss_pin);\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\t*(ss_pin_reg+13) = ss_pin_mask;\n\t}\n\tinline static void resetSS() {\n\t\t*(ss_pin_reg+12) = ss_pin_mask;\n\t}\n#elif defined(__PIC32MX__)\n\tstatic volatile uint32_t *ss_pin_reg;\n\tstatic uint32_t ss_pin_mask;\n\tinline static void initSS() {\n\t\tss_pin_reg = portModeRegister(digitalPinToPort(ss_pin));\n\t\tss_pin_mask = digitalPinToBitMask(ss_pin);\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\t*(ss_pin_reg+8+1) = ss_pin_mask;\n\t}\n\tinline static void resetSS() {\n\t\t*(ss_pin_reg+8+2) = ss_pin_mask;\n\t}\n\n#elif defined(ARDUINO_ARCH_ESP8266)\n\tstatic volatile uint32_t *ss_pin_reg;\n\tstatic uint32_t ss_pin_mask;\n\tinline static void initSS() {\n\t\tss_pin_reg = (volatile uint32_t*)GPO;\n\t\tss_pin_mask = 1 << ss_pin;\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\tGPOC = ss_pin_mask;\n\t}\n\tinline static void resetSS() {\n\t\tGPOS = ss_pin_mask;\n\t}\n\n#elif defined(__SAMD21G18A__)\n\tstatic volatile uint32_t *ss_pin_reg;\n\tstatic uint32_t ss_pin_mask;\n\tinline static void initSS() {\n\t\tss_pin_reg = portModeRegister(digitalPinToPort(ss_pin));\n\t\tss_pin_mask = digitalPinToBitMask(ss_pin);\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\t*(ss_pin_reg+5) = ss_pin_mask;\n\t}\n\tinline static void resetSS() {\n\t\t*(ss_pin_reg+6) = ss_pin_mask;\n\t}\n#else\n\tinline static void initSS() {\n\t\tpinMode(ss_pin, OUTPUT);\n\t}\n\tinline static void setSS() {\n\t\tdigitalWrite(ss_pin, LOW);\n\t}\n\tinline static void resetSS() {\n\t\tdigitalWrite(ss_pin, HIGH);\n\t}\n#endif\n};\n\nextern W5100Class W5100;\n\n\n\n#endif\n\n#ifndef UTIL_H\n#define UTIL_H\n\n#define htons(x) ( (((x)<<8)&0xFF00) | (((x)>>8)&0xFF) )\n#define ntohs(x) htons(x)\n\n#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \\\n ((x)<< 8 & 0x00FF0000UL) | \\\n ((x)>> 8 & 0x0000FF00UL) | \\\n ((x)>>24 & 0x000000FFUL) )\n#define ntohl(x) htonl(x)\n\n#endif\n" } ] } }, "platform": [ "mblockpc" ], "extApiVersion": [ "1.0.3" ], "name": "vdr ethernet shield ", "targets": [ "arduino_mega2560", "arduino_uno" ], "id": "18723", "sort": 999, "description": "Gestion des shields ethernet Arduino. Client et serveur WEB, IP fixe ou dynamique", "homepage": "https://www.du-man.net", "sourceFiles": "", "code": "// enter your javascript code here\n", "handler": "\nconst ExtHandler = {\n\n // when extension is loaded\n onLoad(app, target) {\n },\n\n // when extension is unloaded\n onUnload(app) {\n // TODO\n },\n\n // when device is connected\n onConnect(app, device) {\n // TODO\n },\n\n // when device is disconnected\n onDisconnect(app, device) {\n // TODO\n },\n\n // when stop button is clicked\n onStopAll(app, device) {\n // TODO\n },\n\n // before switch to upload mode\n beforeChangeUploadMode(app, device) {\n // TODO\n return true;\n },\n\n // before switch to debug mode\n beforeChangeDebugMode(app, device) {\n // TODO\n return true;\n },\n\n // after switched to upload mode\n afterChangeUploadMode(app, device) {\n // TODO\n return true;\n },\n\n // after switched to debug mode\n afterChangeDebugMode(app, device) {\n // TODO\n return true;\n },\n\n // when device is selected\n onSelect(app, device) {\n // TODO\n },\n\n // when device is unselected\n onUnselect(app, device) {\n // TODO\n },\n\n // before upload code\n beforeCodeUpload(app, device) {\n // TODO\n },\n\n // after code uploaded\n afterCodeUpload(app, device) {\n // TODO\n },\n\n // when receiving and reading byte\n onRead(app, device) {\n // TODO\n }\n}\n" }PK BV5Zdata.bak/categroy.json[ { "identify": "cate_a6db9026", "name": "Ethernet shield", "menuIconURI": "", "blockIcon": { "name": "ethernet.png", "url": "https://mblock-expanded.oss-cn-shenzhen.aliyuncs.com/c6ed8de0c5964a5fa3964e968e7a6466.png" }, "colors": "#05A6FF", "eid": "18723", "id": "31822", "sort": 999, "create_time": 1634911077, "modify_time": 1653780889, "uid": 1281238 } ]PK BV+hhdata.bak/block.json[ { "eid": "18723", "cid": "31822", "name": "Initialise Ethenet", "opcode": "BLOCK_1653780308718", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 0, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": [ "\"src/SPI.h\"", "\"src/Ethernet.h\"" ], "lib": "", "declare": "#define DEBUG true\r\nEthernetClient client;\r\nbool firstParam=true;;\r\nbool ethSucceed=false;\r\n\r\nvoid receiveData(){\r\n String reponse=\"\";\r\n while (client.connected()){\r\n while (client.available()){\r\n char c = client.read();\r\n reponse += c;\r\n }\r\n }\r\n if (!client.connected()) client.stop();\r\n if(DEBUG) Serial.println(reponse);\r\n}\r\n\r\nvoid ethGetData(){\r\n String reponse=\"\";\r\n ethSucceed = false ;\r\n if (client.find(\"200 OK\")){\r\n ethSucceed = true;\r\n }\r\n client.find(\"\\r\\n\\r\\n\");\r\n while (client.available()){\r\n char c = client.read();\r\n reponse += c;\r\n }\r\n if (!client.connected()) client.stop();\r\n}\r\n\r\nvoid ethernetInitialise(){\r\n byte ethMac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };\r\n\r\n ethSucceed = false ;\r\n if (DEBUG){\r\n Serial.println();\r\n Serial.print(F(\"Set IP...\"));\r\n }\r\n\r\n /*{$BRANCH1}*/ \r\n\r\n \r\n if (DEBUG){\r\n if(ethSucceed) Serial.println(F(\"OK\")); else Serial.println(F(\"Failed\"));\r\n Serial.println(Ethernet.localIP());\r\n }\r\n}", "setup": "", "code": "", "_loop": "" } }, "id": "311960", "create_time": 1634911077, "modify_time": 1675369052, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "Définir IP DHCP", "opcode": "BLOCK_1675367642335", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "id": "364563", "sort": 1, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "ethSucceed = Ethernet.begin(ethMac);", "_loop": "" } }, "create_time": 1672150742, "modify_time": 1675368402, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "Definir IP @[String](string) , Masque @[String](string) , Passerelle @[String](string) , DNS @[String](string) ", "opcode": "BLOCK_1653780309012", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 2, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": [], "lib": "", "declare": "", "setup": "", "code": "IPAddress ethIP;\r\nIPAddress ethDNS;\r\nIPAddress ethGateway;\r\nIPAddress ethMask;\r\n\r\nethIP.fromString(/*{IP}*/);\r\nethMask.fromString(/*{Mask}*/);\r\nethGateway.fromString(/*{Gateway}*/);\r\nethDNS.fromString(/*{DNS}*/);\r\n\r\nEthernet.begin(ethMac, ethIP, ethDNS, ethGateway, ethMask);\r\nethSucceed = (Ethernet.localIP() == ethIP);\r\n\r\n", "_loop": "" } }, "id": "311961", "args": [ { "type": "string", "name": "IP", "val": "172.16.112.50", "checkNumber": false }, { "type": "string", "name": "Mask", "val": "255.255.240.0", "checkNumber": false }, { "type": "string", "name": "Gateway", "val": "172.16.112.254", "checkNumber": false }, { "type": "string", "name": "DNS", "val": "172.16.128.1", "checkNumber": false } ], "create_time": 1634911077, "modify_time": 1675368365, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "Lire @[Dropdown](fieldMenu) ", "opcode": "BLOCK_1653780309457", "blockType": "string", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 3, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "String ethGetIP(int type){\r\n IPAddress ethIP;\r\n switch (type) {\r\n case 0:\r\n ethIP=Ethernet.localIP();\r\n break;\r\n case 1:\r\n ethIP=Ethernet.dnsServerIP();\r\n break;\r\n case 2:\r\n ethIP=Ethernet.gatewayIP();\r\n break;\r\n case 3:\r\n ethIP=Ethernet.subnetMask();\r\n break;\r\n }\r\n String ip;\r\n ip = ethIP[0];\r\n ip +=\".\";\r\n ip += ethIP[1];\r\n ip +=\".\";\r\n ip += ethIP[2];\r\n ip +=\".\";\r\n ip += ethIP[3];\r\n return ip;\r\n}", "setup": "", "code": "ethGetIP(/*{IP}*/)", "_loop": "" } }, "args": [ { "type": "fieldMenu", "name": "IP", "menus": [ { "text": "IP", "value": "0" }, { "text": "DNS", "value": "1" }, { "text": "Passerelle", "value": "2" }, { "text": "Masque", "value": "3" } ], "val": "0" } ], "id": "311962", "create_time": 1634911077, "modify_time": 1675368365, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "Démarrer le client WEB", "opcode": "BLOCK_1654274936853", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "id": "313293", "sort": 4, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "ethernetInitialise();", "_loop": "" } }, "create_time": 1634911077, "modify_time": 1675368365, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "Ajouter Donnée URL Champ @[String](string) Valeur @[String](string)", "opcode": "BLOCK_1653780309804", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 5, "args": [ { "type": "string", "name": "champ", "val": "", "checkNumber": false }, { "type": "string", "name": "valeur", "val": "", "checkNumber": false } ], "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "HttpData(/*{champ}*/,/*{valeur}*/);", "_loop": "" } }, "id": "311963", "create_time": 1634911077, "modify_time": 1675368747, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "Acceder page web : serveur @[String](string) page @[String](string) ", "opcode": "BLOCK_1653780310011", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 6, "args": [ { "type": "string", "name": "server", "val": "api.thingspeak.com", "checkNumber": false }, { "type": "string", "name": "page", "val": "/update", "checkNumber": false } ], "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "/*\r\nvoid AddHttpData(String field, String value){\r\n if (firstParam){\r\n ethRequest=\"\";\r\n }else{\r\n ethRequest=ethRequest+\"&\";\r\n }\r\n ethRequest=ethRequest+field+\"=\"+value;\r\n firstParam=false;\r\n}\r\n*/\r\n\r\nvoid HttpData(String field, String value){\r\n if (firstParam){\r\n client.print(field+\"=\"+value);\r\n firstParam=false;\r\n }else{\r\n client.print(\"&\"+field+\"=\"+value);\r\n }\r\n}\r\n\r\nvoid httpRequest(String strServer, String page){\r\n char server[strServer.length()+1];\r\n strServer.toCharArray(server,strServer.length()+1);\r\n if (DEBUG) Serial.print(F(\"Con. serveur...\"));\r\n ethSucceed = client.connect(server,80);\r\n if (DEBUG){\r\n if(ethSucceed) Serial.println(F(\"OK\")); else Serial.println(F(\"Failed\"));\r\n }\r\n if (DEBUG) Serial.print(F(\"Envoyer...\"));\r\n if(ethSucceed){\r\n ethSucceed = false;\r\n \r\n /*\r\n if (/*{POST}*/){\r\n \r\n client.print(F(\"POST \"));\r\n client.print(page);\r\n client.println(F(\" HTTP/1.1\"));\r\n client.print(F(\"Host: \"));\r\n client.println(strServer);\r\n client.println(F(\"Content-Type: application/x-www-form-urlencoded\"));\r\n client.println(F(\"Connection: close\"));\r\n client.println(F(\"User-Agent: Arduino/1.0\"));\r\n client.print(F(\"Content-Length: \"));\r\n client.println(ethRequest.length());\r\n client.println();\r\n client.println(ethRequest);\r\n client.println();\r\n }else{\r\n */ \r\n client.print(F(\"GET \"));\r\n client.print(page + \"?\");\r\n /*{$BRANCH1}*/\r\n client.println(F(\" HTTP/1.1\"));\r\n client.print(F(\"Host: \"));\r\n client.println(strServer);\r\n client.println(F(\"User-Agent: arduino-ethernet\"));\r\n client.println(F(\"Connection: close\"));\r\n client.println();\r\n //}\r\n ethGetData();\r\n }\r\n firstParam=true;\r\n if (DEBUG){\r\n if(ethSucceed){\r\n Serial.println(F(\"OK\")); \r\n }else{\r\n Serial.println(F(\"Failed\"));\r\n }\r\n Serial.print(F(\"reçu...\"));\r\n }\r\n}", "setup": "", "code": "httpRequest(/*{server}*/, /*{page}*/);", "_loop": "" } }, "id": "311964", "create_time": 1634911077, "modify_time": 1675370085, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "Succès", "opcode": "BLOCK_1654273986221", "blockType": "boolean", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "id": "313292", "sort": 8, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "ethSucceed", "_loop": "" } }, "create_time": 1634911077, "modify_time": 1675368365, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "Démarrer serveur WEB port @[Number](number) ", "opcode": "BLOCK_1653855510926", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "id": "312483", "sort": 9, "args": [ { "type": "number", "name": "port", "val": 80 } ], "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "EthernetServer server(/*{port}*/);", "setup": "", "code": "ethernetInitialise();\r\nserver.begin();\r\ndelay(1000);", "_loop": "" } }, "create_time": 1634911077, "modify_time": 1675370685, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "Afficher la page WEB titre @[String](string) rafraichir @[Dropdown](fieldMenu) ", "opcode": "BLOCK_1653780310978", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 10, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "while(1){\r\n EthernetClient Wclient;\r\n Wclient = server.available();\r\n if (Wclient) {\r\n while (Wclient.connected()) { \r\n if (Wclient.available()) {\r\n char c = Wclient.read();\r\n String ethRequest;\r\n if (ethRequest.length() < 100) {\r\n ethRequest += c; \r\n }\r\n if (c == '\\n') {\r\n _loop();\r\n\r\n Wclient.println(F(\"HTTP/1.1 200 OK\")); //send new page\r\n Wclient.println(F(\"Content-Type: text/html\"));\r\n if(/*{refresh}*/>0){\r\n Wclient.print(F(\"Refresh: \"));\r\n Wclient.println(String(/*{refresh}*/));\r\n }\r\n Wclient.println();\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n Wclient.print(F(\"\"));\r\n Wclient.print(String(/*{titre}*/));\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n\r\n /*{$BRANCH1}*/ \r\n\r\n Wclient.println(F(\"\"));\r\n Wclient.println(F(\"\"));\r\n \r\n ethRequest = \"\";\r\n delay(1);\r\n Wclient.stop();\r\n }\r\n }\r\n }\r\n }\r\n}", "_loop": "" } }, "id": "311966", "args": [ { "type": "string", "name": "titre", "val": "titre", "checkNumber": false }, { "type": "fieldMenu", "name": "refresh", "val": "0", "menus": [ { "text": "jamais", "value": "0" }, { "text": "5 s", "value": "5" }, { "text": "10 s", "value": "10" }, { "text": "30 s", "value": "30" } ] } ], "create_time": 1634911077, "modify_time": 1675368968, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "Texte @[String](string) style @[Dropdown](fieldMenu) ", "opcode": "BLOCK_1653780311427", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 11, "args": [ { "type": "string", "name": "texte", "checkNumber": false, "val": "" }, { "type": "fieldMenu", "name": "style", "val": "p", "menus": [ { "text": "texte", "value": "p" }, { "text": "Titre1", "value": "H1" }, { "text": "Titre2", "value": "H2" } ] } ], "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "Wclient.print(F(\"\"));\r\nWclient.print(String(/*{texte}*/));\r\nWclient.println(F(\"\"));", "_loop": "" } }, "id": "311968", "create_time": 1634911077, "modify_time": 1675368365, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "Bouton Texte @[String](string) nom action @[String](string) ", "opcode": "BLOCK_1653780311846", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 12, "args": [ { "type": "string", "name": "texte", "val": "", "checkNumber": false }, { "type": "string", "name": "action", "val": "", "checkNumber": false } ], "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "Wclient.print(F(\"\"));\r\nWclient.print(String(/*{texte}*/));\r\nWclient.print(F(\"\"));", "_loop": "if (ethRequest.indexOf(\"?\"+String(/*{action}*/)) >0){\r\n /*{$BRANCH1}*/ \r\n}" } }, "id": "311970", "create_time": 1634911077, "modify_time": 1675368365, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "Retour-chariot", "opcode": "BLOCK_1653780311631", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 13, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "Wclient.println(F(\"
\"));", "_loop": "" } }, "id": "311969", "create_time": 1634911077, "modify_time": 1675368365, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "Lien texte @[String](string) url @[String](string) ", "opcode": "BLOCK_1653780312072", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 14, "args": [ { "type": "string", "name": "texte", "val": "", "checkNumber": false }, { "type": "string", "name": "url", "val": "http://", "checkNumber": false } ], "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "Wclient.print(F(\"\"));\r\nWclient.print(String(/*{texte}*/));\r\nWclient.println(F(\"\"));", "_loop": "" } }, "id": "311971", "create_time": 1634911077, "modify_time": 1675368365, "uid": 1281238 }, { "eid": "18723", "cid": "31822", "name": "code html @[String](string) ", "opcode": "BLOCK_1653780312304", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 15, "args": [ { "type": "string", "name": "code", "val": "", "checkNumber": false } ], "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "Wclient.print(String(/*{code}*/));", "_loop": "" } }, "id": "311972", "create_time": 1634911077, "modify_time": 1675368365, "uid": 1281238 }, { "eid": "18723", "cid": "31823", "name": "Initialise SS pin @[Number](number) ", "opcode": "BLOCK_1653781070450", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "args": [ { "type": "number", "name": "SS_pin", "val": 10 } ], "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": [ "\"src/SPI.h\"", "\"src/SD.h\"" ], "lib": "", "declare": "Sd2Card card;\r\nFile SD_file;\r\nbool SD_OK = false;\r\nbool SD_fileOpen = false;\r\nbool SD_fileInit = false;\r\nint SD_nbLine = 0;\r\nint SD_curLine = 0;\r\n\r\nvoid SD_fileClose(){\r\n if (SD_fileOpen){ \r\n SD_file.close();\r\n SD_fileOpen = false;\r\n }\r\n}\r\n\r\nbool SD_OpenFile(String fileName, bool write){\r\n if (SD_OK){\r\n if(write){\r\n SD_file = SD.open(fileName, FILE_WRITE);\r\n return true;\r\n }else{\r\n SD_file = SD.open(fileName);\r\n return true;\r\n }\r\n }\r\n return false;\r\n}", "setup": "card.init(SPI_HALF_SPEED, /*{SS_pin}*/);\r\nSD_OK = SD.begin(/*{SS_pin}*/);", "code": "", "_loop": "" } }, "id": "311985", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18723", "cid": "31823", "name": "taille Carte SD (Go)", "opcode": "BLOCK_1653781071431", "blockType": "number", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "float MBvolumeSize(){\r\n uint32_t volumesize;\r\n SdVolume volume;\r\n if (volume.init(card)){\r\n volumesize = volume.blocksPerCluster(); // clusters are collections of blocks\r\n volumesize *= volume.clusterCount(); // we'll have a lot of clusters\r\n volumesize /= 2; // SD card blocks are always 512 bytes\r\n volumesize /= 1024;\r\n return float(volumesize) / 1024;\r\n }\r\n return 0;\r\n}", "setup": "", "code": "MBvolumeSize()", "_loop": "" } }, "id": "311986", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18723", "cid": "31823", "name": "Le fichier existe @[String](string) ", "opcode": "BLOCK_1653781072255", "blockType": "boolean", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "args": [ { "type": "string", "name": "fileName", "val": "test.txt", "checkNumber": false } ], "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "bool SD_fileExist(String fileName){\r\n if (SD_OK){\r\n if(SD.exists(fileName)){\r\n return true;\r\n }\r\n }\r\n return false;\r\n}", "setup": "", "code": "SD_fileExist(/*{fileName}*/)", "_loop": "" } }, "id": "311987", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18723", "cid": "31823", "name": "Ouvrir fichier @[String](string) pour écrire", "opcode": "BLOCK_1653781072910", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "SD_fileOpen = SD_OpenFile(/*{fileName}*/,true);", "_loop": "" } }, "args": [ { "type": "string", "name": "fileName", "checkNumber": false, "val": "test.txt" } ], "id": "311988", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18723", "cid": "31823", "name": "Ajouter ligne de données @[String](string) ", "opcode": "BLOCK_1653781073695", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "args": [ { "type": "string", "name": "datas", "checkNumber": false, "val": "" } ], "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "void SD_addData(String datas){\r\n if (SD_fileOpen){\r\n SD_file.println(datas);\r\n }\r\n}", "setup": "", "code": "SD_addData(/*{datas}*/);", "_loop": "" } }, "id": "311989", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18723", "cid": "31823", "name": "Fermer fichier", "opcode": "BLOCK_1653781074410", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "SD_fileClose();", "_loop": "" } }, "id": "311990", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18723", "cid": "31823", "name": "Supprimer fichier @[String](string) ", "opcode": "BLOCK_1653781075083", "blockType": "command", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "args": [ { "type": "string", "name": "fileName", "checkNumber": false, "val": "test.txt" } ], "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "void SD_removeFile(String fileName){\r\n if (SD_OK){\r\n if (SD.exists(fileName)){\r\n SD.remove(fileName);\r\n }\r\n }\r\n}", "setup": "", "code": "SD_removeFile(/*{fileName}*/);", "_loop": "" } }, "id": "311991", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18723", "cid": "31823", "name": "Parcourir le ficher @[String](string) par ligne", "opcode": "BLOCK_1653781075850", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "String ReadNextLine(){\r\n String s;\r\n if(SD_fileOpen){\r\n if(!SD_fileInit){ //si premier appel de la fonction\r\n SD_nbLine=0;\r\n while(SD_file.available()){\r\n s=SD_file.readStringUntil('\\n');\r\n SD_nbLine++; //comptage du nombre de ligne\r\n }\r\n SD_fileInit=true;\r\n SD_file.seek(0);\r\n SD_curLine = 0;\r\n }\r\n if(SD_file.available()){\r\n s=SD_file.readStringUntil('\\n');\r\n SD_curLine++;\r\n if(SD_curLine==SD_nbLine){ //renvoi des lignes jusqu'a l'avant dernière pour éviter la ligne vide\r\n SD_fileInit=false;\r\n SD_fileClose();\r\n }\r\n return s.substring(0,s.length()-1);\r\n }\r\n }\r\n}", "setup": "", "code": "SD_fileOpen = SD_OpenFile(/*{fileName}*/,false);\r\ndo{\r\n String s=ReadNextLine();\r\n /*{$BRANCH1}*/ \r\n}while(SD_fileOpen);", "_loop": "" } }, "args": [ { "type": "string", "name": "fileName", "val": "test.txt", "checkNumber": false } ], "id": "311992", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18723", "cid": "31823", "name": "Contenu de la ligne", "opcode": "BLOCK_1653781076765", "blockType": "string", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "s", "_loop": "" } }, "id": "311993", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18723", "cid": "31823", "name": "Extraire donnée n° @[Number](number) de @[String](string) séparateur @[String](string) ", "opcode": "BLOCK_1653781077448", "blockType": "string", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "String getValue(String data, String separator, int index){\r\n int pos1 = 0;\r\n int i = 0;\r\n while(ipos1){\r\n i++;\r\n pos1=pos+1;\r\n }\r\n }\r\n int pos2 = data.indexOf(separator,pos1+1);\r\n if (pos2>pos1){\r\n return data.substring(pos1,pos2);\r\n }else{\r\n return data.substring(pos1,data.length());\r\n }\r\n}", "setup": "", "code": "getValue(/*{datas}*/,/*{separator}*/,/*{index}*/)", "_loop": "" } }, "args": [ { "type": "number", "name": "index", "val": 1 }, { "type": "string", "name": "datas", "val": "", "checkNumber": false }, { "type": "string", "name": "separator", "val": ",", "checkNumber": false } ], "id": "311994", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 }, { "eid": "18723", "cid": "31823", "name": "Parcourir le fichier @[String](string) par bloc de @[Number](number) caractères", "opcode": "BLOCK_1653781078182", "blockType": "conditional", "checkboxInFlyout": false, "gap": 12, "disableOnline": false, "disableOffline": false, "generatorCode": false, "blockState": "incomplete", "sort": 999, "args": [ { "type": "string", "name": "fileName", "checkNumber": false, "val": "page.html" }, { "type": "number", "name": "bloclen", "val": 80 } ], "handler": { "onRun": "(args, app, device, block) => {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "char SD_buff[/*{bloclen}*/] ;\r\nvoid SD_ReadFileBuf(int len){\r\n memset(SD_buff, 0, sizeof SD_buff);\r\n int i = 0;\r\n if (SD_fileOpen){\r\n while(SD_file.available() and i {\n // JavaScript code\n}" }, "codes": { "arduinoc": { "include": "", "lib": "", "declare": "", "setup": "", "code": "SD_buff", "_loop": "" } }, "id": "311996", "create_time": 1634911077, "modify_time": 1634911077, "uid": 1281238 } ]PK BV)L data.bak/translate.json[]PK BV)L data.bak/facepanel.json[]PK BVimgs/PK BV 4)imgs/c6ed8de0c5964a5fa3964e968e7a6466.pngPNG  IHDRd`sBiCCPICC profile(}=H@_E*FqP,8J`Zu0 4$-.kŪ "%/)=B4+0hzLƢR&*u"D b@fO-9]gys9>xfxxfjp'YQVωM #8xh"T`YԈêSqYY+X:İ8ʨ"BN$G=Î?A.\%0r, ZI7)/1 tͺmv?Wz_iZ.ۚ\COlʎ)}SzZ8} pp({ݝ{C"r+L6bKGD pHYs  tIME#!&|IDATx=ip]u}OO%oٌRIX LHmJ„IDŽaBb״3m!{6^y$ˋl-dIϖޢw}IO$o|gͷ{s~G03("3#݄`F dY3#B6H)@{˲'MZ6uԶx<)h3?4?*Bmm-gѻO>jk@A0&2VUl88>{NPOyݵ9Zן dĬvN"9S4r8ٱ{Om;[vK-Pxi妍__mf."sOt+h/{fxzBDLD{7ƻf#gkmYrSZiBQAA8<("hj!AY#3"r$bPA@p *+A lj9^ǒ *9!Y)Gda4T̚5+8"1sIܶx<31"2jb+uם?Qj6nY} bČ G#ѯeSHm//wwtVаxCfb}ʘY#(.NJ&KJϟv.efkO+6xp77y̢9b[?[ ّhi_P<%23܂4(ޭ(!2=Кu}qOM0MC0!HC8Gjx<չf ݿ{X}W\gt,Za?*ٳ,4'UQS6UXvߞZtɉ[<ŗvu],(BV R:3 0Ж Gtw&ۺ&7odA0GFcܽNo߾E"2>TYv]މM7fko`.ҩ55@Р&'Ot$uuu_R7OSaʔI3OUST/ܱ.)$seEڗg:NtsYeY|1 hrǯ~Snk|> vHќ?`kkMj]v%9}ٳϾ1W"d!cx'U>P-^ p4R G.x'XXMLI>_ʹ~G~1,4|D:B)ݷ3OS^tp_/D@ 3C";Xpi L RMfۼ y?B=gsNb($1,v%$NY0BVT #rl:pI)l~vW(tHsg)!R R$ɣ*12$AwG9HH`!Ut".7<(?GS>qؐ TR!Hٰ۪0tV|VlcLYS'|TTVņTB#B :Aǀx$,jie>xDP%?|#&3fo\7&""á=P DTx%˗0$R:RZJ)L/cHr"yΖ{=ZDJ ;8agoA0ӧؐY `yֽh ,A"fYeS|yHY.K:%8?.=wǴOf^ 8|'@%ӗŁ i3O<}8<'r-ťhH@*\*yy4O@4-!H̢Jew ؖP%b@_XĀH }+0 vuur @tp+ٹuچ-]Q '}=M]^@10x{ŽFJRmB $>ږ_o  S'`zl?}[{-+^@F01:4$Yf~,<5~쳃ձSDWΙ#&M 31b.Y=_)$F żJrR)͝{_-_+H#-FD+o.*5h F:d^Zbq^gKw+^[Da "ڮշ|ƪ-*thOX [&ȳJU.]&.dV)[ŽQ9]/͢77TZ+&-Y[81!~rDtwKp^Ӷ]X!RTAS.A# nl5nya98Qk]Y"#} cu%ϛͷV4ibi3f;U T !$IZH `iHEF "XiZ M?33B_taLkih ~cSN/ف1ü˦S=:y`04 C8 Baٲ :v?,V IҚȢ?]A`Of"JB :{ g?aϾ:ڻI}r \bD"PcY6|Ѩ߆O0Y[۰.:RI\NEҏ.]ֶp"Qio(Rܵ.d JkYH$Rcu" Y!1H`BX_i˹X@Ԑ{/5$!1xn#QeKSV1G®RRVQQ>Aխ+IENDB`PK BVD"[x[x)imgs/8af277f6fe6c4f1b8c6232ec68cee5b0.jpgJFIF,,-,ExifII*bj(1 r2i,,GIMP 2.10.302022:05:14 14:11:37 ,JFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?( ( ( ( ( ( ( (w4|)hfn!v?AcBT z c{M1`F>Ҽ5ʰٻZi+!R?G_qRӴKKV7 ު;s7,ev/ky?*˾)7:ću4(((((((((((( ZKgF {YW~)ҡ /0w4i%_Ȋˋ׼wyV{O7G{)̭xC'GRc梳Zuc{j]HCWy@$v3f&hn~VL. Y~޺/xO8f-LiW 秽k[ ICkc:59{=|T SMor$ !#6 Ԍq <=7v-eпG`=ۙlw)3KPXQEQEQEQEQEQEV7|Oj:pOSV|UY9=? /:&ŤӴ9ރܜ}0k퍚I7f~?%<ҫ1 dzw$/=OV'fMGcŠbw]HV~dbޯ!dzօ_OYTk 7>a8Ǯ*ٍa ChHМ>Bի{=t Ҭg{W}}y#jWX=ĦFU>%,TNp> Z$Azut.Usym*I ̫"QW-EҜY7,wpO|)a|=N?_˭ZԼE5+J23~C? QU͛ҋ?2.}&,2. ۷Ԓ:q\W$sPerr1c׍?o,,G#6p;ۂO.![A?խ:1KΥGQZ:E–ڌ.%[eGC9[^s.M ޿KSקd|D'7.:8UäiCc4Q]s@_ӊsJbc8(SM9imy=o8fQӡ5Z ],]BhB6.3+!tSiZb4zKU;h+EsH֝Jr|gs٭]{ϴR:+I!GV2ڼM. NghAoEu$տ (4>e)56uOgt]rV(nZԋ ( ( ( ( (Mf^jJAdGJ^x+AԚ\h^YVQ(^4\^ጇ?t~ %{{md(@=*`>bR*JU[Aylged8ϵ.F'IY~VAFtcg,4vVM{UP/m̼IҵR"b4=>N^z(: Ű1W2~gouK/Or cfcϨ]hޟT&%NV&&Y.I9Ya>]I.qu\f{<e,rg0 x%/#56yocێr>^fHV=9X) Zq ;ח\xo?Duq>6+gioћS;֚=VwmJ"&dцC)"Z)MmԞIZЭAFаEuK9WZǢy;*zI9'=9nP*OWjQP1H9qe=T0NX4搼WXs]HW)0AFr*[=iKǹb7޷eZaPVH r9$IkSK8b1wqNtβ-%2:N59*7y%V?{0)*b-+cXr?OjrE¬c ڑ"Xc c]pghwy3y{n8ieYcJtr]UaL1TVUs^<(Nn{ۋKkg}FCB?J%5[K`'啱>Ӟk: \o¢ն5Qr]9{) >TDzM;6NGg^QRSRFTeT:5q&-[+^unY7{dtx✰3ɁvI6p~42ps*[k;緸xNU䟨+gʧV--oD#9b:5&r`sM f]F iν$j+6^!x~ c[^z׾Z1a(r7B}yzGs77wt͹2x`;Z//--^T$ uh'm%n'^I ^#D}aFϡ_kz`(͕@L HJd&?sV$;AAٜ|%o\^66spcKcǠBWo;wRG98'V<ϕ xgMWL=ZAqaCj;~X\j3BpQߚ ;(lMޙou 6*opI&UlѠ|`ό_`|#yVՂgW1jڭpty#9+ qsw[M3WWQծmAXV4LN"^Ni3K] 7;yVCX @ёr[Pd>3(їi^a¨ګyuJV"*ڽv4I8 2IE5v&`9\~kQ0~J4Fީ4"Ǿ[qppwP/i fZUg>WAh j R#C.zZW%7`pۥ*E({Mɶ.Cui𥽥GYIV椚lmsTlL\(_`^-<``̮͝դuтxN0q޺ 9Z"YX^%wNk}Ah\FMfjV] >؏%xVIK֒6Ǒx* އAڼsU YlZ&Wğ dӯ~`\ibԔa.>AJn}+U4V/ՠU򧳑r*NTi'bZ7`ݕ9ۜ4[Y{qj0\Y\JdEs8bf[h-ҏ;g{\shhZO\*dga>?J4ogYm U@z7^C2-QT`{۹3ɭ #WOA^iN-"w۬ $Ͽ9=J DIrQ7=2-/Sg6 KpY<}r:qV5/6ɬƍnKy3#5:C-R݆DY"K*m:YԐes3WR 8?a^x "纳<@`TerpK xMZ+eMVCo* Ib9'c=3kks&{:Wwy73]"#RUde#o5é*/ڝ!<`Rj>hgl$̤g $g7dK{;=bZ%ԥ\Gm[tz.ݼαFVkki7,db:I+\OGe3E;9H\c98>jsf{5&f'<6GV'ZNXsQOZ[Z\Cv+4pW<[j 0<~e'sZZq^ytbPЫ<[?ōiBhu ~dY g]-RN4;;dsi) [ֵ"|I.(ݬEY:/We4ĵ[{4mʜ_:Y!#PgPIO?Z[mXnt%̛@0RK]F[i 8rIgP{?ɩ,s,q+ ix7쨖Eעv'zZ~F =cŚLaH׹cwF bRK0S9zTЛ=/MFneUiߓ 3RZk Bk N"zI.wbIE'tПV<;Z8m-[/ 2Ad֭eil-u-JdI` ˜ y*]&RI] x/yn~hySךtMm̠Č<À;gӀ+k^y#;fd\ma<`o*v׭F\4VǓZw_澧\js.8lroiӚYגޣi9׏O^^ oo$Jhz)TjjP x =YO ךQi4<ѱz>>nIa ]]]lN[EYsk[Hcn?tT[]PBd7JѥuʀAskl$8RE(&d0Vk2c jm'Rwidz{g[yH-S=)/u{ߐ*VOŅ-Ms=Շ9sO,-Y;xqNNTUЫebԀI'Ž⧶ ӜJ*ږ,B,908W=*j QT`P)i(((CHFiPyb ʺӹ,c&iXg6qcK6TJ iOj,%*zVe,!=+KPk"C\T0cܸꧡG]#]i@+mz~+qlQH6dqUR*N3Fci#[7v6W?E_zϗPUy`-V#zrqp{?J#XfuOZʪ3*RxbzSܼЌc1]Ng n5kjN2+~؂i#b n,t&mƯQ0)DpU Z`QEQEQEQEQEQEQEQEQEQEfx ¿\"Vus)~Dj .%N*՝$bʖv! ǭt6KV HbLB* S袘Q@Q@Q@Q@Q@Q@ uhttp://ns.adobe.com/xap/1.0/ ICC_PROFILElcms0mntrRGB XYZ  )acspMSFT-lcms desc @cprt`6wtptchad,rXYZbXYZgXYZrTRC gTRC bTRC chrm4$dmndX$dmdd|$mluc enUS$GIMP built-in sRGBmluc enUSPublic DomainXYZ -sf32 B%nXYZ o8XYZ $XYZ bparaff Y [chrmT|L&g\mluc enUSGIMPmluc enUSsRGBC     C    H@ruyFa%շhgo]_9O'L# ex7~.ƾ~f@ak,}: x>04ZzLRMzYruOZ_ ;k}յϜDǵj>tx%Ki=H3e(kZܽ{'u"ԿZg޶ه7_f)S UqE&-BGAP}9a˹usOwk-aZGmgyS~vVj6Xm*!#0@ "23ISVϿB:;KW!;9G;Ԃ.ީ|scr5{?{|frg"%K^k^e|EAKe+y 9o CȰd/:ԣ>'joa/^Cgq͖oW->c˕.j*:Yb{&i\f:Ryq1k1DfH2d`ђIfSmZBCLP:\2X m?Yrق@1[ĨP1^D=2Zӆ זlPO&` EsG{Y9Y?ʈZx w:I/KWZsjSO>$(896KZ"#^V0!1"A02@Q #BaPRq? >&‡ >eYG&1\p~,RO HJvM+6}G+Gzgr ?AˍmSȊ _~=Ŭ[ҮM?0qK**mB7Wܲ/!K M ۉm/ŒQG;3';$M5*fQqY+&˯ D0OJiǁ>GO;/\$gǠ"_bss+'iME}~&2;39Ybc 5:O-7ԢPr;%Mr7--r)BT`,8-K;fQgΩN1S_0k C4@'k 2`V+aN|Jڎz֑$Bziq`,iry̲5sTG1W'/ Bw0j+C>iLԾԶleW;kE "m6, da+C֛nc(DAXз{6htU  %9YQXcYbBkN6'?̲oYnk?~;Wi o6L\(RK sdnvi zJyy&OJ9Hhjm KRU Ǽl_WRֻ~K[_K Zӥ֧uQ}&|*ѥmٙ0!1"2@A Qa0B#P3q?#Nf(nxQc4PN;~a*,Pܛ5f2="c ߂F1d)"([+?(z&증}F0Cl9#0J Ǝ eԌPG?{Q{_L_ C(:QeBHBՂV>=I\wh9 ܄rM|J򗕽Y3 NjcoUc6slo(7V@qԢ_o弅^ٽJiOSaRH]ni=(ԔLpђF’R Ωf탺́,I^!,oMB=d."$J}('nlQ媀GFDWgڡ 5)dep'n%EPr'eSvAb+3ccupv qPHSђS`PC$OS"ܞmHWi1LVNZi7* 8š9$@t):<輽A;v +Ǝ7*6U~Ia|y^2T5!ŦF^ GGSl|%!Փg C5`ڇ`$گ!ׄt0G1iK"Gl^Rf[M(z; Oؕ 4DDsI1Mt>ĪTi@8 D1s= H6tPVWJ*A !1AQa"2q#BR03b $@CrSD?BNG 1jSG$MV9Bo}6lL ²&8?ucMMj\b)"u(4|Iզc\[]*c\ տ7e7#oI<(KDlPM+K<LەEa:sڍoxzBwCM(oHJ Nߜ{4I^|19 ;7H.WS(62ϕiY[Q cl"cĒ: kp=ok{͍®1>*j/[Dž[=(Lc2؈٭)JCcբwS߉Q ?(l`F9PnlN2e|<4/t:~f9GZ]4bU~m]>/fi1X>\qnMTSiߧ-ܩqmy/dK\!z`v37'P$$zJ;~އs^bb3vEЁoAٓ9֖zAqz66Fe>lŖO[wGO֔)ڿ(OEfE(s+a)O9?:؅PTMB7tqC`,#6IZM:ym𫹹S(V t-X&OEzmL7ڟƈ1:>mZ cNo=MeQE ֶN6oPyxiЛXvW=ﺬBH쟅$Ok|p[ut~fLnܶWle*4Zl0~U*2zُޙE]M[8ћ :$$7җ+͕^Sc+q7N5 ܨPO]X¬N;Ǖ]NGR){.y/w<X~U&"LXj- 8e3~B֐rFj-#_xXlObnï!DM1|A@K C!ȝILfg)6yjQҙ`<{Қy߀CB{E6R72 >_c(Rw+ÕsZwAVȝޡr<>*Bak\;[ (ۄwON6E25ُƆ!V[T lD-qwiMw+i3l0l;+(NBY{Sr7^odV"|xe~oKŔyOp?*FWiSOqmf,\of3Lʃ]k/I~tXf=7> z<MƌSFxOYp-$_dWlFw}(Pa#_y nœFXbpE-̳gzR4&e؍<(1Gj<%!Au~TUNʪue͘f'7qb}.<$&7zF'?_:Y_Q}p-_]*[#/xkPܕ7*|F[}1@ A׭abM{Xow`עaSJr͎zndZ3:,8F.i\x^=:КGHn&XjϑJu% '{O){G[-RxV~>_( ^"3sfROulc.3@4"\kQղ"pF)_ $q|}8|*WVM,glcuRLnwtmm"o}g)eC{Jb^gO{6K++\nm~ q2a?zT;F6=Y^I6mjoO,$7쵷tؙǫ3?15'hA܄ÌQ։ؼ-`.G>u4$bٲpՈY& 'X2ָWh|/å*ͻ]uӥ2Hoc"'xӭz41(XSrm˔QpcRI ƟviX:iLTgGGKkutY6$xJ+wXA~y,[n|Ku}ՠIkϠ\{huymoІe|t#5$4b􃿁E t$aBw7G?`/'PA"˲ΎqifO8Dy:ydjxrfF8 ~H ,D.ޔdB&!GPaibkLീ>R >Cl}oOXЪA"oxY=O4dT`p&3ԣ(-qN<[2 N$0DS/y5 q#2 KCP<Me({sm֧Y@j G.mo*DK}(LBޏ9|$Ě:;g5pQ3c쌋6 V}H5exflF#" B2T,/C 9 S.nD/gan &(Yr4 0DR<㞁~vcjfbD/6S7Rk`cCcLJ(RpmO9% z\(Qln̰(trHy@tpY?'z/ G G'H "- 9X+iھINL\eނ%fq[{ۙo2_k hcLThtU5m$xl$qVqpe/R:2VX&j I77iYj>0(>s<\;jW'mG„g79V7 ,8%؈hO>ؐ+Y/&3-Z!.`6ٰh zƨm팡/!+?L6meP8!Dvp?L4$U*V܈F`ĸD~]DJ`bl0g](Ď=# I$II$I$@dI$I$A hI$I$,FFI$iCE{(I$'Twh $ %q$+"\_wm<#41?z_sꫳK1\Z=J {(]t8LfgJ߀ \+Cltև׬88,$l H$@Bw($I$@!$I$ H$I$Hb $I?*!1AQaq 0@P?FwedʂjAv)L]45˸ Gm:;GHſu6K{ۖFGBJGDLu+E6[ Ŵ63^8:YEryfD(0A+$YzŒb^骸}P W^(?$wJ$ A11L"dDZR|˳F,'M#:T/4wl͜¿-kGk-l*Ø $? @a@ee%+u%cO)ACOD54"A}&Thb Fc̥J.T rǧp'=xY!ʼxuq:y?\}\FrӤfжv9lpm/p6XXw{xy~YvVf$mA>hehu?1ߘRb12b9c?I~u_- ._….,)!1AQaq0@ ?[\<""FhiU( b*It9{_'$TsT :AkK񷼿v_" `3_H"8:k,m@<-A-57% W,8yyNbT]0`aj5`20W8pnFЕghu4劬+^Dm,Y6+Eձ֑FSvh4ޑEVas} e:EuC9Mp{FܮEZv dJDx>f0i4FK.s2s{)mpAM1Qq%c՘~AyrAN3 T;0TF"/<^4rڨB{e6oMˣV񪱾" r8wsDc\;,\j4kE&"y]h?И+c#}4ʀqhSp}[[JOC Tǣ0KQsz_!(t/LCrt=dKc Vфߙ#dfdfB*Tt5v(ς^zKx\Qؔ7.+֑_h&}9M&V@!Ҏ39FfG_GOF@oD(a!!pZprͮI. 9Os-tf+z|!zMAFHԐX PѐշO <1%|>+FXQ@5⠐Ux`i몴n] F`㹇?mޢF=Z0)h |2lEg|ЈbZئӻIn vmkQ;DE"{Y@aNmWWl%z@qHQPk?9>rg ڷkc\ gVOXHoujE] )ȅ hV Ekg N  TU4c`|͗ݝVă?X&`M#0(G`2hQlv(aE. sa*bPZq<[5Ij[J0 ht` %AZ=[T1x.VIީ _@2Χ4lEB?:؃w#@&,DHAh)ZerS!B Mנ6T|HHj@+" N'bl@tKֿ- Zu< D*x:alc%hMQY#cU49.Dur0p{dkłR\=I-1b?LEk4jߨ2@5tk9>Ɠ#w7Pn6`"z 8H58+4ṻ@-lj:(эF0J@l]Xgu HW8N? :hu!N+OOnR x$(D#ЯE`@C)|~0 P*)~+itja3Gk@wBW4e v*¦RhEҢp_DWʾCk^ۆ;WUkS$iŵUPPR"L8{8[[Ȅ}nl[({-0= 9+"!Ǔ] <&:Y4s*aXuEu3@?M}eWZyQX>E h,uBQn4ټec]<Шa4%h ‡J]k Sm6:٪0~ OƱxg M7q5BjC& {]~7PdU8uJgaiQaMΈZbdH.hn[ܡl>M9_6|=ySExG$ب0aKAiAE̒U#ƗK%ʈH>Vk4ol`Ŷ;_{i-XnNRp)@[H%M@EkT$L>[Z1ӽ`m{ _whHI>2nF]hXdPݨU)~cūlo5;!hPPh?j;CbHHl-Ih)"M0υն[I,!r=J4)[|0`IPESM-Bru"SӇFJԸy2XDL#NqBw>r,dΎu_l8Bjs *h"%$iD@ C*u۲@;0qEp&`5jP?.tD* :6ICI6'.Y>Utq6#Et6LtL#=Usw 0oGVtLpA [AƇ#7﬇x(9q,[4}:YZUTn5"LuV"m4ZAYo5l6( 9,Y#رuŊx Eνg`YpLCF$"2 ^`z rEQWx |/jk^`D.pM:6%4DpH#^)E[xFHB PPL EDO$~W  C9 >51jÏmT;hA?7aպ(!͇+Sʉ>oP>! @U^!5dEj߿GFaH\w"rԚr9SHDR5w&[\42ɿJg0ɂ{x߆$l;B~wa00')pC=@XM!PK BVres/PK BVi18n/PK BVesrc/langs/ru.jsPK BVLEsrc/langs/pt.jsPK BVKsrc/langs/fi.jsPK BVRsrc/langs/tr.jsPK BVbYsrc/langs/tk.jsPK BV`src/langs/en.jsPK BViifsrc/langs/index.jsPK BVDm6 6 _jmanifest.jsonPK BV wdata.bak/PK BV,{;;wdata.bak/ext.jsonPK BV5ZQ6data.bak/categroy.jsonPK BV+hhj8data.bak/block.jsonPK BV)L data.bak/translate.jsonPK BV)L :data.bak/facepanel.jsonPK BVqimgs/PK BV 4)imgs/c6ed8de0c5964a5fa3964e968e7a6466.pngPK BVD"[x[x)Zimgs/8af277f6fe6c4f1b8c6232ec68cee5b0.jpgPK BVf res/PK BVg i18n/PK BVe