Related
I have been working on a project using the ESP32 with the ESP-IDF that will check it's NVS memory for wifi credentials before starting the network stack. If it has said credentials, it will connect to the wifi network in STA mode, if it lacks them, it will launch as it's own AP to allow the user to send it the credentials over HTTP.
After manually putting my test credentials into NVS, I started working on the AP code. Once all the AP code and logic was complete, I manually wiped the flash memory with esptool to force the board to launch in that mode. Doing so worked fine, and I was able to send it the updated credentials over HTTP.
At this point, the board attempted to connect as STA upon reset, however, the SYSTEM_EVENT_STA_WPS_ER_PIN event kept being caught by the wifi event loop. The board has since only experienced this event and has been completely unable to connect to wifi since. To make matters stranger, even after rolling back to a previous version with git, the problem still persists.
main.c
void app_main() {
// Start NVS
initNVS();
// Init Wifi Controller
initWifiController();
// Get Credentials to send to wifi
Creds creds = getCreds();
// Start wifi in STA mode with gathered creds
beginWifi(creds);
initializePins();
initializeTimers();
}
wifiController.c
void initWifiController(){
// * NVS must be initialized before wifi work can be done
// Handle when connected to the network
connectionSemaphore = xSemaphoreCreateBinary();
// Begin network stack
ESP_ERROR_CHECK(esp_netif_init());
// Create event loop for handling callbacks
ESP_ERROR_CHECK(esp_event_loop_create_default());
}
void beginWifi(Creds creds){
if(creds.status == ESP_OK){
ESP_LOGI(TAG, "Connection credentials have been found, connecting to network");
connectSTA(creds);
}
else if(creds.status == ESP_ERR_NVS_NOT_FOUND){
ESP_LOGW(TAG, "Missing credentials, starting as AP");
connectAP();
}
else{
ESP_LOGE(TAG, "ESP failed with error %s, not starting wifi", esp_err_to_name(creds.status));
}
void connectSTA(Creds creds){
ESP_LOGI(TAG, "Attempting to connect to wifi with following creds: %s | %s", creds.ssid, creds.pass);
// Set netif to sta
esp_netif_create_default_wifi_sta();
// Prepare and initialize wifi_init_config_t
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config));
// Register tracked events for event_handler
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, event_handler, NULL));
// TODO: Check if this can be used to avoid havng to use NVS manually
esp_wifi_set_storage(WIFI_STORAGE_RAM);
// Config struct for wifi details
wifi_config_t wifi_config = {};
// Copy casted info into wifi_config
// * https://www.esp32.com/viewtopic.php?f=13&t=14611
// * See above link for details on this
strcpy((char *)wifi_config.sta.ssid, creds.ssid);
strcpy((char *)wifi_config.sta.password, creds.pass);
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
ESP_ERROR_CHECK(esp_wifi_start());
// ? Is this required to avoid a memory leak?
free(creds.pass);
free(creds.ssid);
}
void connectAP(){
// ? How important is it that these be called in this order?
ESP_LOGI(TAG, "Starting in AP Mode");
esp_netif_create_default_wifi_ap();
// TODO: maybe move this creation to initWifiController to avoid making it twice
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config));
// TODO: Consider moving this to init Wifi Controller to avoid running it twice as well
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
// Configuration for AP
wifi_config_t wifi_config = {
.ap = {
.ssid = "Grow System",
.password = "Password",
.ssid_len = strlen("Grow System"),
.max_connection = 4,
.authmode = WIFI_AUTH_WPA_WPA2_PSK
}
};
// TODO: Enable password support on AP configuration
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "Wifi connectAP finished");
registerEndPoints();
}
The code essentially checks NVS for the credentials, if it finds them both it returns a struct containing both of them as well as ESP_OK. If one of them was not found, the struct instead contains ESP_ERR_NVS_NOT_FOUND. wifiController.c then receives this creds struct and calls beginWifi() which then either calls connectSTA() or connectAP() based on the status of the struct. When the credentials are present, connectSTA() is called, but for unknown reasons the event loop consistently only receives the SYSTEM_EVENT_STA_WPS_ER_PIN event. As I mentioned earlier, even after rolling my code back to a version that did not have the connectAP() function, this behavior persists.
Because of this, I have a hunch that the issue may be related to when I wiped the flash manually, as opposed to the code.
The header file contains the following line in it's typedef to define this event.
SYSTEM_EVENT_STA_WPS_ER_PIN, /*!< ESP32 station wps pin code in enrollee mode */
I do not know what that means, as I have not intentionally included anything regarding wps in this project.
So far my research hasn't returned anything incredibly useful, so if anyone has any ideas what SYSTEM_EVENT_STA_WPS_ER_PIN is or what could be causing my issue, I would be very appreciative. If you think that anymore detail would be useful to solve this issue, please let me know and I will be more than happy to provide it.
Useful to solve the problem.
I'm in the proces of learning to use the ESP32 wifi, read your message checked, the ESP-idf and esp-32 technical manual not much info there I found this URI
https://www.wi-fi.org/downloads-public/Wi-Fi_Protected_Setup_Best_Practices_v2.0.2.pdf/8188
Kind regards
Update: check the sdkconfig file in your projectmap against the one in the example map for wifi config settings.
I have been digging into this issue for several days now and I have not found the root cause but have managed to discovery a workaround and some details about the issue. the SYSTEM_EVENT_STA_WPS_ER_PIN event that kept arising actually is caused by the chip trying to use WPS Enrolle Pin mode to connect to the router. Supposedly this generates an eight digit long pin that can be put into your router which should allow it to connect. I really do not know why it was doing this, but I believe it may have had something to do with how I had AP mode set up. My primary confusion now is why rolling back the code did not fix it.
For the "workaround" I found that flashing Espressif's example STA wifi connection code managed to solve it. The chip properly connected to my network once it was flashed, and I was able to reflash my own code without any issues arriving. This seems extremely strange to me, so part of me thinks that maybe the chip just couldn't connect to my network for some reason and an edge case in the code caused it to go into enrollee mode.
Here is a link to the code that I used to "fix" the issue: https://github.com/espressif/esp-idf/blob/master/examples/wifi/getting_started/station/main/station_example_main.c
I will mark this answer as correct and continue looking for the root problem. In the event that someone else know what actually could have caused this, feel free to post and I will update the correct answer. In the event that I find what the root problem is, I will update this answer as well.
EDIT: After continuing to dig, I believe that the problem was actually do to a multitude of errors in my code. Particularly, I was calling esp_netif_create_default_wifi_sta() and then not setting the WI-FI mode. I needed to add esp_wifi_set_mode(WIFI_MODE_STA), which was absent in my program. I believe setting the network stack to sta without changing the wifi mode was what caused my issue.
This is a follow-up to my previous question, Need to write driver for USB peripheral device?
Background
I'm working on designing a USB peripheral using an STM32 microcontroller (bare metal / no OS). The device will occasionally be connected to a Windows PC, and transfer a few KB of data in each direction. There will be a custom PC application that controls the data transfers, using a proprietary protocol (i.e. for the USB payloads).
The PC will always be the master (initiator) - it'll send commands, and the device will issue responses, with up to a few hundred bytes of data going in either direction in a single command or response. I think I'll want to use USB Bulk Transfer mode.
Option 1 - USB CDC
From what I understand, one option is I could use the USB Communications Device Class (CDC). On the device side, I could use sample code from ST for the USB CDC, e.g. from STM32Cube. On the PC side, the device would present as a Virtual COM Port (VCP). Then in software I'd basically have a raw, bidirectional stream, on top of which I'd have to define my messsage formats, commands, etc.
Have I explained this correctly?
Option 2 - WinUSB
I'm having trouble wrapping my mind around exactly what this is, and how to work with it.
What is the relationship of WinUSB to USB device classes? It seems to function as a "generic" USB class, but I can't find any documentation that spells it out as such.
Does WinUSB provide any built-in message delimiters? e.g. Does WinUsb_WritePipe send the contents of the buffer down to the device as an atomic unit? Or do I just get raw streams like a VCP/UART?
How does one implement WinUSB on the device? Is there sample code available? (Preferably for STM32.)
Choosing
What are the relevant considerations in choosing between options 1 and 2 for my application?
Yes, you described USC CDC ACM correctly.
WinUSB exists to support devices that do not have a particular device class. If your device implements a device class such as Human Interface Device, Mass Storage Device, or Communications Device (CDC), you can just use the drivers that come with your operating system to talk to that device. If you want a more customizable and flexible USB interface that doesn't conform to one of those classes, you can use WinUSB to talk to your device. You could also write your own driver if you want, but that is going to be a lot of work and I wouldn't recommend it. Some people have written drivers that are alternatives to WinUSB: you can look up libusbK, libusb0.sys, and UsbDK for examples. WinUSB has the advantage that it comes with Windows so I wouldn't use one of those other drivers unless it has a specific feature you really need.
I believe that WinUSB_WritePipe sends the data as a single USB transfer. A transfer has a specific definition in the USB specification. You can tell when a transfer ends because you will get a short packet at the end of the transfer. A short packet is a packet that is smaller than the maximum packet size of the endpoint, and it could possibly be zero-length. You should double check whether that is actually true though; try sending a transfer that is a multiple of the maximum packet size and make sure that Windows sends a zero-length packet at the end of that. By the way, you should consider sending your data as a control transfer or series of control transfers on endpoint 0. Control transfers have a built-in concept of a request and a response to the request. Despite the name, control transfers can be used to transfer large amounts of data; they are commonly used in the USB bootloaders (see the DFU class). Another advantage of using control transfers instead of non-zero endpoints is that you don't have to add extra endpoint descriptors and initialize the endpoints in your firmware. Your USB stack should have the machinery for handling custom control transfers and you should be able to make custom control transfers just by writing a few callback functions.
To implement WinUSB on the device side, you would need to write your own USB descriptors and then use low-level USB transfer commands to read and write data from endpoints, or to handle vendor-specific control transfers on endpoint zero. I am not familiar with the STM32 USB libraries, but you should be able to identify the core component of it that implements control transfers and IN and OUT endpoints, without doing anything specific to a device class. That is the component that you would need to learn how to use.
By default, you should use WinUSB instead of USB CDC ACM. The only reason to use USB CDC ACM is if your device is actually a serial port or if you want to make it easier for people to talk to your device in a variety of programming languages and environments. Most programming languages support serial ports, but the user would still have to write the code on top of that that generates your particular command format, so it doesn't actually give you that much. One problem with USB CDC ACM is that if the device gets disconnected while you have a handle open to it, and then it gets reconnected, the various USB CDC ACM drivers can often get into a bad state. In particular, usbser.sys prior to Windows 10 does not handle this well, and you usually have to unplug and replug the device to make the COM port usable again. USB CDC ACM uses bulk endpoints for its data transfer, so there is no latency guarantee. With WinUSB, you have the option to use Interrupt endpoints so that you can be guaranteed to always have one packet transferred for every USB frame.
WinUSB consists of two parts:
WinUsb.sys is a kernel-mode driver that can be installed as either a filter or function driver, above the protocol drivers in a USB device’s kernel-mode device stack.
WinUsb.dll is a user-mode DLL that exposes the WinUSB API. Applications can use this API to communicate with WinUsb.sys when it is installed as a device’s function driver.
WinUSB API—exposed by WinUSB.dll. WinUSB is included in the Windows Driver Kit (WDK) in the form of a co-installer package, WinUSBCoInstaller.dll, located in WinDDK\BuildNumber\Redist\Winusb.
To use the WinUSB API in an application:
Include WinUsb.h
Add WinUsb.lib to the list of libraries that are linked to your application.
Usb100.h contains declarations for some useful macros.
Use the device interface GUID to obtain the device path. The correct GUID is the one that you specified in the INF that was used to install WinUsb.sys.
Get a handle to the device information set by passing the device interface GUID that you defined in the INF to SetupDiGetClassDevs. The function returns an HDEVINFO handle.
Call SetupDiEnumDeviceInterfaces to enumerate the system’s device interfaces and obtain information on your device interface.
Call SetupDiGetDeviceInterfaceDetail to get detailed data for the device interface.
Call the GetDevicePath function to obtain the device path.
Pass the device path to CreateFile to obtain a file handle for the device. Use ReadFile and WriteFile to communicate with device.
Pass the file handle to WinUsb_Initialize to initialize WinUSB and obtain a WinUSB handle. You use the device’s WinUSB handle to identify the device when you call WinUSB API functions, not the device’s file handle.
For more advanced solutions - use functions:
WinUsb_QueryDeviceInformation to obtain the device’s speed.
WinUsb_QueryInterfaceSettings to obtain the corresponding interface descriptors. The WinUSB handle corresponds to the first interface.
WinUsb_QueryPipe gets information about each endpoint.
WinUsb_WritePipe writes the buffer to the device - default behavior: zero-length writes are forwarded down the stack. If the transfer length is greater than a maximum transfer length, WinUSB divides the request into smaller requests of maximum transfer length and submits them serially.
more functions and info: http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/winusb_howto.docx
For debugging purposes You probably need:
winusbtrace_tool https://blogs.msdn.microsoft.com/usbcoreblog/2010/02/05/how-to-generate-and-view-a-winusb-debug-trace-log/;
Wireshark https://www.wireshark.org with USBPcap plugin.
Other Example:
http://searchingforbit.blogspot.com/2012/04/winusb-communication-with-stm32-part-1.html.
Sample template comes with Visual Studio.
You need also have knowledge of writing .inf files.
Another easy way to communicate with USB - libusb-win32 https://sourceforge.net/projects/libusb-win32/
My simple example console application sends small (for keep-alive) chunks of data to device:
#include "stdafx.h"
#include <SetupAPI.h>
#include <Hidsdi.h>
#include <devguid.h>
#include <winusb.h>
#include <usb.h>
#pragma comment(lib, "hid.lib")
#pragma comment(lib, "setupapi.lib")
#pragma comment(lib, "winusb.lib")
#include <iUString.h>
iString<char> DevicePath;
bool WinusbHandle_Open=false;
bool DeviceHandle_Open = false;
WINUSB_INTERFACE_HANDLE WinusbHandle;
HANDLE DeviceHandle;
UCHAR usb_out_buffer[64];
DEFINE_GUID(GUID_DEVCLASS_WINUSB, 0x88bae032L, 0x5a81, 0x49f0, 0xbc, 0x3d, 0xa4, 0xff, 0x13, 0x82, 0x16, 0xd6);
DEFINE_GUID(GUID_DEVCLASS_STL, 0xf177724dL, 0x74d3, 0x430e, 0x86, 0xb5, 0xf0, 0x36, 0x89, 0x10, 0xeb, 0x23);
GUID winusb_guid;
GUID stl_guid;
bool connectusb();
void disconnectusb();
int main()
{
DWORD n;
DWORD numEvents;
HANDLE rHnd;
WinusbHandle_Open = false;
DeviceHandle_Open = false;
winusb_guid = GUID_DEVCLASS_WINUSB;
stl_guid = GUID_DEVCLASS_STL;
usb_out_buffer[0] = 0;
usb_out_buffer[1] = 1;
usb_out_buffer[2] = 2;
usb_out_buffer[3] = 3;
ULONG bytesWritten;
ULONG timeout;
timeout = 100;
rHnd = GetStdHandle(STD_INPUT_HANDLE);
WinUsb_SetPipePolicy(WinusbHandle, 0x01, PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout);
timeout = TRUE;
WinUsb_SetPipePolicy(WinusbHandle, 0x01, AUTO_CLEAR_STALL, sizeof(ULONG), &timeout);
timeout = TRUE;
WinUsb_SetPipePolicy(WinusbHandle, 0x01, RAW_IO, sizeof(ULONG), &timeout);//Bypasses queuing and error handling to boost performance for multiple read requests.
while (true)
{
if ((!WinusbHandle_Open) || (!WinusbHandle_Open)) { if (!connectusb())Sleep(2000); }
if ((!WinusbHandle_Open) || (!WinusbHandle_Open))continue;
bytesWritten = 0;
if (!WinUsb_WritePipe(WinusbHandle, 0x01, &usb_out_buffer[0], 2, &bytesWritten, NULL))
{
n = GetLastError();
disconnectusb();
}
Sleep(2000);
}
disconnectusb();
return 0;
}
bool connectusb()
{
BOOL bResult = FALSE;
HDEVINFO deviceInfo;
SP_DEVICE_INTERFACE_DATA interfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
DWORD n;
SP_DEVINFO_DATA devinfo;
BYTE devdetailbuffer[4096];
bool found;
deviceInfo = SetupDiGetClassDevs(&stl_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (deviceInfo == INVALID_HANDLE_VALUE) { return false; }
found = false;
for (n = 0;; n++)
{
interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if (!SetupDiEnumDeviceInterfaces(deviceInfo, NULL, &stl_guid, n, &interfaceData))
{
n = GetLastError();
break;
}
detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)devdetailbuffer;
detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
devinfo.cbSize = sizeof(devinfo);
if (!SetupDiGetDeviceInterfaceDetail(deviceInfo, &interfaceData, detailData, sizeof(devdetailbuffer), NULL, &devinfo)) { printf("SetupDiGetDeviceInterfaceDetail: %u\n", GetLastError()); break; }
if (IsEqualGUID(devinfo.ClassGuid, winusb_guid))
{
if ((-1 != iStrPos(detailData->DevicePath, "VID_0483")) || (-1 != iStrPos(detailData->DevicePath, "vid_0483")))
{
if ((-1 != iStrPos(detailData->DevicePath, "PID_576B")) || (-1 != iStrPos(detailData->DevicePath, "pid_576b")))
{
DevicePath = detailData->DevicePath;
found = true;
break;
}
}
}
}
SetupDiDestroyDeviceInfoList(deviceInfo);
if (!found)return false;
DeviceHandle = CreateFile(DevicePath.Buffer() ,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if (INVALID_HANDLE_VALUE == DeviceHandle) {
n = GetLastError();
}
if (INVALID_HANDLE_VALUE == DeviceHandle) return false;
DeviceHandle_Open = true;
if (!WinUsb_Initialize(DeviceHandle, &WinusbHandle))
{
n = GetLastError();
CloseHandle(DeviceHandle); DeviceHandle_Open = false;
return false;
}
WinusbHandle_Open = true;
return true;
}
void disconnectusb()
{
if (WinusbHandle_Open) { WinUsb_Free(WinusbHandle); WinusbHandle_Open = false; }
if (DeviceHandle_Open) { CloseHandle(DeviceHandle); DeviceHandle_Open = false; }
}
I also have to do your exact same requirement: PC <==> STM
Microsoft has lots of documentation on WinUSB. Here is what I've seen that answers your questions...
Custom USB device sample
https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CustomUsbDeviceAccess
Developing Windows applications for USB devices -- C# AND VB
https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/developing-windows-applications-that-communicate-with-a-usb-device
Windows desktop app for a USB device
https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/windows-desktop-app-for-a-usb-device
How to Access a USB Device by Using WinUSB Functions
https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/using-winusb-api-to-communicate-with-a-usb-device
Developing Windows drivers for USB host controllers
https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/developing-windows-drivers-for-usb-host-controllers
Windows.Devices.Usb Windows.Devices.Usb Namespace
https://learn.microsoft.com/en-us/uwp/api/windows.devices.usb
I solved this request so I understand your intention is about to make your firmware could be enumerated as a WINUSB (winusb generic driver) device automatically by Windows while plugging-in.
I believe it'd be clear if you have a demo and code so I made one for you :)
My KEIL project using the STM32F4 Discovery board working with WINUSB as an USB CDC device.
You can see more information and have the source code from my GitHub.
For deploying WINUSB it's necessary to manually modify USB device and middleware layers source code in the KEIL project.
You can focus on usbd_ctlreq.c, usbd_cdc.c and usbd_desc.c to have a comparison with origins generated by CubeMX.
let's say we have a P2P multi-player Flash based game hosted on a website. Would it be possible to create a browser extension that would listen to what is going on within the Flash application? For example, I would like to know when a player connects to a room, gets kicked or banned, or simply leaves by himself. I'm sorry this is not really a specific question but I need a direction to start. Thanks in advance!
I can see a few ways to communicate between Flash and a browser plugin.
One is to open a socket to a server running on the local machine. Because of the security sandbox, this may not be the easiest approach, but if feasible, it is of course probably the one to go for because you've already got your socket-handling code written, and listening/writing to a additional socket isn't terribly complicated. For this approach, you just need your plugin to start listening on a socket, and get the flash applet to connect to it.
Another way might be to try something with passing messages in cookies. Pretty sure this would just cause much grief, though.
Another way, and I suspect this may turn out to be the easier path, is to communicate between Flash and JavaScript using the ExternalInterface class, then from JavaScript to the plugin. Adobe's IntrovertIM example should get you started if you can find a copy on the web.
In Flash, create two functions, a jsToSwf(command:String, args:Array<String>):Dynamic function, to handle incoming messages from JS that are sent to that callback, and a swfToJs(command:String, args:Array<String> = null):Dynamic function, which calls flash.external.ExternalInterface.call("swfToJs", command, args);.
To set it up, you need to do something like:
if (flash.external.ExternalInterface.available) {
flash.external.ExternalInterface.addCallback("jsToSwf", jsToSwf);
swfToJs("IS JS READY?");
}
(The two parameters to addCallback are what the function is called in JS, and what it's called in Flash. They don't have to be the same thing, but it sort of makes sense that they do)
In JS, you need the same functions: function swfToJs(command, params) accepts commands and parameter lists from Flash; and jsToSwf(command, params) calls getSwf("Furcadia").jsToSwf(command, params);.
getSwf("name") should probably be something like:
/** Get ref to specified SWF file.
// Unfortunately, document.getElementById() doesn't
// work well with Flash Player/ExternalInterface. */
function getSwf(movieName) {
result = '';
if (navigator.appName.indexOf("Microsoft") != -1) {
result = window[movieName];
} else {
result = document[movieName];
}
return result;
}
The only fiddly bit there is that you need to do a little handshake to make sure everyone's listening. So when you have Flash ready, it calls swfToJs("IS JS READY?"); then the JS side, on getting that command, replies with jsToSwf("JS IS READY!"); then on getting that, Flash confirms receipt with swfToJs("FLASH IS READY!"); and both sides set a flag saying they're now clear to send any commands they like.
So, you've now got Flash talking with JS. But how does JS talk with a browser extension? And, do you mean extension, or add-on, since there's a difference! Well, that becomes a whole 'nother can of worms, since you didn't specify which browser.
Every browser handles things differently. For example, Mozilla has port.emit()/port.on() and the older postMessage() as APIs for JS to communicate with add-ons.
Still, I think ExternalInterface lets us reduce a hard question (Flash-to-external-code comms) to a much simpler question (Js-to-external-code comms).
Hey all i am trying to send a text message from a virtual machine (VMWARE) to my local machine so that i can hit a button in the VM and have it do something on the local.
Is there anyway to send a text through an IP, TCP/IP, LAN using VB6 or VB.net? I was looking at the net send to send something but it doesn't seem to work for me (as well as it seems to pop up a dialog box for every text you send). I've already tried this out:
http://www.codeproject.com/KB/vb/CfSimpleSendComp.aspx
But it doesn't seem to work at all on my computer? I've tried both the IP of the machine and also the computer's name. Maybe .NET Remoting in VB?
Could anyone let me know if there are other ways to do what i would like to do?
Thanks!
David
You also can consider to use Eneter Messaging Framework.
It is lightweight and very easy to use.
I am sorry, I am not familiar with VB syntax, but in C# the whole implementation
is here: (You can copy paste the code into your project, include Eneter.Messaging.Framework.dll and change the IP to yours.)
The server listening to string messages.
using System;
using Eneter.Messaging.EndPoints.StringMessages;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;
using Eneter.Messaging.MessagingSystems.TcpMessagingSystem;
namespace StringReceiver
{
class Program
{
static void Main(string[] args)
{
// Create Tcp based messaging.
IMessagingSystemFactory aTcpMessaging = new TcpMessagingSystemFactory();
IInputChannel anInputChannel = aTcpMessaging.CreateInputChannel("127.0.0.1:7091");
// Create string message receiver
// Note: it is possible to receiver typed messages too.
IStringMessagesFactory aStringMessagesFactory = new StringMessagesFactory();
IStringMessageReceiver aStringMessageReceiver = aStringMessagesFactory.CreateStringMessageReceiver();
aStringMessageReceiver.MessageReceived += StringMessageReceived;
// Attach the input channel to the string message receiver
// and start listening.
Console.WriteLine("String sercer is listening.");
aStringMessageReceiver.AttachInputChannel(anInputChannel);
}
// Processing messages.
static void StringMessageReceived(object sender, StringMessageEventArgs e)
{
Console.WriteLine("Received message: " + e.Message);
}
}
}
The client sending the string messages:
using Eneter.Messaging.EndPoints.StringMessages;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;
using Eneter.Messaging.MessagingSystems.TcpMessagingSystem;
namespace StringMessageSender
{
class Program
{
static void Main(string[] args)
{
// Create Tcp based messaging.
IMessagingSystemFactory aTcpMessaging = new TcpMessagingSystemFactory();
IOutputChannel anOutputChannel = aTcpMessaging.CreateOutputChannel("127.0.0.1:7091");
// Create string message receiver
// Note: it is possible to receiver typed messages too.
IStringMessagesFactory aStringMessagesFactory = new StringMessagesFactory();
IStringMessageSender aStringMessageSender = aStringMessagesFactory.CreateStringMessageSender();
// Attach the output channel to the string message sender
// so that we can send messages via Tcp to desired Ip address.
aStringMessageSender.AttachOutputChannel(anOutputChannel);
// Send message.
aStringMessageSender.SendMessage("Hello world.");
}
}
}
Eneter Messaging Framework can be downloaded at www.eneter.net.
If you would like to get more technical info: www.eneter.net/OnlineHelp/EneterMessagingFramework/Index.html
More examples: eneter.blogspot.com
You need a client and a server, one of them at each end. These could communicate over TCPIP (TCP or UDP), Microsoft Networking (named Pipes, Mailslots), or whatever you have. Some options depend on what OS the two machines are running, but since you mentioned NET SEND we can probably assume some flavor of Windows.
The Messenger Service is gone in later versions of Windows NT (Vista, Windows 7) so it's not the best option. There are other Mailslots messengers though as well as lots of UDP messengers.
The real question is what action you want to perform "at the push of a button." Heck, you could easily run Telnet if that gave you what you were after.
Don't forget you may have to open firewalls for any of these to work though.
.Net Remoting isn't available in VB, you must mean VB.Net. That's a remote object invokation technology though and probably not what you want.
You'd probably get to a result more quickly picking one development tool set and using whatever it offers for TCP or UDP sockets.
There are several ways. The best way depends on how you define 'text message'.
If you literally just need to hit a button and run a command on a remote machine, I would run PsExec in Process object. Cheesy but effective. Something like:
Using p as new Process()
p.StartInfo.FileName = "c:\path\to\PsExec.exe"
p.StartInfo.Arguments = "\\RemoteComputerName RemoteCommand.exe"
p.Start()
End Using
If you need bi-directional communication with a custom protocol, I would use WCF or the TCPListener and TCPClient classes to create your own socket server and client.
I would stay away from remoting.
I need to configure USB OTG on iMX31 for device mode. We need a raw channel between the host and target and usb seems to be the best suited. However I haven't been able to correctly configure the OTG controller. I dont know what I am missing. I have performed the steps mentioned in section 32.14.1 of iMX31 Reference Manual. I have also configured PORTSC1 register for ULPI.
Can any one help me out here? any poineters/code/any thing that can help me is welcome.
Thanks
The litekit is supported by the vanilla Linux kernel.
It's pretty easy to declare the OTG for device mode. You just need to declare it as device when you register your device:
static struct fsl_usb2_platform_data usb_pdata = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_ULPI,
};
Register code:
mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
Don't forget to configure the pads for the physical ULPI lines, and eventually make the initial transactions for your transceiver.
You can find all the necessary code as I did it for the moboard platform and the marxbot board file.