How can I reply to a get request from managing software such as (solarwinds) - sharp-snmp

I use sharpSnmp to make a SNMP agent (virtual SNMP machine) that communicates with monitoring software.
But my agent is not detected by Monitoring apps.
I can get the Message from monitoring software by this code, the incoming message from monitoring software (solarwinds) has an OID: "1.3.6.1.2.1.1.2.0" with null value. I tried to set it's value and reply by this code:
private void MessageToListener(object sender, EventArgs e)
{
int i = 0;
//Listener listen = sender as Listener;
MessageReceivedEventArgs ee = e as MessageReceivedEventArgs;
ISnmpMessage message = ee.Message;
int messageId = message.MessageId();
int requestId = message.RequestId();
OctetString userName = message.Parameters.UserName;
IList<Variable> List= new List<Variable>
{
new Variable(new ObjectIdentifier("1.3.6.1.2.1.1.2.0"), new OctetString("Shanghai"))
};
if (message.Version == VersionCode.V2)
{
Messenger.Set(VersionCode.V2, new IPEndPoint(IPAddress.Parse("192.168.52.10"), 161), userName, List,
10000);
}
}
but I get 'Timeout exception' at my agent side and 'Test Failed' at monitoring software side.
Where is my mistake? anybody can help?

Related

Azure Service Bus SendMessageAsync method terminates and crashes whole program

I created a .NET core 6 project. I added Azure.Messaging.ServiceBus as the dependency. I am using below code to send message to service bus topic.
// See https://aka.ms/new-console-template for more information
using Azure.Messaging.ServiceBus;
using System.Dynamic;
using System.Net;
using System.Text;
using System.Text.Json;
Console.WriteLine("Hello, World!");
Sender t = new Sender();
Sender.Send();
class Sender
{
public static async Task Send()
{
string connectionString = "Endpoint=sb://sb-test-one.servicebus.windows.net/;SharedAccessKeyName=manage;SharedAccessKey=8e+6SWp3skB3AeDlwH6ufGEainEs45353435JzDywz5DU=;";
string topicName = "topicone";
string subscriptionName = "subone";
// The Service Bus client types are safe to cache and use as a singleton for the lifetime
try
{
await using var client = new ServiceBusClient(connectionString, new ServiceBusClientOptions
{
TransportType = ServiceBusTransportType.AmqpWebSockets
});
// create the sender
ServiceBusSender sender = client.CreateSender(topicName);
dynamic data = new ExpandoObject();
data.name = "Abc";
data.age = 6;
// create a message that we can send. UTF-8 encoding is used when providing a string.
var messageBody = JsonSerializer.Serialize(data);
ServiceBusMessage message = new ServiceBusMessage(messageBody);
// send the message
await sender.SendMessageAsync(message);
var s = 10;
}
catch (Exception e)
{
var v = 10;
}
//// create a receiver for our subscription that we can use to receive the message
//ServiceBusReceiver receiver = client.CreateReceiver(topicName, subscriptionName);
//// the received message is a different type as it contains some service set properties
//ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();
//// get the message body as a string
//string body = receivedMessage.Body.ToString();
//Console.WriteLine(body);
Console.WriteLine("Press any key to end the application");
Console.ReadKey();
}
}
Issue: When I call await sender.SendMessageAsync(message); after this line get executed, the program is actually terminating. It not awating. The whole execution stops after this line.
System is not throwing any exception and service bus is not receiving any message.
I just noticed that all other samples I saw had a default SharedAccessPolicy called RootManageSharedAccessKey policy available by default in the azure portal. For me, I had to create this policy. To my policy I have given Manage, Send, ReceiveAccess.
Needed to change Sender.Send(); to Sender.Send().GetAwaiter().GetResult();

Android app fails bluetooth connection with ESP when calling connect()

I'm trying to build an Android app in Android Studio using Kotlin to send some simple data between an ESP32 and a mobile over Bluetooth. I've been following along a number of tutorials but just can't seem to get the connection established, permissions and scanning for devices looks to be working correctly. When I call connect() on the socket the app hangs for a few seconds and then crashes with this error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.btleveller, PID: 28899
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { (has extras) }} to activity {com.example.btleveller/com.example.btleveller.MainActivity}: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
at android.app.ActivityThread.deliverResults(ActivityThread.java:5368)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5407)
etc... I can post the full output if it's helpful
My ESP is running some very basic helloworld style code using the NimBLE-Arduino code, programmed through VSCode with the PlatformIO extension. I think this side of it is all working correct as I can see the device in the "nRF Connect" app on my mobile. The scanning is done through the CompanionDeviceManager library:
I thought maybe there was a problem with the UUID I was supplying, or that I needed to make changes for BLE as opposed to regular Bluetooth but so far nothing I've found online has worked. I've also tried using "createL2capChannel()" to create the socket but got stuck on the PSM value. These are the relevant bits of code:
//private val ESP_UUID = UUID.fromString("0000dead-0000-1000-8000-00805F9B34FB")
private val ESP_UUID = UUID.fromString("0000baad-0000-1000-8000-00805F9B34FB")
...
// Look for connection, kicked off by button press
fun lookForConn(view: View) {
val deviceFilter: BluetoothDeviceFilter = BluetoothDeviceFilter.Builder()
.setNamePattern(Pattern.compile("BLE"))
.build()
// The argument provided in setSingleDevice() determines whether a single
// device name or a list of them appears.
val pairingRequest: AssociationRequest = AssociationRequest.Builder()
.addDeviceFilter(deviceFilter)
.setSingleDevice(false)
.build()
// When the app tries to pair with a Bluetooth device, show the
// corresponding dialog box to the user.
deviceManager.associate(pairingRequest,
object : CompanionDeviceManager.Callback() {
override fun onDeviceFound(chooserLauncher: IntentSender) {
startIntentSenderForResult(chooserLauncher,
SELECT_DEVICE_REQUEST_CODE, null, 0, 0, 0)
}
override fun onFailure(error: CharSequence?) {
// Handle the failure.
Log.d("DEVHandler","failed to find dev?")
}
}, null)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
SELECT_DEVICE_REQUEST_CODE -> when(resultCode) {
Activity.RESULT_OK -> {
// The user chose to pair the app with a Bluetooth device.
val deviceToPair: BluetoothDevice? =
data?.getParcelableExtra(CompanionDeviceManager.EXTRA_DEVICE)
Log.d("DEVHandler","try to bond:" + deviceToPair?.name)
deviceToPair?.let { device ->
device.createBond()
val newConn = ConnectThread(deviceToPair).run()
}
}
}
else -> super.onActivityResult(requestCode, resultCode, data)
}
}
private inner class ConnectThread(device: BluetoothDevice) : Thread() {
private var mHaveConn = false
public fun IsConnected(): Boolean {
return mHaveConn
}
private val mmSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) {
//device.createRfcommSocketToServiceRecord(ESP_UUID)
device.createInsecureRfcommSocketToServiceRecord(ESP_UUID)
}
public override fun run() {
// Cancel discovery because it otherwise slows down the connection.
BTMan.mBTAdapter?.cancelDiscovery()
mmSocket?.let { socket ->
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
if (socket == null)
Log.d("CONNThread", "Socket is null...")
if (socket.isConnected == true)
Log.d("CONNThread", "Socket is already connected...")
socket.connect()
Log.d("CONNThread", "Made a connection")
// The connection attempt succeeded. Perform work associated with
// the connection in a separate thread.
//manageMyConnectedSocket(socket)
mHaveConn = true
}
}
// Closes the client socket and causes the thread to finish.
fun cancel() {
try {
mmSocket?.close()
} catch (e: IOException) {
Log.e("CONNThread", "Could not close the client socket", e)
}
mHaveConn = false
}
}

How to get all the session id of a queue in azure service bus .Net Core

i'm making a web application which is connected to Azure by using .Net Core 2.1.1. I encountered some problem related with service bus queue when i'm trying to get the sessionid of the related queue.
I found some code, but it isn't supported by the .Net Core. Here below is the code:
var queueClient = QueueClient.CreateFromConnectionString(AppSettings.ServiceBusConnection, queueName);
var sessions = await queueClient.GetMessageSessionsAsync();
return sessions;
I also already tried this function,
var connString = Configuration.GetConnectionString("servicebus");
sessionClient = new SessionClient(connString, queue,ReceiveMode.PeekLock);
List<IMessageSession> sessions=new List<IMessageSession>();
while (true)
{
var session = await sessionClient.AcceptMessageSessionAsync();
if (session == null)
break;
sessions.Add(session);
}
return sessions;
}
But it keep giving me Timeout Exception. Can anyone help me ?
This is something which i tried and it worked for me, Please check the screenshot below
Here is the code i have tried
using System;
namespace Core.SBConsole
{
using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.ServiceBus.Core;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
class Program
{
// Connection String for the namespace can be obtained from the Azure portal under the
// 'Shared Access policies' section.
const string ServiceBusConnectionString = "{Connection String}";
const string QueueName = "mvq";
static IMessageSender messageSender;
static ISessionClient sessionClient;
const string SessionPrefix = "session-prefix";
static void Main(string[] args)
{
MainAsync().GetAwaiter().GetResult();
}
static async Task MainAsync()
{
const int numberOfSessions = 5;
const int numberOfMessagesPerSession = 3;
messageSender = new MessageSender(ServiceBusConnectionString, QueueName);
sessionClient = new SessionClient(ServiceBusConnectionString, QueueName);
// Send messages with sessionId set
await SendSessionMessagesAsync(numberOfSessions, numberOfMessagesPerSession);
// Receive all Session based messages using SessionClient
await ReceiveSessionMessagesAsync(numberOfSessions, numberOfMessagesPerSession);
Console.WriteLine("=========================================================");
Console.WriteLine("Completed Receiving all messages... Press any key to exit");
Console.WriteLine("=========================================================");
Console.ReadKey();
await messageSender.CloseAsync();
await sessionClient.CloseAsync();
}
static async Task ReceiveSessionMessagesAsync(int numberOfSessions, int messagesPerSession)
{
Console.WriteLine("===================================================================");
Console.WriteLine("Accepting sessions in the reverse order of sends for demo purposes");
Console.WriteLine("===================================================================");
for (int i = 0; i < numberOfSessions; i++)
{
int messagesReceivedPerSession = 0;
// AcceptMessageSessionAsync(i.ToString()) as below with session id as parameter will try to get a session with that sessionId.
// AcceptMessageSessionAsync() without any messages will try to get any available session with messages associated with that session.
IMessageSession session = await sessionClient.AcceptMessageSessionAsync();// (SessionPrefix + i.ToString());
if (session != null)
{
// Messages within a session will always arrive in order.
Console.WriteLine("=====================================");
Console.WriteLine($"Received Session: {session.SessionId}");
while (messagesReceivedPerSession++ < messagesPerSession)
{
Message message = await session.ReceiveAsync();
Console.WriteLine($"Received message: SequenceNumber:{message.SystemProperties.SequenceNumber} Body:{Encoding.UTF8.GetString(message.Body)}");
// Complete the message so that it is not received again.
// This can be done only if the queueClient is created in ReceiveMode.PeekLock mode (which is default).
await session.CompleteAsync(message.SystemProperties.LockToken);
}
Console.WriteLine($"Received all messages for Session: {session.SessionId}");
Console.WriteLine("=====================================");
// Close the Session after receiving all messages from the session
await session.CloseAsync();
}
}
}
static async Task SendSessionMessagesAsync(int numberOfSessions, int messagesPerSession)
{
if (numberOfSessions == 0 || messagesPerSession == 0)
{
await Task.FromResult(false);
}
for (int i = numberOfSessions - 1; i >= 0; i--)
{
var messagesToSend = new List<Message>();
string sessionId = SessionPrefix + i;
for (int j = 0; j < messagesPerSession; j++)
{
// Create a new message to send to the queue
string messageBody = "test" + j;
var message = new Message(Encoding.UTF8.GetBytes(messageBody));
// Assign a SessionId for the message
message.SessionId = sessionId;
messagesToSend.Add(message);
// Write the sessionId, body of the message to the console
Console.WriteLine($"Sending SessionId: {message.SessionId}, message: {messageBody}");
}
// Send a batch of messages corresponding to this sessionId to the queue
await messageSender.SendAsync(messagesToSend);
}
Console.WriteLine("=====================================");
Console.WriteLine($"Sent {messagesPerSession} messages each for {numberOfSessions} sessions.");
Console.WriteLine("=====================================");
}
}
}
Things to consider before creating queue
1) Make sure service bus is not in the free or basic tier, if yes then scale it to Standadrd
2) Make sure to enable session while creating queue.
I am using Microsoft.Azure.ServiceBus nuget pakcage 3.4 which is latest now.If you are using some other package try to upgrade/downgrade it.
Hope it helps.

From C# after getting IBM MQ message how to identify message data type? Is it Object or String type?

In our company we are using IBM MQ server for message queueing. For the same queue we are putting both String and Object type data message with the help of methods WriteObject and WriteString.
The challenge is occured when it comes to consumption(read message) of queue. Since the Get data can be both Object or String we need to decide which method to use ReadString or ReadObject on the MQMessage instance. I made workaround like firstly using ReadObject method, if an exception occured then try it with ReadString.
I did not like this workaround, is there any way to identify message data type after calling MQQueue instance's Get method?
Here below you can find my workaround:
public object GetMessage(string queueName) {
MQQueueManager queueManager = new MQQueueManager("queueManagerName", "channel", "connection");
MQGetMessageOptions queueGetMessageOptions = new MQGetMessageOptions();
queueGetMessageOptions.Options = MQC.MQGMO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING + MQC.MQPMO_SYNCPOINT;
try {
queueRead = queueManager.AccessQueue(queueName, MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING);
queueMessage = new MQMessage();
queueMessage.Format = MQC.MQFMT_STRING;
queueRead.Get(queueMessage, queueGetMessageOptions);
try {
var readObject = queueMessage.ReadObject();
return readObject;
} catch (SerializationException) { } // if message in queue not a object
queueMessage.DataOffset = 0;
var stringMsg = queueMessage.ReadString(queueMessage.MessageLength);
return stringMsg;
} catch (MQException exp) {
if (exp.ReasonCode != 2033) {
log.ErrorFormat("MQException: ResonCode: {0}, {1}", exp.ReasonCode, exp.Message);
}
}
return "";
}
What a horrible design.
First off, why are you putting 2 different message types into the same queue? Bad, very bad idea. You should be using 2 different queues. What, does someone think queues are scarce or rare? You should be handing out queues like candy.
Secondly, if you really need to go with this design then you should read the MQ Knowledge Center on MQMD structure. It contains a field called 'Message Type'. Most applications use 'Message Type' to contain either 'MQMT_DATAGRAM' or 'MQMT_REQUEST' but you can set your own values starting with 'MQMT_APPL_FIRST'.
So, define a couple of constants:
public const int MY_MSG_OBJECT = MQC.MQMT_APPL_FIRST + 1;
public const int MY_MSG_STRING = MQC.MQMT_APPL_FIRST + 2;
Hence, the sending application putting a string message would do:
MQMessage sendmsg = new MQMessage();
sendmsg.Format = MQC.MQFMT_STRING;
sendmsg.MessageType = MY_MSG_STRING;
sendmsg.WriteString("This is a test message");
queue.Put(sendmsg, pmo);
and the sending application putting an object message would do:
MQMessage sendmsg = new MQMessage();
sendmsg.Format = MQC.MQFMT_NONE;
sendmsg.MessageType = MY_MSG_OBJECT;
sendmsg.WriteObject(someObject);
queue.Put(sendmsg, pmo);
The receiving application would do:
MQMessage rcvmsg = new MQMessage();
queue.Get(rcvmsg, gmo);
// Check the Message Type
if (rcvmsg.MessageType == MY_MSG_STRING)
{
readString = queue.ReadString();
}
else if (rcvmsg.MessageType == MY_MSG_OBJECT)
{
readObject = queue.ReadObject();
}
else
{
System.Console.Out.WriteLine("Error: Unknown message type.");
}

Servicestack RabbitMQ: Infinite loop fills up dead-letter-queue when RabbitMqProducer cannot redeclare temporary queue in RPC-pattern

When I declare a temporary reply queue to be exclusive (e.g. anonymous queue (exclusive=true, autodelete=true) in rpc-pattern), the response message cannot be posted to the specified reply queue (e.g. message.replyTo="amq.gen-Jg_tv8QYxtEQhq0tF30vAA") because RabbitMqProducer.PublishMessage() tries to redeclare the queue with different parameters (exclusive=false), which understandably results in an error.
Unfortunately, the erroneous call to channel.RegisterQueue(queueName) in RabbitMqProducer.PublishMessage() seems to nack the request message in the incoming queue so that, when ServiceStack.Messaging.MessageHandler.DefaultInExceptionHandler tries to acknowlege the request message (to remove it from the incoming queue), the message just stays on top of the incoming queue and gets processed all over again. This procedure repeats indefinitely and results in one dlq-message per iteration which slowly fills up the dlq.
I am wondering,
if ServiceStack handles the case, when ServiceStack.RabbitMq.RabbitMqProducer cannot declare the response queue, correctly
if ServiceStack.RabbitMq.RabbitMqProducer muss always declare the response queue before publishing the response
if it wouldn't be best to have some configuration flag to omit all exchange and queue declaration calls (outside of the first initialization). The RabbitMqProducer would just assume every queue/exchange to be properly set up and just publish the message.
(At the moment our client just declares its response queue to be exclusive=false and everything works fine. But I'd really like to use rabbitmq's built-in temporary queues.)
MQ-Client Code, requires simple "SayHello" service:
const string INQ_QUEUE_NAME = "mq:SayHello.inq";
const string EXCHANGE_NAME="mx.servicestack";
var factory = new ConnectionFactory() { HostName = "192.168.179.110" };
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
// Create temporary queue and setup bindings
// this works (because "mq:tmp:" stops RabbitMqProducer from redeclaring response queue)
string responseQueueName = "mq:tmp:SayHello_" + Guid.NewGuid().ToString() + ".inq";
channel.QueueDeclare(responseQueueName, false, false, true, null);
// this does NOT work (RabbitMqProducer tries to declare queue again => error):
//string responseQueueName = Guid.NewGuid().ToString() + ".inq";
//channel.QueueDeclare(responseQueueName, false, false, true, null);
// this does NOT work either (RabbitMqProducer tries to declare queue again => error)
//var responseQueueName = channel.QueueDeclare().QueueName;
// publish simple SayHello-Request to standard servicestack exchange ("mx.servicestack") with routing key "mq:SayHello.inq":
var props = channel.CreateBasicProperties();
props.ReplyTo = responseQueueName;
channel.BasicPublish(EXCHANGE_NAME, INQ_QUEUE_NAME, props, Encoding.UTF8.GetBytes("{\"ToName\": \"Chris\"}"));
// consume response from response queue
var consumer = new QueueingBasicConsumer(channel);
channel.BasicConsume(responseQueueName, true, consumer);
var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
// print result: should be "Hello, Chris!"
Console.WriteLine(Encoding.UTF8.GetString(ea.Body));
}
}
Everything seems to work fine when RabbitMqProducer does not try to declare the queues, like that:
public void PublishMessage(string exchange, string routingKey, IBasicProperties basicProperties, byte[] body)
{
const bool MustDeclareQueue = false; // new config parameter??
try
{
if (MustDeclareQueue && !Queues.Contains(routingKey))
{
Channel.RegisterQueueByName(routingKey);
Queues = new HashSet<string>(Queues) { routingKey };
}
Channel.BasicPublish(exchange, routingKey, basicProperties, body);
}
catch (OperationInterruptedException ex)
{
if (ex.Is404())
{
Channel.RegisterExchangeByName(exchange);
Channel.BasicPublish(exchange, routingKey, basicProperties, body);
}
throw;
}
}
The issue got adressed in servicestack's version v4.0.32 (fixed in this commit).
The RabbitMqProducer no longer tries to redeclare temporary queues and instead assumes that the reply queue already exist (which solves my problem.)
(The underlying cause of the infinite loop (wrong error handling while publishing response message) probably still exists.)
Edit: Example
The following basic mq-client (which does not use ServiceStackmq client and instead depends directly on rabbitmq's .net-library; it uses ServiceStack.Text for serialization though) can perform generic RPCs:
public class MqClient : IDisposable
{
ConnectionFactory factory = new ConnectionFactory()
{
HostName = "192.168.97.201",
UserName = "guest",
Password = "guest",
//VirtualHost = "test",
Port = AmqpTcpEndpoint.UseDefaultPort,
};
private IConnection connection;
private string exchangeName;
public MqClient(string defaultExchange)
{
this.exchangeName = defaultExchange;
this.connection = factory.CreateConnection();
}
public TResponse RpcCall<TResponse>(IReturn<TResponse> reqDto, string exchange = null)
{
using (var channel = connection.CreateModel())
{
string inq_queue_name = string.Format("mq:{0}.inq", reqDto.GetType().Name);
string responseQueueName = channel.QueueDeclare().QueueName;
var props = channel.CreateBasicProperties();
props.ReplyTo = responseQueueName;
var message = ServiceStack.Text.JsonSerializer.SerializeToString(reqDto);
channel.BasicPublish(exchange ?? this.exchangeName, inq_queue_name, props, UTF8Encoding.UTF8.GetBytes(message));
var consumer = new QueueingBasicConsumer(channel);
channel.BasicConsume(responseQueueName, true, consumer);
var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
//channel.BasicAck(ea.DeliveryTag, false);
string response = UTF8Encoding.UTF8.GetString(ea.Body);
string responseType = ea.BasicProperties.Type;
Console.WriteLine(" [x] New Message of Type '{1}' Received:{2}{0}", response, responseType, Environment.NewLine);
return ServiceStack.Text.JsonSerializer.DeserializeFromString<TResponse>(response);
}
}
~MqClient()
{
this.Dispose();
}
public void Dispose()
{
if (connection != null)
{
this.connection.Dispose();
this.connection = null;
}
}
}
Key points:
client declares anonymous queue (=with empty queue name) channel.QueueDeclare()
server generates queue and returns queue name (amq.gen*)
client adds queue name to message properties (props.ReplyTo = responseQueueName;)
ServiceStack automatically sends response to temporary queue
client picks up response and deserializes
It can be used like that:
using (var mqClient = new MqClient("mx.servicestack"))
{
var pingResponse = mqClient.RpcCall<PingResponse>(new Ping { });
}
Important: You've got to use servicestack version 4.0.32+.

Resources