Restarting Camera.StartStreamingBitmaps after Camera.PictureCaptured - .net-micro-framework

I have a .Net Gadgeteer camera app that streams bitmaps from the camera to a screen. On the press of a button it stops streaming the bitmaps from the camera, takes a picture, writes it to SD card, and then restarts the streaming. Here's a simplified version of the code (without the saving to SD card stuff):
using Microsoft.SPOT;
using GT = Gadgeteer;
using Gadgeteer.Modules.GHIElectronics;
namespace SimpleStopStreamingApp
{
public partial class Program
{
void ProgramStarted()
{
camera.CameraConnected += new Camera.CameraConnectedEventHandler(camera_CameraConnected);
camera.BitmapStreamed += new Camera.BitmapStreamedEventHandler(camera_BitmapStreamed);
camera.PictureCaptured += new Camera.PictureCapturedEventHandler(camera_PictureCaptured);
button.ButtonPressed += new Button.ButtonEventHandler(button_ButtonPressed);
}
void camera_CameraConnected(Camera sender)
{
camera.StartStreamingBitmaps(new Bitmap(camera.CurrentPictureResolution.Width, camera.CurrentPictureResolution.Height));
}
void camera_BitmapStreamed(Camera sender, Bitmap bitmap)
{
display_T35.SimpleGraphics.DisplayImage(bitmap, 0, 0);
}
void button_ButtonPressed(Button sender, Button.ButtonState state)
{
camera.StopStreamingBitmaps();
camera.TakePicture();
}
void camera_PictureCaptured(Camera sender, GT.Picture picture)
{
camera.StartStreamingBitmaps(new Bitmap(camera.CurrentPictureResolution.Width, camera.CurrentPictureResolution.Height));
}
}
}
However when I try to restart the streaming (in the PictureCaptured event handler) I get the exception.
#### Exception System.Exception - 0xffffffff (1) ####
#### Message:
#### GHI.Premium.USBHost.USBH_Webcam::StartStreaming_Internal [IP: 0000] ####
#### GHI.Premium.USBHost.USBH_Webcam::StartStreaming [IP: 0005] ####
#### Gadgeteer.Modules.GHIElectronics.Camera::StartStreamingBitmaps [IP: 007e] ####
#### Gadgeteer.Modules.GHIElectronics.Camera::OnPictureCapturedEvent [IP: 0037] ####
#### System.Reflection.MethodBase::Invoke [IP: 0000] ####
#### Gadgeteer.Program::DoOperation [IP: 001a] ####
#### Microsoft.SPOT.Dispatcher::PushFrameImpl [IP: 0054] ####
#### Microsoft.SPOT.Dispatcher::PushFrame [IP: 001a] ####
#### Microsoft.SPOT.Dispatcher::Run [IP: 0006] ####
#### Gadgeteer.Program::Run [IP: 0020] ####
A first chance exception of type 'System.Exception' occurred in GHI.Premium.USBHost.dll
Error invoking method "Gadgeteer.Modules.GHIElectronics.Camera" (check arguments to Program.BeginInvoke are correct)
(N.B. I get this same exception if I store the bitmap as an instance variable and pass it in to both calls to StartStreamingBitmaps instead of creating a new Bitmap each time.)
What's going on? How should one stop the camera streaming to capture and image and then restart it streaming?

It almost sounds like StartStreamingBitmaps is expected to run on a thread (by the note to check arguments to Program.BeginInvoke are correct).
Looking at this:
void camera_PictureCaptured(Camera sender, GT.Picture picture)
{
camera.StartStreamingBitmaps(new Bitmap(camera.CurrentPictureResolution.Width, camera.CurrentPictureResolution.Height));
}
I don't know anything about this Gadgeteer module, but if you wired it up correctly, I'd think your new GT.Picture is already contained in the picture parameter that was passed in.
It almost looks like you are trying to stream images from the camera after the camera has finished taking the picture.
Can you edit your post and give more details? Can you verify that this camera_PictureCaptured event is where your exception is being thrown? It'd be easy enough to do by modifying your event handler to be:
void camera_PictureCaptured(Camera sender, GT.Picture picture)
{
try
{
camera.StartStreamingBitmaps(new Bitmap(camera.CurrentPictureResolution.Width, camera.CurrentPictureResolution.Height));
} catch (Exception err)
{
throw new Exception("PictureCaptured: " + err.Message);
}
}
If this event handler is not the one throwing the exception, try placing similar try...catch routines in your other event handlers until you discover which one is really causing the problem.

Try removing the callback when you stop streaming the bitmaps:
void button_ButtonPressed(Button sender, Button.ButtonState state)
{
camera.BitmapStreamed -= new Camera.BitmapStreamedEventHandler(camera_BitmapStreamed);
camera.StopStreamingBitmaps();
camera.TakePicture();
}
void camera_PictureCaptured(Camera sender, GT.Picture picture)
{
camera.BitmapStreamed += new Camera.BitmapStreamedEventHandler(camera_BitmapStreamed);
camera.StartStreamingBitmaps(new Bitmap(camera.CurrentPictureResolution.Width, camera.CurrentPictureResolution.Height));
}

Related

Can we recognise inaccessible url using apache CloseableHttpAsyncClient

I am using CloseableHttpAsyncClient for downloading image with socketreadtimemout of 10 sec , connect timeout 5sec and doing a retry if it fails with sockettimeout and Timeout exception.
Now when the url is not accessible(404) then instead of resource not found exception it is failing with socket timeout and doing a retry again.So in my case for this invalid url also we are trying again and it adds up to the latency(~10+10=20 sec).
Below is the code snippet
Future<HttpResponse> httpResponseFuture = asyncCloseableHttpClient.execute(httpUriRequest, null);
try {
return httpResponseFuture.get(10000, TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
Throwable cause = e.getCause() != null ? e.getCause() : e;
if (cause instanceof ConnectException) {
throw new DownloadConnectionException("ConnectionException " + cause, DOWNLOAD_FAILED, cause);
}
if (cause instanceof SocketTimeoutException) {
throw new DownloadTimeoutException(DOWNLOAD_TIMEOUT_EXCEPTION);
}
if (cause instanceof ConnectionClosedException) {
throw new DownloadConnectionClosedException("ConnectionClosedException " + DOWNLOAD_FAILED, cause);
}
if(cause instanceof UnsupportedCharsetException) {
throw new BadRequestException("Image download failed with UnsupportedCharsetException " + cause,
INVALID_CONTENT_TYPE_EXCEPTION, cause);
}
} catch (TimeoutException e) {
throw new DownloadTimeoutException(DOWNLOAD_TIMEOUT_EXCEPTION);
}
This the config values for CloseableHttpAsyncClient
RequestConfig config = RequestConfig.custom()
.setSocketTimeout(10000)
.setConnectTimeout(5000)
.setRedirectsEnabled(true)
.setMaxRedirects(3)
.setStaleConnectionCheckEnabled(false) // never set this to true, 30 ms extra per request
.setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
.build();
This is retry config
RetryConfig.custom().maxAttempts(downloadAttempts).retryOnException(e -> ( e instanceof DownloadTimeoutException) ) .waitDuration(Duration.ofMillis(30)).build();
To give more context why I am setting the socketreadtimemout of 10 sec because let's say for some bigger image download it may fail 1st time,so in that case retry is valid scenario but not in the resource not found case.
Can we do anything to make resource not found/invalid url fail fast so that it wont fail with sockettimeout exception.

How to catch/Capture "javax.net.ssl.SSLHandshakeException: Failed to create SSL connection" while sending message over java vert.x Eventbus

I am trying to use SSL over eventbus. To test the failure case I tried sending message to the eventbus from another verticle in same cluster by passing some different keystore.
I am getting below exception on console but it is not failing the replyHandler hence my code is not able to detect the SSL exception.
my code:
eb.request("ping-address", "ping!", new DeliveryOptions(), reply -> {
try {
if (reply.succeeded()) {
System.out.println("Received reply " + reply.result().body());
} else {
System.out.println("An exception " + reply.cause().getMessage());
}
} catch (Exception e) {
System.out.println("An error occured" + e.getCause());
}
});
Exception on console:
**javax.net.ssl.SSLHandshakeException: Failed to create SSL connection**
at io.vertx.core.net.impl.ChannelProvider$1.userEventTriggered(ChannelProvider.java:109)
at io.netty.channel.AbstractChannelHandlerContext.invokeUserEventTriggered(AbstractChannelHandlerContext.java:341)
at io.netty.channel.AbstractChannelHandlerContext.invokeUserEventTriggered(AbstractChannelHandlerContext.java:327)
at io.netty.channel.AbstractChannelHandlerContext.fireUserEventTriggered(AbstractChannelHandlerContext.java:319)
at io.netty.handler.ssl.SslHandler.handleUnwrapThrowable(SslHandler.java:1249)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1230)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1271)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:505)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:444)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:283)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1422)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:931)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:700)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:635)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:552)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:514)
at io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1044)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:813)
Caused by: javax.net.ssl.SSLException: Received fatal alert: bad_certificate
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1647)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1615)
at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1781)
at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1070)
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:896)
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:766)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:282)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1329)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1224)
... 20 more
But handler is failing for timeout after 30 sec.
Timed out after waiting 30000(ms) for a reply. address: __vertx.reply.8419a431-d633-4ba8-a12e-c41fd5a4f37a, repliedAddress: ping-address
I want to capture the SSL exception immediately and handle it. Please guide me how can I Capture/catch this exception.
I tried with below code. Below one is able to handle the exception and I am not getting reply result from called event-bus. Reply result is always null. (value is always null)
MessageProducer<Object> ms = eb.sender("ping-address");
ms.write("ping!", reply -> {
if (reply.succeeded()) {
reply.map(value -> {
System.out.println("Received reply " + value);
return reply;
});
} else {
System.out.println("No reply");
System.out.println("An exception : " + reply.cause().getMessage());
}
});
You can't catch this exception because the Vert.x clustered EventBus implementation buffers messages when the nodes are not connected together. The message could be sent later if the problem is only temporary.
If you want to be notified earlier, you could set a lower timeout in DeliveryOptions.

How I can get to work a foo.local mDNS link between an ESP32 Server and an ESP32 Client?

I am trying to access http:///myServerName.local/ link through a client running on ESP32 after I establish the mDNS on the server running on another ESP32.
I tried implementing an HTTP request with the previous link, but it won't seem to work. I also tried just to access the link from my browser but that won't work either.
Client Code:
HTTPClient http;
Serial.print("[HTTP] begin... \n");
http.begin("http://myServerName.local/"); //HTTP
Serial.print("[HTTP GET... \n");
int httpCode = http.GET();
...
Server Code:
void advertiseServices(const char* myName)
{
if(MDNS.begin(myName))
{
Serial.println(F("mDNS responder started."));
Serial.print(F("I am: "));
Serial.println(myName);
//Add service to MDNS-SD
MDNS.addService("http", "tcp", 80);
}
else
{
while(1)
{
Serial.println(F("Error setting up MDNS responder"));
delay(1000);
}
}
}
void setup(void)
{
//Activarea serviciilor prin care putem lua legatura cu device-urile in functie de numele lor
advertiseServices("myServerName");
...
}
The only thing I got so far was -1 for httpCode and nothing else.

How to handle UndeliverableException error thrown via blockingFirst() in Micronaut?

Below is a snippet from my micronaut web service:
try {
val result = hClient.exchange(GET<String>("$readEndpoint/$token")).blockingFirst()
logger.error("result")
} catch (e: Exception) {
logger.error(e.message)
}
hClient is a reactive http client injected as #Inject val hClient: RxHttpClient
The endpoint is throwing "Connection reset by peer" exception.
Issue I am facing
Even though I have wrapped code in try and catch, An exception io.reactivex.exceptions.UndeliverableException is thrown and not caught.
I basically get two exceptions thrown, one is caught by catch block with message Error occurred reading HTTP response: Connection reset by peer, another one is flowing up to service with message io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | java.nio.channels.ClosedChannelException
Reproducible via below code
Keep timeout too less to receive a timeout error.
micronaut:
http:
client:
read-timeout: 1s
#Controller("/")
class TokenController(
#Client("https://hello123456789.com/dummy") #Inject val hClient: RxHttpClient
) {
#Get("/test")
fun refresh(): String {
try {
val result = hClient.exchange(HttpRequest.GET<String>("/token/1234")).blockingFirst()
println("result")
} catch (e: Exception) {
println(e.message)
}
return ""
}
}
Googling told me that I need to add global onError to rxjava but couldn't find how to do that in Micronaut.
Any help is appreciated.

Creating new user with Smack on ejabberd throws XMPP Exception: forbidden(403)

Hi I am working on ejabberd and I am quite new to this technology.
I am trying to add a user on my ejabberd server using this code:
try {
conf.setSASLAuthenticationEnabled(true);
connection.connect();
Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.manual);
Log.i("XMPPClient", "Connected to "
+connection.getHost());
createUser("tester","testerpass");
}
} catch (XMPPException e1) {
Log.e("XMPPClient", e1.toString());
xmppClient.setConnection(null);
}
public void createUser(String user, String pass) {
try {
//Admin login
connection.login(user, pass);
} catch (XMPPException e) {
e.printStackTrace();
}
Log.i("connection.isAuthenticated() : ",""+connection.isAuthenticated() );
if (connection.isAuthenticated()) {
AccountManager manager = connection.getAccountManager();
try {
manager.createAccount(user, pass);
} catch (XMPPException e) {
Log.w("[create_user] Cannot create new user: XMPP Exception.", "0");
e.printStackTrace();
} catch (IllegalStateException e) {
Log.w("[create_user] Cannot create new user: not logged in.", "0");
e.printStackTrace();
}
}
}
Its connecting to server and admin login is perfectly But during creating new account
it gives forbidden 403 error that is :
06-15 20:01:40.092: I/XMPPClient(1300):Connected to 68.178.255.136
06-15 20:01:41.952: I/connection.isAuthenticated() :(1300): true
06-15 20:01:42.562: W/[create_user] Cannot create new user: XMPP Exception.(1300): 0
06-15 20:01:42.562: W/System.err(1300): forbidden(403)
06-15 20:01:42.562: W/System.err(1300): at org.jivesoftware.smack.AccountManager.createAccount(AccountManager.java:246)
I would be very thankful if somebody can suggest a workarround for this .
Goto C:\Program Files (x86)\ejabberd-2.1.8\conf (in my case) folder & open ejabberd.cfg file using Notepad++ (it is easy to edit using it).
In the file do the following changes:
%% Put this in the section ACCESS RULES
{access, register_from, [{allow, admin}]}.
%% Change mod_register so it contains the new access rule:
{mod_register, [
{access_from, register_from},
...
] ...
I want to update the answer to reflect the change in Asmack library version 4.0 onward.
Connection.getAccountManager() is now AccountManager.getInstance(XMPPConnection)
AccountManager accountManager=AccountManager.getInstance(connection);
try {
accountManager.createAccount("username", "password");
} catch (XMPPException e1) {
Log.d(e1.getMessage(), e1);
}
In my case, i need to edit the file EJABERD_HOME/conf/ejabberd.yml, on mod_register change parameters to:
ip_access : all
access_from : all
access: register
To allow users register from another host
For yaml configuration as follows.
access_rules:
local:
allow: all
configure:
allow: all
trusted_network:
allow: all
register:
allow: all
.......
modules:
mod_register:
ip_access: trusted_network
access: register
access_from: all
Note: This is allow all configuration. Make strict configuration as required.