So I'm using the ESP8266WebServer and ESP8266WiFiMulti libraries to run a webpage with websockets and I'm trying to figure out how many client connections I can have, and if there's any way to increase that connection limit?
Right now it seems that I can successfully create three connections from separate IPs, and then upon initiating the fourth connection, it fails (the server doesn't crash in the serial model, but the fourth connection won't load the webpage).
I've also noticed that if I refresh my own singular connection a certain number of times (inconsistent), it will fail to load the webpage as well. I haven't been able to decipher whether this has to do with there being too many consecutive connections in general or if I'm overtaxing the server by attempting to reconnect within too quick a timeframe?
In general though, it seems rather unstable and I could really use some assistance on figuring out why.
Here's my current code:
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <Hash.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
static const char ssid[] = "********";
static const char password[] = "********";
MDNSResponder mdns;
static void writeLED(bool);
ESP8266WiFiMulti WiFiMulti;
IPAddress ipAddressTest = (99,99,99,99);
ESP8266WebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);
uint8_t pageHitCounter = 0;
IPAddress ipAddressOne = (99,99,99,99);
IPAddress ipAddressTwo = (99,99,99,99);
IPAddress ipAddressThree = (99,99,99,99);
IPAddress ipAddressFour = (99,99,99,99);
uint8_t rxBuff[256];
uint8_t som = 0x11;
uint8_t eom = 0x12;
uint8_t subsys;
uint8_t receivedSubsys;
uint8_t rx_byte = 0x00;
uint8_t messageLength = 0;
uint8_t receivedMessageLength = 0;
uint8_t messageContent;
uint8_t serialCurrent;
int initialCounter = 0;
boolean messageBegun = false;
boolean messageInProgress = false;
int currNumRefresh = 0;
int currMicroC = 0;
int currMicroD = 0;
int currMicroE = 0;
int currPressureC = 0;
int currPressureD = 0;
int currPressureE = 0;
int currValveStatusNumC = 0;
int currValveStatusNumD = 0;
int currValveStatusNumE = 0;
int currFluid = 0;
char statusbuf[256];
char status[] = "";
int statusIndex = 0;
String valveStatusC = "Closed";
String valveTubePropsC = "175px solid #00ADEF";
String valveColorC = "red";
String valveStatusD = "Closed";
String valveTubePropsD = "175px solid #00ADEF";
String valveColorD = "red";
String valveStatusE = "Closed";
String valveTubePropsE = "175px solid #00ADEF";
String valveColorE = "red";
uint8_t currCountdown = 0;
long prevTimeCountdown = 0;
long countdownInterval = 1000;
long countdownPostInterval = 100;
bool countdownFlag = true;
bool teensyPOWER = false;
bool pumpPOWER = false;
bool teensyLED = false;
void switchPOWERon() {
//Serial.println("TEST POWER ON");
int powerStatusLength = 1;
subsys = 0x10;
//Account for the end of message
messageLength = powerStatusLength + 2;
messageContent = 1;
Serial.write(som);
Serial.write(messageLength);
Serial.write(subsys);
Serial.write(messageContent);
Serial.write(eom);
//Serial.println("");
//Serial.println("TURN POWER ON|");
//teensyLED = true;
} //end switchPOWERon
void switchPOWERoff() {
/*Very similar to switchPoweron(), removed for char space*/
} //end switchPOWERoff
void pumpPOWERon() {
//Serial.println("TEST POWER ON");
int pumpPowerStatusLength = 1;
subsys = 0x13;
//Account for the end of message
messageLength = pumpPowerStatusLength + 2;
messageContent = 1;
Serial.write(som);
Serial.write(messageLength);
Serial.write(subsys);
Serial.write(messageContent);
Serial.write(eom);
//Serial.println("");
//Serial.println("TURN POWER ON|");
//teensyLED = true;
} //end switchPOWERon
void pumpPOWERoff() {
/*Very similar to pumpPoweron(), removed for char space*/
} //end switchPOWERoff
void switchLEDon() {
//Serial.println("TEST LED ON");
int ledStatusLength = 1;
subsys = 0x14;
//Account for the end of message
messageLength = ledStatusLength + 2;
messageContent = 1;
Serial.write(som);
Serial.write(messageLength);
Serial.write(subsys);
Serial.write(messageContent);
Serial.write(eom);
//Serial.println("");
//Serial.println("TURN LED ON|");
//teensyLED = true;
} //end switchLEDon
void switchLEDoff() {
/*Very similar to switchLEDon(), removed for char space*/
} //end switchLEDoff
void statusUpdate(uint8_t num) {
//Valve C
if(currValveStatusNumC == 0)
{
valveColorC = "red";
valveTubePropsC = "175px solid #00ADEF";
valveStatusC = "Closed";
} //end if
else if(currValveStatusNumC == 1)
{
valveColorC = "green";
valveTubePropsC = "350px solid #00ADEF";
valveStatusC = "Open";
} //end else if
/*Valves D/E removed for char space, very similar to Valve C*/
String test = "";
test += currNumRefresh;
test += ",";
/*Preparing more variables to send to the webpage, removed for char space*/
test += ",";
test += ipAddressTest;
//Serial.print("TEST: ");
//Serial.println(ipAddressTest);
test.toCharArray(statusbuf, 256);
webSocket.sendTXT(num, statusbuf, strlen(statusbuf));
}
static const char PROGMEM INDEX_HTML[] = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<title>Adafruit HUZZAH ESP8266</title>
<style type='text/css'>
/*CSS removed to fit maximum number of allowed characters*/
</style>
<script>
var currPressureTest = 0;
var currFluidTest = 0;
function POWERswitch(){
var POWERswitchCheck = document.getElementById('switch1').checked;
if(POWERswitchCheck){
websock.send("teensyPOWERon");
}
else if(!POWERswitchCheck) {
websock.send("teensyPOWERoff");
}
}
function FLUSHbegin(){
websock.send("pumpPOWERon");
}
function FLUSHend(){
websock.send("pumpPOWERoff");
}
function LEDswitch(){
var LEDswitchCheck = document.getElementById('myonoffswitch').checked;
if(LEDswitchCheck){
websock.send("teensyLEDon");
}
else if(!LEDswitchCheck) {
websock.send("teensyLEDoff");
}
}
var websock;
var test = "open";
var webpageHitCounter = 20;
function start() {
websock = new WebSocket('ws://' + window.location.hostname + ':81/');
websock.onopen = function(evt) {
console.log('websock open');
statusUpdate();
};
websock.onclose = function(evt) {
console.log('websock close');
};
websock.onerror = function(evt) {
console.log(evt);
};
websock.onmessage = function(evt) {
console.log(evt);
var e = document.getElementById('ledstatus');
var te = document.getElementById('myonoffswitch');
var pe = document.getElementById('switch1');
if(evt.data === 'teensyPOWERon')
{
pe.checked = 'checked';
}
else if(evt.data === 'teensyPOWERoff')
{
pe.checked = '';
}
else if(evt.data === 'pumpPOWERon')
{
}
else if(evt.data === 'pumpPOWERoff')
{
}
else if(evt.data === 'teensyLEDon')
{
te.checked = 'checked';
}
else if(evt.data === 'teensyLEDoff')
{
te.checked = '';
}
else if(evt.data === 'Update Status')
{
}
else {
console.log('status event');
var totalStatus = evt.data;
var splitStatus = totalStatus.split(',');
//Num Refresh
document.getElementById("demo").innerHTML = splitStatus[0];
/*Setting more variables from splitStatus[], removed for char space*/
}
};
}
function statusUpdate() {
websock.send("Update Status");
setTimeout('statusUpdate()', 5000);
}
</script>
</head>
<body style='background-color:#4a4a4c;' onload="start();">
<div style='text-align:center;'>
<h1 style='text-decoration: underline; color:white;'>Adafruit HUZZAH ESP8266</h1>
</div>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<div style="clear:both;"></div>
<div class='counterContainer'>
<span id="counterText" style="color:white;"></span>
</div>
<div id='adminControls' class='adminControlsRow'>
<h2>Administrator Controls</h2>
<div id='Newbtn' class='powerSwitchContainer'>
<h2>HHIO PTT Power</h2>
<span class="switch">
<span class="switch-border1">
<span class="switch-border2">
<input id="switch1" type="checkbox" onclick='POWERswitch()' checked />
<label for="switch1"></label>
<span class="switch-top"></span>
<span class="switch-shadow"></span>
<span class="switch-handle"></span>
<span class="switch-handle-left"></span>
<span class="switch-handle-right"></span>
<span class="switch-handle-top"></span>
<span class="switch-handle-bottom"></span>
<span class="switch-handle-base"></span>
<span class="switch-led switch-led-green">
<span class="switch-led-border">
<span class="switch-led-light">
<span class="switch-led-glow"></span>
</span>
</span>
</span>
<span class="switch-led switch-led-red">
<span class="switch-led-border">
<span class="switch-led-light">
<span class="switch-led-glow"></span>
</span>
</span>
</span>
</span>
</span>
</span>
</div>
<div class='flushBtnContainer'>
<h2>Fluid Reservoir</h2>
<button id='flushBtn' onmousedown="FLUSHbegin();" onmouseup="FLUSHend();">Flush</button>
</div>
</div>
<div style='background-color:#1E1E20; clear:both;'>
<h2 style='color: white;'>LED Controls</h2>
<div id='LEDbtn' class='onoffswitch'>
<input type='checkbox' name='onoffswitch' class='onoffswitch-checkbox' id='myonoffswitch' onclick='LEDswitch()'>
<label class='onoffswitch-label' for='myonoffswitch'>
<span class='onoffswitch-inner'></span>
<span class='onoffswitch-switch'></span>
</label>
</div>
</div>
<div style='background-color:#1E1E20; color: white;'>
<h2>Num Refresh Test</h2>
<div id="demo"><h2>Let WEBSOCKET change this text</h2></div>
</div>
<div class='headerRow'>
/*Headers removed for char space*/
</div>
<div class='microswitchRow'>
<div class="microswitchContainer">
<div class="microswitch white">
<input type="radio" name="switchC" class="microswitchRadio" id="switchOffC" checked>
<input type="radio" name="switchC" class="microswitchRadio" id="switchOnC">
<label for="switchOffC">Detached</label>
<label for="switchOnC">Attached</label>
<span class="toggle"></span>
</div>
</div>
<div class="microswitchContainer">
<div class="microswitch white">
<input type="radio" name="switchD" class="microswitchRadio" id="switchOffD" checked>
<input type="radio" name="switchD" class="microswitchRadio" id="switchOnD">
<label for="switchOffD">Detached</label>
<label for="switchOnD">Attached</label>
<span class="toggle"></span>
</div>
</div>
<div class="microswitchContainer">
<div class="microswitch white">
<input type="radio" name="switchE" class="microswitchRadio" id="switchOffE" checked>
<input type="radio" name="switchE" class="microswitchRadio" id="switchOnE">
<label for="switchOffE">Detached</label>
<label for="switchOnE">Attached</label>
<span class="toggle"></span>
</div>
</div>
</div>
<div class='pressureRow'>
<div class='pressureContainer'>
<div class='gauge-a'></div>
<div class='gauge-b'></div>
<div class='gauge-c'></div>
<div class='gauge-data'><h1 id='pressurePercentC'>0%</h1></div>
</div>
<div class='pressureContainer'>
<div class='gauge-a'></div>
<div class='gauge-b'></div>
<div class='gauge-d'></div>
<div class='gauge-data'><h1 id='pressurePercentD'>0%</h1></div>
</div>
<div class='pressureContainer'>
<div class='gauge-a'></div>
<div class='gauge-b'></div>
<div class='gauge-e'></div>
<div class='gauge-data'><h1 id='pressurePercentE'>0%</h1></div>
</div>
</div>
<div class='valveRow'>
<div class='valveContainer'>
<div class="valveTube-c"></div>
<div class="valve-c"></div>
<div class='valve-data'><h1 id='valveStatus-c'>Closed</h1></div>
</div>
<div class='valveContainer'>
<div class="valveTube-d"></div>
<div class="valve-d"></div>
<div class='valve-data'><h1 id='valveStatus-d'>Closed</h1></div>
</div>
<div class='valveContainer'>
<div class="valveTube-e"></div>
<div class="valve-e"></div>
<div class='valve-data'><h1 id='valveStatus-e'>Closed</h1></div>
</div>
</div>
<div class='fluidContainer'>
<meter class='fluidMeter' max='100' value='50' low='25' high='75' optimum='100'></meter>
<div class='fluid-data'><h1 id='fluidPercent'>0%</h1></div>
</div>
</body>
</html>
)rawliteral";
const int LEDPIN = 0;
// Current POWER status
bool POWERStatus;
// Current LED status
bool LEDStatus;
// Commands sent through Web Socket
/*command array declarations removed for char space*/
const char statusIdentifier[] = "Update Status";
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
//Serial.printf("webSocketEvent(%d, %d, ...)\r\n", num, type);
switch(type) {
case WStype_DISCONNECTED:
//Serial.printf("[%u] Disconnected!\r\n", num);
break;
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(num);
//Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\r\n", num, ip[0], ip[1], ip[2], ip[3], payload);
// Send the current LED status
if (LEDStatus) {
webSocket.sendTXT(num, LEDON, strlen(LEDON));
}
else if(!LEDStatus) {
webSocket.sendTXT(num, LEDOFF, strlen(LEDOFF));
}
else if(teensyPOWER) {
webSocket.sendTXT(num, teensyPOWERON, strlen(teensyPOWERON));
}
else if(!teensyPOWER) {
webSocket.sendTXT(num, teensyPOWEROFF, strlen(teensyPOWEROFF));
}
else if(pumpPOWER) {
webSocket.sendTXT(num, teensyPOWERON, strlen(teensyPOWERON));
}
else if(!pumpPOWER) {
webSocket.sendTXT(num, pumpPOWEROFF, strlen(pumpPOWEROFF));
}
else if(teensyLED) {
webSocket.sendTXT(num, teensyLEDON, strlen(teensyLEDON));
}
else if(!teensyLED) {
webSocket.sendTXT(num, teensyLEDOFF, strlen(teensyLEDOFF));
}
}
break;
case WStype_TEXT:
//Serial.printf("[%u] get Text: %s\r\n", num, payload);
if (strcmp(LEDON, (const char *)payload) == 0) {
writeLED(true);
}
else if (strcmp(LEDOFF, (const char *)payload) == 0) {
writeLED(false);
}
else if(strcmp(teensyPOWERON, (const char *)payload) == 0) {
switchPOWERon();
}
else if(strcmp(teensyPOWEROFF, (const char *)payload) == 0) {
switchPOWERoff();
}
else if(strcmp(pumpPOWERON, (const char *)payload) == 0) {
pumpPOWERon();
}
else if(strcmp(pumpPOWEROFF, (const char *)payload) == 0) {
pumpPOWERoff();
}
else if(strcmp(teensyLEDON, (const char *)payload) == 0) {
switchLEDon();
}
else if(strcmp(teensyLEDOFF, (const char *)payload) == 0) {
switchLEDoff();
}
else if(strcmp(statusIdentifier, (const char *)payload) == 0) {
statusUpdate(num);
}
else {
//Serial.println("Unknown command");
}
// send data to all connected clients
webSocket.broadcastTXT(payload, length);
break;
case WStype_BIN:
//Serial.printf("[%u] get binary length: %u\r\n", num, length);
hexdump(payload, length);
// echo data back to browser
webSocket.sendBIN(num, payload, length);
break;
default:
//Serial.printf("Invalid WStype [%d]\r\n", type);
break;
}
}
void handleRoot()
{
server.send(200, "text/html", INDEX_HTML);
if(ipAddressTest != (0,0,0,0))
{
if(ipAddressOne == (99,99,99,99))
{
ipAddressOne = ipAddressTest;
pageHitCounter++;
//server.send(200, "text/html", INDEX_HTML);
Serial.print("1st NEW IP: ");
Serial.println(ipAddressTest);
}
else if(ipAddressTwo == (99,99,99,99))
{
if(ipAddressOne == ipAddressTest)
{
Serial.print("Old Connection-1 currently connected; Current Connection: ");
Serial.println(ipAddressTest);
//server.send(200, "text/html", INDEX_HTML);
}
else
{
ipAddressTwo = ipAddressTest;
pageHitCounter++;
//server.send(200, "text/html", INDEX_HTML);
Serial.print("2nd NEW IP: ");
Serial.println(ipAddressTest);
}
}
else if(ipAddressThree == (99,99,99,99))
{
if(ipAddressOne == ipAddressTest || ipAddressTwo == ipAddressTest)
{
Serial.print("Old Connection-2 currently connected; Current Connection: ");
Serial.println(ipAddressTest);
//server.send(200, "text/html", INDEX_HTML);
}
else
{
ipAddressThree = ipAddressTest;
pageHitCounter++;
//server.send(200, "text/html", INDEX_HTML);
Serial.print("3rd NEW IP: ");
Serial.println(ipAddressTest);
}
}
else if(ipAddressFour == (99,99,99,99))
{
if(ipAddressOne == ipAddressTest || ipAddressTwo == ipAddressTest || ipAddressThree == ipAddressTest)
{
Serial.println("Old Connection-3 currently connected; Current Connection: ");
Serial.println(ipAddressTest);
//server.send(200, "text/html", INDEX_HTML);
}
else
{
ipAddressFour = ipAddressTest;
pageHitCounter++;
//server.send(200, "text/html", INDEX_HTML);
Serial.print("4th NEW IP: ");
Serial.println(ipAddressTest);
}
}
else
{
if(ipAddressOne == ipAddressTest || ipAddressTwo == ipAddressTest || ipAddressThree == ipAddressTest || ipAddressFour == ipAddressTest)
{
Serial.println("Old Connection-4 currently connected; Current Connection: ");
Serial.println(ipAddressTest);
//server.send(200, "text/html", INDEX_HTML);
}
else
{
Serial.print("Too many connections! Attempting to Connect: ");
Serial.println(ipAddressTest);
}
}
}
}
void handleNotFound()
{
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i=0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}
static void writeLED(bool LEDon)
{
LEDStatus = LEDon;
// Note inverted logic for Adafruit HUZZAH board
if (LEDon) {
digitalWrite(LEDPIN, 0);
}
else {
digitalWrite(LEDPIN, 1);
}
}
void setup()
{
pinMode(LEDPIN, OUTPUT);
writeLED(false);
Serial.begin(115200);
//Serial.setDebugOutput(true);
Serial.println();
Serial.println();
Serial.println();
currCountdown = 4;
for(uint8_t t = 4; t > 0; t--) {
unsigned long currTime = millis();
if(countdownFlag == true)
{
Serial.printf("[SETUP] BOOT WAIT %d...\r\n", t);
Serial.flush();
countdownFlag = false;
}
if(currTime - prevTimeCountdown > countdownInterval)
{
prevTimeCountdown = currTime;
countdownFlag = true;
} //end if
else
{
t++;
} //end else
} //end for
WiFiMulti.addAP(ssid, password);
/*
prevTimeCountdown = 0;
countdownFlag = true;
*/
while(WiFiMulti.run() != WL_CONNECTED) {
/*
unsigned long currTime = millis();
if(countdownFlag == true)
{
Serial.print(".");
countdownFlag = false;
} //end if
if(currTime - prevTimeCountdown > countdownInterval)
{
prevTimeCountdown = currTime;
countdownFlag = true;
} //end if
*/
Serial.print(".");
delay(1000);
} //end while
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (mdns.begin("espWebSock", WiFi.localIP())) {
Serial.println("MDNS responder started");
mdns.addService("http", "tcp", 80);
mdns.addService("ws", "tcp", 81);
}
else {
Serial.println("MDNS.begin failed");
}
Serial.print("Connect to http://espWebSock.local or http://");
Serial.println(WiFi.localIP());
server.on("/", handleRoot);
server.onNotFound(handleNotFound);
server.begin();
webSocket.begin();
webSocket.onEvent(webSocketEvent);
}
void loop()
{
//Communication Protocol
if(Serial.available() > 0)
{
//Serial.print("SERIAL.AVAILABLE: ");
//Serial.println(Serial.available());
if(initialCounter == 0)
{
rx_byte = Serial.read();
/*
//Print Start of Message
Serial.print("0x");
if(rx_byte<0x10)
{
Serial.print("0");
}
Serial.println(rx_byte, HEX);
*/
//Serial.println(rx_byte, BIN);
//Serial.println(rx_byte);
initialCounter++;
}
if((!messageBegun) && (rx_byte == som))
{
messageBegun = true;
//Serial.println("MESSAGE BEGUN TRUE");
} //end if (messageInProgress && rx_byte)
if((messageBegun) && (!messageInProgress))
{
serialCurrent = Serial.available();
if(serialCurrent > 0)
{
receivedMessageLength = (uint8_t)Serial.read();
/*
Serial.print("MESSAGE LENGTH: ");
Serial.println(receivedMessageLength);
*/
messageBegun = false;
messageInProgress = true;
//Serial.println("MESSAGE IN PROGRESS TRUE");
} //end if (serialCurrent)
} //end if (messageBegun && messageInProgress)
if(messageInProgress)
{
serialCurrent = Serial.available();
if(serialCurrent >= receivedMessageLength)
{
Serial.readBytes(rxBuff, receivedMessageLength);
if((byte)rxBuff[receivedMessageLength-1] != eom)
{
//Serial.println("ERROR");
//Serial.write(Serial.read());
} //end if (rxBuff != eom)
else
{
messageInProgress = false;
for(int i=0; i<receivedMessageLength; i++)
{
if(rxBuff[i] == eom)
{
/*
//Print End of Message
Serial.print("0x");
if(rx_byte<0x10)
{
Serial.print("0");
}
Serial.println(rxBuff[i], HEX);
*/
initialCounter = 0;
receivedMessageLength = 0;
} //end if
else if(i == 0)
{
receivedSubsys = rxBuff[i];
/*
//Print Subsystem
Serial.print("0x");
if(rx_byte<0x10)
{
Serial.print("0");
}
Serial.println(rxBuff[i], HEX);
*/
} //end if
else
{
if(receivedSubsys == 0x14)
{
currNumRefresh = rxBuff[i];
} //end if
/*Other subsystems removed for char space*/
} //end else
} //end if (serialCurrent)
} //end if (messageInProgress)
} //end if (Serial.available)
webSocket.loop();
ipAddressTest = server.handleClient();
}
P.S. I slightly modified ESP8266WebServer.cpp's handleClient() function to return the current IP address in order to track individual users, however sometimes I get 0.0.0.0 as an IP address and I don't know why or how to tell if that IP is a new IP or not.
I think Espressif documentation suggests a max of 5 UDP/TCP connections, that's what everyone always mentions anyways. I'd look it up but I'm behind a firewall right now :)
You don't mention which environment you are using, but I'm guessing Arduino based.
I don't know why you hit a limit at 3 instead of 5, could it be you're using connections for other protocols? I'm not sure what the MDNS stuff does, so maybe something in that. Also your browser could possibly be opening more connections then you expect (debug with browser debug functionality, e.g. f12? on most).
As usual, minimizing your code to the smallest example will help, try just the webserver, and see if you get closer to 5 :)
you must be careful with the size of the files you upload with FS.h. depending on the size some problems are generated when generating the page
Alright so I seem to have solved the issue by using the FS.h library and having an actual filesystem with directories where I can have actual html/css/js files and what not. This seems to have solved the stability issues.
Related
I have tried first google translation in larvel [
Full Name الاسم الكامل
(Required)
-->
<input type="text" class="form-control" dir="rtl" v-model="text1" #keyup="arabicValue( text1)" id= "text1">
arabicValue: function(txt,text1) {
console.log(txt + "txt");
let char;
// char = txt.value;
char = txt;
console.log(char + "in");
char = char.replace(/`/g, "ذ");
char = char.replace(/0/g, "۰");
char = char.replace(/1/g, "۱");
char = char.replace(/2/g, "۲");
char = char.replace(/3/g, "۳");
char = char.replace(/4/g, "٤");
char = char.replace(/5/g, "۵");
char = char.replace(/6/g, "٦");
char = char.replace(/7/g, "۷");
char = char.replace(/8/g, "۸");
char = char.replace(/9/g, "۹");
char = char.replace(/0/g, "۰");
char = char.replace(/q/g, "ف");
char = char.replace(/w/g, "ث");
char = char.replace(/e/g, "ه");
char = char.replace(/r/g, "ص");
char = char.replace(/t/g, "ط");
char = char.replace(/y/g, "ذ");
char = char.replace(/u/g, "ش");
char = char.replace(/i/g, "أنا");
char = char.replace(/o/g, "ا");
char = char.replace(/p/g, "ص");
char = char.replace(/\[/g, "ج");
char = char.replace(/\]/g, "د");
char = char.replace(/a/g, "أ");
char = char.replace(/s/g, "س");
char = char.replace(/d/g, "د");
char = char.replace(/f/g, "ب");
char = char.replace(/g/g, "ز");
char = char.replace(/h/g, "ح");
char = char.replace(/j/g, "ي");
char = char.replace(/k/g, "ك");
char = char.replace(/l/g, "ل");
char = char.replace(/\;/g, "ك");
char = char.replace(/\'/g, "ط");
char = char.replace(/z/g, "ض");
char = char.replace(/x/g, "ء");
char = char.replace(/c/g, "ج");
char = char.replace(/v/g, "الخامس");
char = char.replace(/b/g, "ب");
char = char.replace(/n/g, "ن");
char = char.replace(/m/g, "م");
char = char.replace(/\,/g, "و");
char = char.replace(/\./g, "ز");
char = char.replace(/\//g, "ظ");
char = char.replace(/~/g, " ّ");
char = char.replace(/Q/g, "َ");
char = char.replace(/W/g, "ً");
char = char.replace(/E/g, "ُ");
char = char.replace(/R/g, "ٌ");
char = char.replace(/T/g, "ط");
char = char.replace(/Y/g, "إ");
char = char.replace(/U/g, "‘");
char = char.replace(/I/g, "÷");
char = char.replace(/O/g, "×");
char = char.replace(/P/g, "؛");
char = char.replace(/A/g, "ِ");
char = char.replace(/S/g, "ٍ");
char = char.replace(/G/g, "لأ");
// char = char.replace(/H/g, "أ");
char = char.replace(/J/g, "ـ");
char = char.replace(/K/g, "،");
char = char.replace(/L/g, "/");
char = char.replace(/Z/g, "~");
char = char.replace(/X/g, "ْ");
char = char.replace(/B/g, "لآ");
char = char.replace(/N/g, "آ");
char = char.replace(/M/g, "’");
char = char.replace(/\?/g, "؟");
text1 = char;
this.text1 = text1;
console.log(text1 + "after");
}`enter code here`
]1and then also tried char replacement in arabic from english on user input and problem is there is no right conversion from english to arabic.is there any way to get exact right arabic characters on user input.
PHP:
For Numbers:
$inputNumbers = $numbers;
$arabic_numbers = ['٩', '٨', '٧', '٦', '٥', '٤', '٣', '٢', '١','٠'];
$num = range(0, 9);
$arabic_numbers_output = str_replace($arabic_numbers , $num, $inputNumbers);
For Letters:
$inputText = $text;
$arabic_letters = ['آ', 'ب', 'ج']; // and so on ...
$letters = ['A', 'B', 'J']; // and so on ...
$arabic_letters_output = str_replace($arabic_letters , $letters , $inputText);
JS:
For Numbers:
String.prototype.toArabicDigit= function()
{
var id= ['۰','۱','۲','۳','۴','۵','۶','۷','۸','۹'];
return this.replace(/[0-9]/g, function(w){ return id[+w] });
}
var en_number = "0123456789";
alert(en_number.toArabicDigit());
For Letters:
(This is for Farsi but you can modify it to match with Arabic)
if (typeof HTMLElement!="undefined" && ! HTMLElement.prototype.insertAdjacentElement) {
HTMLElement.prototype.insertAdjacentElement = function (where,parsedNode) {
switch (where) {
case 'beforeBegin':
this.parentNode.insertBefore(parsedNode,this)
break;
case 'afterBegin':
this.insertBefore(parsedNode,this.firstChild);
break;
case 'beforeEnd':
this.appendChild(parsedNode);
break;
case 'afterEnd':
if (this.nextSibling)
this.parentNode.insertBefore(parsedNode,this.nextSibling);
else
this.parentNode.appendChild(parsedNode);
break;
}
}
HTMLElement.prototype.insertAdjacentHTML = function (where,htmlStr) {
var r = this.ownerDocument.createRange();
r.setStartBefore(this);
var parsedHTML = r.createContextualFragment(htmlStr);
this.insertAdjacentElement(where,parsedHTML)
}
HTMLElement.prototype.insertAdjacentText = function (where,txtStr) {
var parsedText = document.createTextNode(txtStr)
this.insertAdjacentElement(where,parsedText)
}
}
var FarsiType = {
// Farsi keyboard map based on Iran Popular Keyboard Layout
farsiKey: [
32, 33, 34, 35, 36, 37, 1548, 1711,
41, 40, 215, 43, 1608, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 1705, 44, 61, 46, 1567,
64, 1616, 1584, 125, 1609, 1615, 1609, 1604,
1570, 247, 1600, 1548, 47, 8217, 1583, 215,
1563, 1614, 1569, 1613, 1601, 8216, 123, 1611,
1618, 1573, 126, 1580, 1688, 1670, 94, 95,
1662, 1588, 1584, 1586, 1740, 1579, 1576, 1604,
1575, 1607, 1578, 1606, 1605, 1574, 1583, 1582,
1581, 1590, 1602, 1587, 1601, 1593, 1585, 1589,
1591, 1594, 1592, 60, 124, 62, 1617
],
Type: true,
counter: 0,
ShowChangeLangButton: 1, // 0: Hidden / 1: Visible
KeyBoardError: 0, // 0: Disable FarsiType / 1: Show Error
ChangeDir: 2, // 0: No Action / 1: Do Rtl-Ltr / 2: Rtl-Ltr button
UnSupportedAction: 0 //0: Disable FarsiType / 1: Low Support
}
FarsiType.enable_disable = function(Dis) {
var invis, obj;
if (!Dis.checked) {
FarsiType.Type = true;
disable = false;
color = 'darkblue';
} else {
FarsiType.Type = false;
disable = true;
color = '#ECE9D8';
}
if (FarsiType.ShowChangeLangButton == 1) {
for (var i=1; i<= FarsiType.counter; i++) {
obj = document.getElementById('FarsiType_button_' + i);
obj.disabled = disable;
obj.style.backgroundColor = color;
}
}
}
FarsiType.Disable = function() {
FarsiType.Type = false;
var Dis = document.getElementById('disableFarsiType')
if (Dis != null) {
Dis.checked = true;
}
if (FarsiType.ShowChangeLangButton == 1) {
for (var i=1; i<= FarsiType.counter; i++) {
obj = document.getElementById('FarsiType_button_' + i);
obj.disabled = true;
obj.style.backgroundColor = '#ECE9D8';
}
}
}
FarsiType.init = function() {
var Inputs = document.getElementsByTagName('INPUT');
for (var i=0; i<Inputs.length; i++) {
if (Inputs[i].type.toLowerCase() == 'text' && (Inputs[i].lang.toLowerCase() == 'fa' || Inputs[i].lang.toLowerCase() == 'fa-ir')) {
FarsiType.counter++;
new FarsiType.KeyObject(Inputs[i], FarsiType.counter);
}
}
var Areas = document.getElementsByTagName('TEXTAREA');
for (var i=0; i<Areas.length; i++) {
if (Areas[i].lang.toLowerCase() == 'fa' || Areas[i].lang.toLowerCase() == 'fa-ir') {
FarsiType.counter++;
new FarsiType.KeyObject(Areas[i], FarsiType.counter);
}
}
var Dis = document.getElementById('disableFarsiType')
if (Dis != null) {
FarsiType.enable_disable (Dis);
Dis.onclick = new Function( "FarsiType.enable_disable (this);" )
}
}
FarsiType.KeyObject = function(z,x) {
GenerateStr = "";
if (FarsiType.ShowChangeLangButton == 1) {
GenerateStr = GenerateStr + "<input type='button' id=FarsiType_button_"+x+" style='border: none; background-color:darkblue; font-size:11; color:white; font-family:tahoma; padding: 1px; margin: 1px; width: auto; height: auto;' value='FA' /> ";
}
if (FarsiType.ChangeDir == 2) {
GenerateStr = GenerateStr + "<input type='button' id=FarsiType_ChangeDir_"+x+" style='border: none; background-color:darkblue; font-size:11; color:white; font-family:tahoma; padding: 1px; margin: 1px; width: auto; height: auto;' value='RTL' />"
}
z.insertAdjacentHTML("afterEnd", GenerateStr);
if (FarsiType.ShowChangeLangButton == 1) {
z.bottelm = document.getElementById ('FarsiType_button_' + x);
z.bottelm.title = 'Change lang to english';
}
if (FarsiType.ChangeDir == 2) {
z.Direlm = document.getElementById ('FarsiType_ChangeDir_' + x);
}
z.farsi = true;
z.dir = "rtl";
z.align = "right";
z.style.textAlign = z.align;
z.style.direction = z.dir;
setSelectionRange = function(input, selectionStart, selectionEnd) {
input.focus()
input.setSelectionRange(selectionStart, selectionEnd)
}
ChangeDirection = function() {
if (z.dir == "rtl") {
z.dir = "ltr";
z.align = "left";
z.Direlm.value = "LTR";
z.Direlm.title = "Change direction: Right to Left"
} else {
z.dir = "rtl";
z.align = "right";
z.Direlm.value = "RTL";
z.Direlm.title = "Change direction: Left to Right"
}
z.style.textAlign = z.align;
z.style.direction = z.dir;
z.focus();
}
ChangeLang = function(e, ze) {
if(ze)
z = ze;
if (FarsiType.Type) {
if (z.farsi) {
z.farsi = false;
if (FarsiType.ShowChangeLangButton == 1) {
z.bottelm.value = "EN";
z.bottelm.title = 'Change lang to persian';
}
if (FarsiType.ChangeDir == 1) {
z.style.textAlign = "left";
z.style.direction = "ltr";
}
} else {
z.farsi = true;
if (FarsiType.ShowChangeLangButton == 1) {
z.bottelm.value = "FA";
z.bottelm.title = 'Change lang to english';
}
if (FarsiType.ChangeDir == 1) {
z.style.textAlign = "right";
z.style.direction = "rtl";
}
}
z.focus();
}
if (e.preventDefault) e.preventDefault();
e.returnValue = false;
return false;
}
Convert = function(e) {
if (e == null)
e = window.event;
var key = e.which || e.charCode || e.keyCode;
var eElement = e.target || e.originalTarget || e.srcElement;
if (e.ctrlKey && key == 32) {
ChangeLang(e, z);
}
if (FarsiType.Type) {
if (
(e.charCode != null && e.charCode != key) ||
(e.which != null && e.which != key) ||
(e.ctrlKey || e.altKey || e.metaKey) ||
(key == 13 || key == 27 || key == 8)
) return true;
//check windows lang
if (key > 128) {
if (FarsiType.KeyBoardError == 0) {
FarsiType.Disable();
} else {
alert("Please change your windows language to English");
return false;
}
}
// If Farsi
if (FarsiType.Type && z.farsi) {
//check CpasLock
if ((key >= 65 && key <= 90&& !e.shiftKey) || (key >= 97 && key <= 122 ) && e.shiftKey) {
alert("Caps Lock is On. To prevent entering farsi incorrectly, you should press Caps Lock to turn it off.");
return false;
}
// Shift-space -> ZWNJ
if (key == 32 && e.shiftKey)
key = 8204;
else
key = FarsiType.farsiKey[key-32];
key = typeof key == 'string' ? key : String.fromCharCode(key);
// to farsi
try {
var docSelection = document.selection;
var selectionStart = eElement.selectionStart;
var selectionEnd = eElement.selectionEnd;
if (typeof selectionStart == 'number') {
//FOR W3C STANDARD BROWSERS
var nScrollTop = eElement.scrollTop;
var nScrollLeft = eElement.scrollLeft;
var nScrollWidth = eElement.scrollWidth;
eElement.value = eElement.value.substring(0, selectionStart) + key + eElement.value.substring(selectionEnd);
setSelectionRange(eElement, selectionStart + key.length, selectionStart + key.length);
var nW = eElement.scrollWidth - nScrollWidth;
if (eElement.scrollTop == 0) { eElement.scrollTop = nScrollTop }
} else if (docSelection) {
var nRange = docSelection.createRange();
nRange.text = key;
nRange.setEndPoint('StartToEnd', nRange);
nRange.select();
}
} catch(error) {
try {
// IE
e.keyCode = key
} catch(error) {
try {
// OLD GECKO
e.initKeyEvent("keypress", true, true, document.defaultView, false, false, true, false, 0, key, eElement);
} catch(error) {
//OTHERWISE
if (FarsiType.UnSupportedAction == 0) {
alert('Sorry! no FarsiType support')
FarsiType.Disable();
var Dis = document.getElementById('disableFarsiType')
if (Dis != null) {
Dis.disabled = true;
}
return false;
} else {
eElement.value += key;
}
}
}
}
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
}
return true;
}
if (FarsiType.ShowChangeLangButton == 1) { z.bottelm.onmouseup = ChangeLang; }
if (FarsiType.ChangeDir == 2) { z.Direlm.onmouseup = ChangeDirection; }
z.onkeypress = Convert;
}
if (window.attachEvent) {
window.attachEvent('onload', FarsiType.init)
} else if (window.addEventListener) {
window.addEventListener('load', FarsiType.init, false)
}
I've an ESP32-cam and want to controll a servo. My code compiled without error but doesn't work.
There are two files involved, a .ino and a .cpp. The .ino seems to work right because the servo contributes to his start position 90° at startup but When i want to turn it right or left, nothing happens. This part is controlled in the .cpp and i've spend a lot of time to figure out what went wrong here without success. Any help is highly appreciated.
.ino
#include "esp_camera.h"
#include <WiFiMulti.h>
#include <Servo.h>
Servo myservo;
WiFiMulti wifiMulti;
int ledPin = 4;
#define CAMERA_MODEL_AI_THINKER
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
// GPIO Setting
int servoPin = 2;
int posDegrees = 90; //servo initial position 90°
int posDegreesStep = 30;
extern String WiFiAddr ="";
void startCameraServer();
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
Serial.println();
myservo.attach(servoPin, 2, 0, 180); //(pin, channel, min, max) degrees
myservo.write(posDegrees);
pinMode(servoPin , OUTPUT );
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
//init with high specs to pre-allocate larger buffers
if(psramFound()){
config.frame_size = FRAMESIZE_SXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
//drop down frame size for higher initial frame rate
sensor_t * s = esp_camera_sensor_get();
s->set_framesize(s, FRAMESIZE_CIF);
wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1");
wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_2");
//wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3");
Serial.println("Connecting Wifi...");
if (wifiMulti.run() == WL_CONNECTED) {
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
}
startCameraServer();
Serial.print("Camera Ready!");
Serial.print(WiFi.localIP());
WiFiAddr = WiFi.localIP().toString();
Serial.println("' to connect");
}
void wifireconnect() {
if (wifiMulti.run() != WL_CONNECTED) {
Serial.println("WiFi not connected!");
delay(500);
WiFi.disconnect();
Serial.println("\nReboot");
ESP.restart();
}
}
void loop() {
wifireconnect();
}
.cpp
#include "esp_http_server.h"
#include "esp_timer.h"
#include "esp_camera.h"
#include "img_converters.h"
#include "camera_index.h"
#include "Arduino.h"
#include "Servo.h"
extern int servoPin;
extern int posDegrees;
extern int posDegreesStep;
extern String WiFiAddr;
typedef struct {
size_t size;
size_t index;
size_t count;
int sum;
int * values;
} ra_filter_t;
typedef struct {
httpd_req_t *req;
size_t len;
} jpg_chunking_t;
#define PART_BOUNDARY "123456789000000000000987654321"
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
static ra_filter_t ra_filter;
httpd_handle_t stream_httpd = NULL;
httpd_handle_t camera_httpd = NULL;
static ra_filter_t * ra_filter_init(ra_filter_t * filter, size_t sample_size) {
memset(filter, 0, sizeof(ra_filter_t));
filter->values = (int *)malloc(sample_size * sizeof(int));
if (!filter->values) {
return NULL;
}
memset(filter->values, 0, sample_size * sizeof(int));
filter->size = sample_size;
return filter;
}
static int ra_filter_run(ra_filter_t * filter, int value) {
if (!filter->values) {
return value;
}
filter->sum -= filter->values[filter->index];
filter->values[filter->index] = value;
filter->sum += filter->values[filter->index];
filter->index++;
filter->index = filter->index % filter->size;
if (filter->count < filter->size) {
filter->count++;
}
return filter->sum / filter->count;
}
static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size_t len) {
jpg_chunking_t *j = (jpg_chunking_t *)arg;
if (!index) {
j->len = 0;
}
if (httpd_resp_send_chunk(j->req, (const char *)data, len) != ESP_OK) {
return 0;
}
j->len += len;
return len;
}
static esp_err_t capture_handler(httpd_req_t *req) {
camera_fb_t * fb = NULL;
esp_err_t res = ESP_OK;
int64_t fr_start = esp_timer_get_time();
fb = esp_camera_fb_get();
if (!fb) {
Serial.printf("Camera capture failed");
httpd_resp_send_500(req);
return ESP_FAIL;
}
httpd_resp_set_type(req, "image/jpeg");
httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg");
size_t fb_len = 0;
if (fb->format == PIXFORMAT_JPEG) {
fb_len = fb->len;
res = httpd_resp_send(req, (const char *)fb->buf, fb->len);
} else {
jpg_chunking_t jchunk = {req, 0};
res = frame2jpg_cb(fb, 80, jpg_encode_stream, &jchunk) ? ESP_OK : ESP_FAIL;
httpd_resp_send_chunk(req, NULL, 0);
fb_len = jchunk.len;
}
esp_camera_fb_return(fb);
int64_t fr_end = esp_timer_get_time();
Serial.printf("JPG: %uB %ums", (uint32_t)(fb_len), (uint32_t)((fr_end - fr_start) / 1000));
return res;
}
static esp_err_t stream_handler(httpd_req_t *req) {
camera_fb_t * fb = NULL;
esp_err_t res = ESP_OK;
size_t _jpg_buf_len = 0;
uint8_t * _jpg_buf = NULL;
char * part_buf[64];
static int64_t last_frame = 0;
if (!last_frame) {
last_frame = esp_timer_get_time();
}
res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
if (res != ESP_OK) {
return res;
}
while (true) {
fb = esp_camera_fb_get();
if (!fb) {
Serial.printf("Camera capture failed");
res = ESP_FAIL;
} else {
if (fb->format != PIXFORMAT_JPEG) {
bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
esp_camera_fb_return(fb);
fb = NULL;
if (!jpeg_converted) {
Serial.printf("JPEG compression failed");
res = ESP_FAIL;
}
} else {
_jpg_buf_len = fb->len;
_jpg_buf = fb->buf;
}
}
if (res == ESP_OK) {
size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
}
if (res == ESP_OK) {
res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
}
if (res == ESP_OK) {
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
}
if (fb) {
esp_camera_fb_return(fb);
fb = NULL;
_jpg_buf = NULL;
} else if (_jpg_buf) {
free(_jpg_buf);
_jpg_buf = NULL;
}
if (res != ESP_OK) {
break;
}
int64_t fr_end = esp_timer_get_time();
int64_t frame_time = fr_end - last_frame;
last_frame = fr_end;
frame_time /= 1000;
uint32_t avg_frame_time = ra_filter_run(&ra_filter, frame_time);
//Serial.printf("MJPG: %uB %ums (%.1ffps), AVG: %ums (%.1ffps)"
// ,(uint32_t)(_jpg_buf_len),
// (uint32_t)frame_time, 1000.0 / (uint32_t)frame_time,
// avg_frame_time, 1000.0 / avg_frame_time
//);
}
last_frame = 0;
return res;
}
static esp_err_t cmd_handler(httpd_req_t *req) {
char* buf;
size_t buf_len;
char variable[32] = {0,};
char value[32] = {0,};
buf_len = httpd_req_get_url_query_len(req) + 1;
if (buf_len > 1) {
buf = (char*)malloc(buf_len);
if (!buf) {
httpd_resp_send_500(req);
return ESP_FAIL;
}
if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
if (httpd_query_key_value(buf, "var", variable, sizeof(variable)) == ESP_OK &&
httpd_query_key_value(buf, "val", value, sizeof(value)) == ESP_OK) {
} else {
free(buf);
httpd_resp_send_404(req);
return ESP_FAIL;
}
} else {
free(buf);
httpd_resp_send_404(req);
return ESP_FAIL;
}
free(buf);
} else {
httpd_resp_send_404(req);
return ESP_FAIL;
}
int val = atoi(value);
sensor_t * s = esp_camera_sensor_get();
int res = 0;
if (!strcmp(variable, "framesize")) {
if (s->pixformat == PIXFORMAT_JPEG) res = s->set_framesize(s, (framesize_t)val);
}
else if (!strcmp(variable, "quality")) res = s->set_quality(s, val);
else if (!strcmp(variable, "contrast")) res = s->set_contrast(s, val);
else if (!strcmp(variable, "brightness")) res = s->set_brightness(s, val);
else if (!strcmp(variable, "saturation")) res = s->set_saturation(s, val);
else if (!strcmp(variable, "gainceiling")) res = s->set_gainceiling(s, (gainceiling_t)val);
else if (!strcmp(variable, "colorbar")) res = s->set_colorbar(s, val);
else if (!strcmp(variable, "awb")) res = s->set_whitebal(s, val);
else if (!strcmp(variable, "agc")) res = s->set_gain_ctrl(s, val);
else if (!strcmp(variable, "aec")) res = s->set_exposure_ctrl(s, val);
else if (!strcmp(variable, "hmirror")) res = s->set_hmirror(s, val);
else if (!strcmp(variable, "vflip")) res = s->set_vflip(s, val);
else if (!strcmp(variable, "awb_gain")) res = s->set_awb_gain(s, val);
else if (!strcmp(variable, "agc_gain")) res = s->set_agc_gain(s, val);
else if (!strcmp(variable, "aec_value")) res = s->set_aec_value(s, val);
else if (!strcmp(variable, "aec2")) res = s->set_aec2(s, val);
else if (!strcmp(variable, "dcw")) res = s->set_dcw(s, val);
else if (!strcmp(variable, "bpc")) res = s->set_bpc(s, val);
else if (!strcmp(variable, "wpc")) res = s->set_wpc(s, val);
else if (!strcmp(variable, "raw_gma")) res = s->set_raw_gma(s, val);
else if (!strcmp(variable, "lenc")) res = s->set_lenc(s, val);
else if (!strcmp(variable, "special_effect")) res = s->set_special_effect(s, val);
else if (!strcmp(variable, "wb_mode")) res = s->set_wb_mode(s, val);
else if (!strcmp(variable, "ae_level")) res = s->set_ae_level(s, val);
else {
res = -1;
}
if (res) {
return httpd_resp_send_500(req);
}
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
return httpd_resp_send(req, NULL, 0);
}
static esp_err_t status_handler(httpd_req_t *req) {
static char json_response[1024];
sensor_t * s = esp_camera_sensor_get();
char * p = json_response;
*p++ = '{';
p += sprintf(p, "\"framesize\":%u,", s->status.framesize);
p += sprintf(p, "\"quality\":%u,", s->status.quality);
p += sprintf(p, "\"brightness\":%d,", s->status.brightness);
p += sprintf(p, "\"contrast\":%d,", s->status.contrast);
p += sprintf(p, "\"saturation\":%d,", s->status.saturation);
p += sprintf(p, "\"special_effect\":%u,", s->status.special_effect);
p += sprintf(p, "\"wb_mode\":%u,", s->status.wb_mode);
p += sprintf(p, "\"awb\":%u,", s->status.awb);
p += sprintf(p, "\"awb_gain\":%u,", s->status.awb_gain);
p += sprintf(p, "\"aec\":%u,", s->status.aec);
p += sprintf(p, "\"aec2\":%u,", s->status.aec2);
p += sprintf(p, "\"ae_level\":%d,", s->status.ae_level);
p += sprintf(p, "\"aec_value\":%u,", s->status.aec_value);
p += sprintf(p, "\"agc\":%u,", s->status.agc);
p += sprintf(p, "\"agc_gain\":%u,", s->status.agc_gain);
p += sprintf(p, "\"gainceiling\":%u,", s->status.gainceiling);
p += sprintf(p, "\"bpc\":%u,", s->status.bpc);
p += sprintf(p, "\"wpc\":%u,", s->status.wpc);
p += sprintf(p, "\"raw_gma\":%u,", s->status.raw_gma);
p += sprintf(p, "\"lenc\":%u,", s->status.lenc);
p += sprintf(p, "\"hmirror\":%u,", s->status.hmirror);
p += sprintf(p, "\"dcw\":%u,", s->status.dcw);
p += sprintf(p, "\"colorbar\":%u", s->status.colorbar);
*p++ = '}';
*p++ = 0;
httpd_resp_set_type(req, "application/json");
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
return httpd_resp_send(req, json_response, strlen(json_response));
}
static esp_err_t index_handler(httpd_req_t *req) {
httpd_resp_set_type(req, "text/html");
String page = "";
page += "<meta name=\"viewport\" content=\"width=device-width\">\n";
page += "<p><h2></h2></p><br/><br/><br/>";
page += "<script>var xhttp = new XMLHttpRequest();</script>";
page += "<script>function getsend(arg) { xhttp.open('GET', arg +'?' + new Date().getTime(), true); xhttp.send() } </script>";
//page += "<p align=center><IMG SRC='http://" + WiFiAddr + ":81/stream' style='width:280px;'></p><br/><br/>";
page += "<p align=center><IMG SRC='http://" + WiFiAddr + ":81/stream' style='width:600px; transform:rotate(0deg);'></p><br/>";
//page += "<p align=center> <button style=width:90px;height:80px onmousedown=getsend('go') onmouseup=getsend('stop') ontouchstart=getsend('go') ontouchend=getsend('stop') ></button> </p>";
//page += "<p align=center>";
//page += "<button style=width:90px;height:80px onmousedown=getsend('left') onmouseup=getsend('stop') ontouchstart=getsend('left') ontouchend=getsend('stop')></button> ";
//page += "<button style=width:90px;height:80px onmousedown=getsend('stop') onmouseup=getsend('stop')></button> ";
//page += "<button style=width:90px;height:80px onmousedown=getsend('right') onmouseup=getsend('stop') ontouchstart=getsend('right') ontouchend=getsend('stop')></button>";
//page += "</p>";
//page += "<p align=center><button style=width:90px;height:80px onmousedown=getsend('back') onmouseup=getsend('stop') ontouchstart=getsend('back') ontouchend=getsend('stop') ></button></p>";
page += "<p align=center><br/><br/>";
page += "<button style=width:120px;height:40px;background:#768d87 onmousedown=getsend('links')>links</button> ";
page += "<button style=width:150px;height:40px;background:#91b8b3 onmousedown=getsend('reboot')>ESP Restart</button> ";
page += "<button style=width:120px;height:40px;background:#768d87 onmousedown=getsend('rechts')>rechts</button>";
page += "</p>";
return httpd_resp_send(req, &page[0], strlen(&page[0]));
}
static esp_err_t reboot_handler(httpd_req_t *req) {
delay(500);
Serial.println("rebooting");
delay(2000);
ESP.restart();
httpd_resp_set_type(req, "text/html");
return httpd_resp_send(req, "OK", 2);
}
static esp_err_t links_handler(httpd_req_t *req) {
Servo myservo;
if (posDegrees >= 0 && posDegrees <= 180) {
posDegrees = posDegrees + posDegreesStep;
}
if (posDegrees > 180) {
posDegrees = 180;
}
else {
myservo.write(posDegrees); // move the servo to calculated angle
Serial.print("Moved to: ");
Serial.print(posDegrees); // print the angle
Serial.println(" degree");
}
httpd_resp_set_type(req, "text/html");
return httpd_resp_send(req, "OK", 2);
}
static esp_err_t rechts_handler(httpd_req_t *req) {
Servo myservo;
if (posDegrees > 0 && posDegrees <= 180) {
posDegrees = posDegrees - posDegreesStep;
}
if (posDegrees < 0) {
posDegrees = 0;
} else {
myservo.write(posDegrees); // move the servo to calculated angle
Serial.print("Moved to: ");
Serial.print(posDegrees); // print the angle
Serial.println(" degree");
}
httpd_resp_set_type(req, "text/html");
return httpd_resp_send(req, "OK", 2);
}
void startCameraServer() {
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
httpd_uri_t reboot_uri = {
.uri = "/reboot",
.method = HTTP_GET,
.handler = reboot_handler,
.user_ctx = NULL
};
httpd_uri_t links_uri = {
.uri = "/links",
.method = HTTP_GET,
.handler = links_handler,
.user_ctx = NULL
};
httpd_uri_t rechts_uri = {
.uri = "/rechts",
.method = HTTP_GET,
.handler = rechts_handler,
.user_ctx = NULL
};
httpd_uri_t index_uri = {
.uri = "/",
.method = HTTP_GET,
.handler = index_handler,
.user_ctx = NULL
};
httpd_uri_t status_uri = {
.uri = "/status",
.method = HTTP_GET,
.handler = status_handler,
.user_ctx = NULL
};
httpd_uri_t cmd_uri = {
.uri = "/control",
.method = HTTP_GET,
.handler = cmd_handler,
.user_ctx = NULL
};
httpd_uri_t capture_uri = {
.uri = "/capture",
.method = HTTP_GET,
.handler = capture_handler,
.user_ctx = NULL
};
httpd_uri_t stream_uri = {
.uri = "/stream",
.method = HTTP_GET,
.handler = stream_handler,
.user_ctx = NULL
};
ra_filter_init(&ra_filter, 20);
Serial.printf("Starting web server on port: '%d'", config.server_port);
if (httpd_start(&camera_httpd, &config) == ESP_OK) {
httpd_register_uri_handler(camera_httpd, &index_uri);
httpd_register_uri_handler(camera_httpd, &reboot_uri);
httpd_register_uri_handler(camera_httpd, &links_uri);
httpd_register_uri_handler(camera_httpd, &rechts_uri);
} else {
Serial.printf("Starting web server failed");
}
config.server_port += 1;
config.ctrl_port += 1;
Serial.printf("Starting stream server on port: '%d'", config.server_port);
if (httpd_start(&stream_httpd, &config) == ESP_OK) {
httpd_register_uri_handler(stream_httpd, &stream_uri);
}
}
I had the exact same issue. It's probably because the timers for the camera are interfering with the servo timers. You have to use this library, ServoESP32, and attach your servo like this:
Servo remote;
remote.attach(16, 2);
All this does is attach your servo to channel 2 given that channels 0 and 1 are being used by the CAM. I tried this and it fixed the problem instantly.
Hello every one i m trying to develop web filter and i found Win Divert Samples
here the code is i m trying to run in visual Studio 12 and got this error
IntelliSense: argument of type "PVOID" is incompatible with parameter of type "char *"
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "windivert.h"
#define MAXBUF 0xFFFF
#define MAXURL 4096
/*
* URL and blacklist representation.
*/
typedef struct
{
char *domain;
char *uri;
} URL, *PURL;
typedef struct
{
UINT size;
UINT length;
PURL *urls;
} BLACKLIST, *PBLACKLIST;
/*
* Pre-fabricated packets.
*/
typedef struct
{
WINDIVERT_IPHDR ip;
WINDIVERT_TCPHDR tcp;
} PACKET, *PPACKET;
typedef struct
{
PACKET header;
UINT8 data[];
} DATAPACKET, *PDATAPACKET;
/*
* THe block page contents.
*/
const char block_data[] =
"HTTP/1.1 200 OK\r\n"
"Connection: close\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<!doctype html>\n"
"<html>\n"
"\t<head>\n"
"\t\t<title>BLOCKED!</title>\n"
"\t</head>\n"
"\t<body>\n"
"\t\t<h1>BLOCKED!</h1>\n"
"\t\t<hr>\n"
"\t\t<p>This URL has been blocked!</p>\n"
"\t</body>\n"
"</html>\n";
/*
* Prototypes
*/
static void PacketInit(PPACKET packet);
static int __cdecl UrlCompare(const void *a, const void *b);
static int UrlMatch(PURL urla, PURL urlb);
static PBLACKLIST BlackListInit(void);
static void BlackListInsert(PBLACKLIST blacklist, PURL url);
static void BlackListSort(PBLACKLIST blacklist);
static BOOL BlackListMatch(PBLACKLIST blacklist, PURL url);
static void BlackListRead(PBLACKLIST blacklist, const char *filename);
static BOOL BlackListPayloadMatch(PBLACKLIST blacklist, char *data,
UINT16 len);
/*
* Entry.
*/
int __cdecl main(int argc, char **argv)
{
HANDLE handle;
WINDIVERT_ADDRESS addr;
UINT8 packet[MAXBUF];
UINT packet_len;
PWINDIVERT_IPHDR ip_header;
PWINDIVERT_TCPHDR tcp_header;
PVOID payload;
UINT payload_len;
PACKET reset0;
PPACKET reset = &reset0;
PACKET finish0;
PPACKET finish = &finish0;
PDATAPACKET blockpage;
UINT16 blockpage_len;
PBLACKLIST blacklist;
unsigned i;
INT16 priority = 404; // Arbitrary.
// Read the blacklists.
if (argc <= 1)
{
fprintf(stderr, "usage: %s blacklist.txt [blacklist2.txt ...]\n",
argv[0]);
exit(EXIT_FAILURE);
}
blacklist = BlackListInit();
for (i = 1; i < (UINT)argc; i++)
{
BlackListRead(blacklist, argv[i]);
}
BlackListSort(blacklist);
// Initialize the pre-frabricated packets:
blockpage_len = sizeof(DATAPACKET)+sizeof(block_data)-1;
blockpage = (PDATAPACKET)malloc(blockpage_len);
if (blockpage == NULL)
{
fprintf(stderr, "error: memory allocation failed\n");
exit(EXIT_FAILURE);
}
PacketInit(&blockpage->header);
blockpage->header.ip.Length = htons(blockpage_len);
blockpage->header.tcp.SrcPort = htons(80);
blockpage->header.tcp.Psh = 1;
blockpage->header.tcp.Ack = 1;
memcpy(blockpage->data, block_data, sizeof(block_data)-1);
PacketInit(reset);
reset->tcp.Rst = 1;
reset->tcp.Ack = 1;
PacketInit(finish);
finish->tcp.Fin = 1;
finish->tcp.Ack = 1;
// Open the Divert device:
handle = WinDivertOpen(
"outbound && " // Outbound traffic only
"ip && " // Only IPv4 supported
"tcp.DstPort == 80 && " // HTTP (port 80) only
"tcp.PayloadLength > 0", // TCP data packets only
WINDIVERT_LAYER_NETWORK, priority, 0
);
if (handle == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
printf("OPENED WinDivert\n");
// Main loop:
while (TRUE)
{
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
{
fprintf(stderr, "warning: failed to read packet (%d)\n",
GetLastError());
continue;
}
if (!WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL,
NULL, NULL, &tcp_header, NULL, &payload, &payload_len) ||
!BlackListPayloadMatch(blacklist, payload, (UINT16)payload_len))
{
// Packet does not match the blacklist; simply reinject it.
if (!WinDivertSend(handle, packet, packet_len, &addr, NULL))
{
fprintf(stderr, "warning: failed to reinject packet (%d)\n",
GetLastError());
}
continue;
}
// The URL matched the blacklist; we block it by hijacking the TCP
// connection.
// (1) Send a TCP RST to the server; immediately closing the
// connection at the server's end.
reset->ip.SrcAddr = ip_header->SrcAddr;
reset->ip.DstAddr = ip_header->DstAddr;
reset->tcp.SrcPort = tcp_header->SrcPort;
reset->tcp.DstPort = htons(80);
reset->tcp.SeqNum = tcp_header->SeqNum;
reset->tcp.AckNum = tcp_header->AckNum;
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET), 0);
if (!WinDivertSend(handle, (PVOID)reset, sizeof(PACKET), &addr, NULL))
{
fprintf(stderr, "warning: failed to send reset packet (%d)\n",
GetLastError());
}
// (2) Send the blockpage to the browser:
blockpage->header.ip.SrcAddr = ip_header->DstAddr;
blockpage->header.ip.DstAddr = ip_header->SrcAddr;
blockpage->header.tcp.DstPort = tcp_header->SrcPort;
blockpage->header.tcp.SeqNum = tcp_header->AckNum;
blockpage->header.tcp.AckNum =
htonl(ntohl(tcp_header->SeqNum) + payload_len);
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len, 0);
addr.Direction = !addr.Direction; // Reverse direction.
if (!WinDivertSend(handle, (PVOID)blockpage, blockpage_len, &addr,
NULL))
{
fprintf(stderr, "warning: failed to send block page packet (%d)\n",
GetLastError());
}
// (3) Send a TCP FIN to the browser; closing the connection at the
// browser's end.
finish->ip.SrcAddr = ip_header->DstAddr;
finish->ip.DstAddr = ip_header->SrcAddr;
finish->tcp.SrcPort = htons(80);
finish->tcp.DstPort = tcp_header->SrcPort;
finish->tcp.SeqNum =
htonl(ntohl(tcp_header->AckNum) + sizeof(block_data) - 1);
finish->tcp.AckNum =
htonl(ntohl(tcp_header->SeqNum) + payload_len);
WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET), 0);
if (!WinDivertSend(handle, (PVOID)finish, sizeof(PACKET), &addr, NULL))
{
fprintf(stderr, "warning: failed to send finish packet (%d)\n",
GetLastError());
}
}
}
/*
* Initialize a PACKET.
*/
static void PacketInit(PPACKET packet)
{
memset(packet, 0, sizeof(PACKET));
packet->ip.Version = 4;
packet->ip.HdrLength = sizeof(WINDIVERT_IPHDR) / sizeof(UINT32);
packet->ip.Length = htons(sizeof(PACKET));
packet->ip.TTL = 64;
packet->ip.Protocol = IPPROTO_TCP;
packet->tcp.HdrLength = sizeof(WINDIVERT_TCPHDR) / sizeof(UINT32);
}
/*
* Initialize an empty blacklist.
*/
static PBLACKLIST BlackListInit(void)
{
PBLACKLIST blacklist = (PBLACKLIST)malloc(sizeof(BLACKLIST));
UINT size;
if (blacklist == NULL)
{
goto memory_error;
}
size = 1024;
blacklist->urls = (PURL *)malloc(size*sizeof(PURL));
if (blacklist->urls == NULL)
{
goto memory_error;
}
blacklist->size = size;
blacklist->length = 0;
return blacklist;
memory_error:
fprintf(stderr, "error: failed to allocate memory\n");
exit(EXIT_FAILURE);
}
/*
* Insert a URL into a blacklist.
*/
static void BlackListInsert(PBLACKLIST blacklist, PURL url)
{
if (blacklist->length >= blacklist->size)
{
blacklist->size = (blacklist->size*3) / 2;
printf("GROW blacklist to %u\n", blacklist->size);
blacklist->urls = (PURL *)realloc(blacklist->urls,
blacklist->size*sizeof(PURL));
if (blacklist->urls == NULL)
{
fprintf(stderr, "error: failed to reallocate memory\n");
exit(EXIT_FAILURE);
}
}
blacklist->urls[blacklist->length++] = url;
}
/*
* Sort the blacklist (for searching).
*/
static void BlackListSort(PBLACKLIST blacklist)
{
qsort(blacklist->urls, blacklist->length, sizeof(PURL), UrlCompare);
}
/*
* Match a URL against the blacklist.
*/
static BOOL BlackListMatch(PBLACKLIST blacklist, PURL url)
{
int lo = 0, hi = ((int)blacklist->length)-1;
while (lo <= hi)
{
INT mid = (lo + hi) / 2;
int cmp = UrlMatch(url, blacklist->urls[mid]);
if (cmp > 0)
{
hi = mid-1;
}
else if (cmp < 0)
{
lo = mid+1;
}
else
{
return TRUE;
}
}
return FALSE;
}
/*
* Read URLs from a file.
*/
static void BlackListRead(PBLACKLIST blacklist, const char *filename)
{
char domain[MAXURL+1];
char uri[MAXURL+1];
int c;
UINT16 i, j;
PURL url;
FILE *file = fopen(filename, "r");
if (file == NULL)
{
fprintf(stderr, "error: could not open blacklist file %s\n",
filename);
exit(EXIT_FAILURE);
}
// Read URLs from the file and add them to the blacklist:
while (TRUE)
{
while (isspace(c = getc(file)))
;
if (c == EOF)
{
break;
}
if (c != '-' && !isalnum(c))
{
while (!isspace(c = getc(file)) && c != EOF)
;
if (c == EOF)
{
break;
}
continue;
}
i = 0;
domain[i++] = (char)c;
while ((isalnum(c = getc(file)) || c == '-' || c == '.') && i < MAXURL)
{
domain[i++] = (char)c;
}
domain[i] = '\0';
j = 0;
if (c == '/')
{
while (!isspace(c = getc(file)) && c != EOF && j < MAXURL)
{
uri[j++] = (char)c;
}
uri[j] = '\0';
}
else if (isspace(c))
{
uri[j] = '\0';
}
else
{
while (!isspace(c = getc(file)) && c != EOF)
;
continue;
}
printf("ADD %s/%s\n", domain, uri);
url = (PURL)malloc(sizeof(URL));
if (url == NULL)
{
goto memory_error;
}
url->domain = (char *)malloc((i+1)*sizeof(char));
url->uri = (char *)malloc((j+1)*sizeof(char));
if (url->domain == NULL || url->uri == NULL)
{
goto memory_error;
}
strcpy(url->uri, uri);
for (j = 0; j < i; j++)
{
url->domain[j] = domain[i-j-1];
}
url->domain[j] = '\0';
BlackListInsert(blacklist, url);
}
fclose(file);
return;
memory_error:
fprintf(stderr, "error: memory allocation failed\n");
exit(EXIT_FAILURE);
}
/*
* Attempt to parse a URL and match it with the blacklist.
*
* BUG:
* - This function makes several assumptions about HTTP requests, such as:
* 1) The URL will be contained within one packet;
* 2) The HTTP request begins at a packet boundary;
* 3) The Host header immediately follows the GET/POST line.
* Some browsers, such as Internet Explorer, violate these assumptions
* and therefore matching will not work.
*/
static BOOL BlackListPayloadMatch(PBLACKLIST blacklist, char *data, UINT16 len)
{
static const char get_str[] = "GET /";
static const char post_str[] = "POST /";
static const char http_host_str[] = " HTTP/1.1\r\nHost: ";
char domain[MAXURL];
char uri[MAXURL];
URL url = {domain, uri};
UINT16 i = 0, j;
BOOL result;
HANDLE console;
if (len <= sizeof(post_str) + sizeof(http_host_str))
{
return FALSE;
}
if (strncmp(data, get_str, sizeof(get_str)-1) == 0)
{
i += sizeof(get_str)-1;
}
else if (strncmp(data, post_str, sizeof(post_str)-1) == 0)
{
i += sizeof(post_str)-1;
}
else
{
return FALSE;
}
for (j = 0; i < len && data[i] != ' '; j++, i++)
{
uri[j] = data[i];
}
uri[j] = '\0';
if (i + sizeof(http_host_str)-1 >= len)
{
return FALSE;
}
if (strncmp(data+i, http_host_str, sizeof(http_host_str)-1) != 0)
{
return FALSE;
}
i += sizeof(http_host_str)-1;
for (j = 0; i < len && data[i] != '\r'; j++, i++)
{
domain[j] = data[i];
}
if (i >= len)
{
return FALSE;
}
if (j == 0)
{
return FALSE;
}
if (domain[j-1] == '.')
{
// Nice try...
j--;
if (j == 0)
{
return FALSE;
}
}
domain[j] = '\0';
printf("URL %s/%s: ", domain, uri);
// Reverse the domain:
for (i = 0; i < j / 2; i++)
{
char t = domain[i];
domain[i] = domain[j-i-1];
domain[j-i-1] = t;
}
// Search the blacklist:
result = BlackListMatch(blacklist, &url);
// Print the verdict:
console = GetStdHandle(STD_OUTPUT_HANDLE);
if (result)
{
SetConsoleTextAttribute(console, FOREGROUND_RED);
puts("BLOCKED!");
}
else
{
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
puts("allowed");
}
SetConsoleTextAttribute(console,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
return result;
}
/*
* URL comparison.
*/
static int __cdecl UrlCompare(const void *a, const void *b)
{
PURL urla = *(PURL *)a;
PURL urlb = *(PURL *)b;
int cmp = strcmp(urla->domain, urlb->domain);
if (cmp != 0)
{
return cmp;
}
return strcmp(urla->uri, urlb->uri);
}
/*
* URL matching
*/
static int UrlMatch(PURL urla, PURL urlb)
{
UINT16 i;
for (i = 0; urla->domain[i] && urlb->domain[i]; i++)
{
int cmp = (int)urlb->domain[i] - (int)urla->domain[i];
if (cmp != 0)
{
return cmp;
}
}
if (urla->domain[i] == '\0' && urlb->domain[i] != '\0')
{
return 1;
}
for (i = 0; urla->uri[i] && urlb->uri[i]; i++)
{
int cmp = (int)urlb->uri[i] - (int)urla->uri[i];
if (cmp != 0)
{
return cmp;
}
}
if (urla->uri[i] == '\0' && urlb->uri[i] != '\0')
{
return 1;
}
return 0;
}
This file compiles without errors as C code, so be sure that you compile it as C. If you need to compile it as C++, then add explicit cast to char* at payload parameter in this line:
if (!WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL,
NULL, NULL, &tcp_header, NULL, &payload, &payload_len) ||
!BlackListPayloadMatch(blacklist, payload, (UINT16)payload_len))
Like this:
if (!WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL,
NULL, NULL, &tcp_header, NULL, &payload, &payload_len) ||
!BlackListPayloadMatch(blacklist, (char*)payload, (UINT16)payload_len))
I used DrawItem () to redraw CListBox. ods_hotlight does not work in win7/win8.
How can I do this CListBox hotlight tracking?
OK ,I solved this now .... ,Code posted below :
extern "C" WINUSERAPI BOOL WINAPI TrackMouseEvent (LPTRACKMOUSEEVENT lpEventTrack);
void CListBoxCS::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_HOVER | TME_LEAVE;
tme.dwHoverTime = HOVER_DEFAULT;
tme.hwndTrack = m_hWnd;
tme.dwHoverTime = 1;
TrackMouseEvent (&tme);
BOOL bOut = TRUE;
short index;
index = (short) ItemFromPoint (point,bOut);
if (FALSE == bOut) {
if (m_ihot != index) {
m_ihot = index;
//printf ("index = %d \n",m_ihot);
Invalidate (FALSE);
}
} else {
//printf ( "out \n" );
}
}
void CListBoxCS::OnMouseLeave (void)
{
//printf ( "mouse leave \n" );
m_ihot = -1;
}
void CListBoxCS::DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// some judgements here .....
// some preparations
// hot light code ...
if ((act & ODA_SELECT) || (act & ODA_DRAWENTIRE)) {
if (lpDIS->itemState & ODS_SELECTED) {
dc.FillSolidRect (&lpDIS->rcItem,(RGB (209, 232, 255)));
} else {
dc.FillSolidRect (&lpDIS->rcItem,(RGB (230, 230, 230)));
}
if (m_ihot == lpDrawItemStruct->itemID) {
dc.FillSolidRect (&lpDIS->rcItem,(RGB (229, 243, 251)));
}
}
// something U like to do ....
}
I want to hide files (in my program). I decided to use NtQueryDirectoryFile. But the files are not hidden, the code does not work. I don't use a driver, I use user mode. Can anybody help me please?
The code snippet:
typedef NTSTATUS (WINAPI * NTQUERYDIRECTORYFILE) (IN HANDLE FileHandle,IN HANDLE Event OPTIONAL,IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,IN PVOID ApcContext OPTIONAL,OUT PIO_STATUS_BLOCK IoStatusBlock,OUT PVOID FileInformation,IN ULONG FileInformationLength,IN MYFILE_INFORMATION_CLASS FileInformationClass,IN BOOLEAN ReturnSingleEntry,IN PUNICODE_STRING FileName OPTIONAL,IN BOOLEAN RestartScan);
NTQUERYDIRECTORYFILE OriginalNtQueryDirectoryFile;
#define STATUS_NO_SUCH_FILE 0xC000000F
NTSTATUS
HookedNtQueryDirectoryFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG FileInformationLength,
IN MYFILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry,
IN PUNICODE_STRING FileName OPTIONAL,
IN BOOLEAN RestartScan)
{
NTSTATUS status = OriginalNtQueryDirectoryFile(FileHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,FileInformation,FileInformationLength,FileInformationClass,ReturnSingleEntry,FileName,RestartScan);
vector<wstring> listDataForHidding;
listDataForHidding.push_back(L"afile.txt");
listDataForHidding.push_back(L"bfile.txt");
listDataForHidding.push_back(L"cfile.txt");
listDataForHidding.push_back(L"dfile.txt");
if (NT_SUCCESS(status))
{
PMYFILE_DIRECTORY_INFORMATION FileDirectoryInfo, LastFileDirectoryInfo;
PMYFILE_FULL_DIR_INFORMATION LastFileFullDirectoryInfo, FileFullDirectoryInfo;
PMYFILE_BOTH_DIR_INFORMATION LastFileBothDirectoryInfo, FileBothDirectoryInfo;
PMYFILE_NAMES_INFORMATION LastFileNamesInfo, FileNamesInfo;
ULONG Offset = 0;
BOOL bNeedHide = FALSE;
switch (FileInformationClass)
{
case FileDirectoryInformation :
FileDirectoryInfo = NULL;
do
{
//FileDirectoryInfo = (PVOID)((ULONG)FileInformation + Offset);
FileDirectoryInfo = (PMYFILE_DIRECTORY_INFORMATION)((ULONG)FileInformation + Offset);
LastFileDirectoryInfo = FileDirectoryInfo;
wstring wstrCurrFileName = FileDirectoryInfo->FileName;
bNeedHide = FALSE;
for(size_t index = 0; index < listDataForHidding.size(); index ++)
{
if(wstrCurrFileName.find(listDataForHidding[index]) != wstring::npos)
{
bNeedHide = TRUE;
break;
}
}
//if (FileDirectoryInfo->FileName[0] == 0x5F00)
if(bNeedHide == TRUE)
{
if (!FileDirectoryInfo->NextEntryOffset)
{
if (LastFileDirectoryInfo) LastFileDirectoryInfo->NextEntryOffset = 0;
else status = STATUS_NO_SUCH_FILE;
return status;
} else
if (LastFileDirectoryInfo) LastFileDirectoryInfo->NextEntryOffset += FileDirectoryInfo->NextEntryOffset;
}
Offset += FileDirectoryInfo->NextEntryOffset;
} while (FileDirectoryInfo->NextEntryOffset);
break;
case FileFullDirectoryInformation :
FileFullDirectoryInfo = NULL;
do
{
LastFileFullDirectoryInfo = FileFullDirectoryInfo;
//FileFullDirectoryInfo = (PVOID)((ULONG)FileInformation + Offset);
FileFullDirectoryInfo = (PMYFILE_FULL_DIR_INFORMATION)((ULONG)FileInformation + Offset);
wstring wstrCurrFileName = FileDirectoryInfo->FileName;
bNeedHide = FALSE;
for(size_t index = 0; index < listDataForHidding.size(); index ++)
{
if(wstrCurrFileName.find(listDataForHidding[index]) != wstring::npos)
{
bNeedHide = TRUE;
break;
}
}
//if (FileFullDirectoryInfo->FileName[0] == 0x5F00)
if(bNeedHide == TRUE)
{
if (!FileFullDirectoryInfo->NextEntryOffset)
{
if (LastFileFullDirectoryInfo) LastFileFullDirectoryInfo->NextEntryOffset = 0;
else status = STATUS_NO_SUCH_FILE;
return status;
} else
if (LastFileFullDirectoryInfo) LastFileFullDirectoryInfo->NextEntryOffset += FileFullDirectoryInfo->NextEntryOffset;
}
Offset += FileFullDirectoryInfo->NextEntryOffset;
} while (FileFullDirectoryInfo->NextEntryOffset);
break;
case FileBothDirectoryInformation :
FileBothDirectoryInfo = NULL;
do
{
LastFileBothDirectoryInfo = FileBothDirectoryInfo;
//FileBothDirectoryInfo = (PVOID)((ULONG)FileInformation + Offset);
FileBothDirectoryInfo = (PMYFILE_BOTH_DIR_INFORMATION)((ULONG)FileInformation + Offset);
wstring wstrCurrFileName = FileDirectoryInfo->FileName;
bNeedHide = FALSE;
for(size_t index = 0; index < listDataForHidding.size(); index ++)
{
if(FileBothDirectoryInfo->FileNameLength > 1 && wstrCurrFileName.find(listDataForHidding[index]) != wstring::npos)
{
bNeedHide = TRUE;
break;
}
}
//if (FileBothDirectoryInfo->FileNameLength > 1 && FileBothDirectoryInfo->FileName[0] == 0x5F00)
if(bNeedHide == TRUE)
{
if (!FileBothDirectoryInfo->NextEntryOffset)
{
if (LastFileBothDirectoryInfo) LastFileBothDirectoryInfo->NextEntryOffset = 0;
else status = STATUS_NO_SUCH_FILE;
return status;
} else
if (LastFileBothDirectoryInfo) LastFileBothDirectoryInfo->NextEntryOffset += FileBothDirectoryInfo->NextEntryOffset;
}
Offset += FileBothDirectoryInfo->NextEntryOffset;
} while (FileBothDirectoryInfo->NextEntryOffset);
break;
case FileNamesInformation :
FileNamesInfo = NULL;
do
{
LastFileNamesInfo = FileNamesInfo;
//FileNamesInfo = (PVOID)((ULONG)FileInformation + Offset);
FileNamesInfo = (PMYFILE_NAMES_INFORMATION)((ULONG)FileInformation + Offset);
wstring wstrCurrFileName = FileDirectoryInfo->FileName;
bNeedHide = FALSE;
for(size_t index = 0; index < listDataForHidding.size(); index ++)
{
if(wstrCurrFileName.find(listDataForHidding[index]) != wstring::npos)
{
bNeedHide = TRUE;
break;
}
}
//if (FileNamesInfo->FileName[0] == 0x5F00)
if(bNeedHide == TRUE)
{
if (!FileNamesInfo->NextEntryOffset)
{
if(LastFileNamesInfo) LastFileNamesInfo->NextEntryOffset = 0;
else status = STATUS_NO_SUCH_FILE;
return status;
} else
if (LastFileNamesInfo) LastFileNamesInfo->NextEntryOffset += FileNamesInfo->NextEntryOffset;
}
Offset += FileNamesInfo->NextEntryOffset;
} while (FileNamesInfo->NextEntryOffset);
break;
}
}
return status;
}