Developing a Mac OSX Network Driver for a Serial Port AT Command Based Modem - macos

First allow me to say that I don't have any experience developing drivers for OSX, nor drivers for Windows. So, there are a lot of things that I don't understand about how drivers work; I'm sure it'll be evident in my question.
I have a modem that is able to open and close TCP/UDP sockets using AT commands. I would like to create some kind of program (kernel extension? driver?) that implements a network driver, converting the network interface calls into AT command serial messages.
That's the basic jist of it. I'm essentially asking if anybody can point me in the right direction / give me a high level overview of how they would approach it and what Apple guides to focus on.

The XNU networking stack -- like most network stacks -- expects network devices to send and receive IP packets directly. It isn't tooled to work with network devices that handle part of the network stack (like TCP or UDP) internally -- it won't be possible to implement a network driver which uses this device.
You might have more luck exposing this device as a SOCKS proxy. You will need to write a userspace daemon which listens on a TCP port on localhost (on the computer) and relays traffic to the serial device; once that's done, you can set the computer to use that device as a SOCKS proxy in the Networking control panel.
(As an aside: most devices that implement this type of interface have a very low limit on the number of open sockets -- often fewer than 10. They're unlikely to be able to handle the network load generated by a desktop OS.)

Related

USB stack confusion/serial emulator

I am looking at implementing USB communication on a MCU which has a USB engine built into it. Basically you have access to the pipes/endpoints.
I am a little bit confused on the USB stack now. It appears that drivers operate on another level above the pipe/endpoint setup, so the pipe/endpoint is like a middle level layer that drivers are built on. Is this correct?
Secondly, I am interested in simulating serial communication over USB. It appears windows has a premade driver so on the computer side I do not need to program the pipe level.
How do I find out what I need to implement on the MCU to make it behave correctly with the generic serial driver?
This is an answer to your second question regarding the serial communication.
The USB standard defines a communication device class (CDC) for serial communication. The required drivers on the host side are implemented by Windows, macOS, Linux and many more operation systems.
The relevant CDC subclass is PSTN. The relevant documents are found in Class definition for Communication Devices 1.2.
The device basically implements four endpoints:
Control endpoint for configuration requests (baud rate, DTR state etc.). Have a look at SetLineCodeing, GetLineCoding and SetControlLineState.
Bulk endpoint for USB to serial transmission
Bulk endpoint for serial to USB transmission
Interrupt endpoint for notifications (DCD state, errors). See SerialState.
And of course you need to get the device descriptor right.
On top of that, you need to implement all the standard USB requests.
Chances are high that this has already been written for your MCU, both the standard requests and the serial communication. So why not use the existing code?

snmp network discovery identify mac address of device connected to a router

i am working on a network discovery program which employs snmp to discover devices in the network. My program takes the router-ip as input, scans the iprotetable(iprouttenext hop),to determine if any other routers are connected to it. for non router devices (like switch) the algorithm scans the arptable (ipnettomediatable) of the router, but cant find the connected switch unless i ping from the switch to the router. is there any way where i can determine the device connected directly to the router ..?
Getting the devices connected to a router or switch is not that easy. Switches usually maintain a MAC forwarding database where it stores which MAC address has been seen on which switch port. This table can be easily read by using the bridge MIB. Unfortunately, there are several issues to take care of:
Those entries disappear again, when a device to the switch has been switched off or is simply not communicating. Usually, the entries in the MAC forwarding tables age out after 5 minutes or so.
The fact that a MAC address has been seen on a switch port doesn't mean that the device having the mac address is directly connected to the port. There might be any number of other switches, routers or hubs inbetween.
Some manufacturers like Cisco or HP use their own protocols to determine the network topology. There are several protocols (that area usually also available through a SNMP MIB):
CDP (Cisco Discovery Protocol): This is a proprietary protocol developed by Cisco to expose network topology information. Some vendors licensed this technology and implement that protocol in their products.
LLDP (Link Layer Discovery Protocol): A standard similar to CDP, but without paying Cisco license fees :-)
And many more. I know kthat Extreme Networks has their own protocols and I am pretty sure that other vendors have them as well.
The problem with those protocols is when you have a mixed environment. Cisco switches talking CDP do not understand Extremen Network's protocol and vica versa.
If your goal is to find IP addresses to discover, then you might use the ARP caches for routers. Scanning the ARP caches for switches makes no real sense, because they're operating on layer 2.
I was using broadcast message for my java snmp agent

how to convert RS232 communication to TCP/IP communication

I have a created hardware communicating application using RS232 protocol in MFC. But as there is problem regarding voltage signal strength, i would like to shift from RS232 to TCP/IP.
Can anyone help me on this topic...?
The solution is to extend the microcontroller board with a serial device server.
Known brands are Lantronix or Moxa, but there are many other options and manufacturers. For an "embedded" solution that is integrated on your board, the "Lantronix XPort" is a typical product.
http://www.lantronix.com/device-networking/embedded-device-servers/xport.html
(I'm not affiliated with the Lantronix company.)
The Serial Device Server will connect to your RS232 on one end, and on its TCP/Ethernet side it offers usually a TCP server. It is usually configurable via network, through a built-in web interface, much like an Internet router.
Your PC application then needs to be changed as follows: Instead of opening a Windows COM port, you need to make a TCP client connection to that server, on a preconfigured TCP port. (Lantronix has 10001 as the default TCP port for this.)
But there is also special Windows driver software that lets you talk to your Serial Device Server / your microcontroller through a "virtual COM port". This is sometimes the best solution for legacy PC applications, where you cannot change the original code and have to use a Windows COM port. For a MFC application this might be a good choice.

Mac - Virtual Serial Port

I need to create a Cocoa app that will create a virtual serial port available to other apps, meaning registered in the IO Kit Registry.
Gist of the app:
Create a virtual serial port (listed in /dev and registered with the IOKit Registry)
Initiate a tcp connection out to another computer
Proxy everything received on the virtual serial port out to the
network and vice versa.
This app will be used by third party apps that talk to serial ports on the computer, allowing for the particular serial device to be located across the network. The Cocoa and network part is no problem, I've written several apps that talk over the network. My hangup is the serial port.
I've done the test with socat/netcat/minicom to verify that it all works to proxy pty/tty traffic over the network but the tty I use doesn't show up as usable by random applications because it's not registered in the IO Kit Registry.
While I can use a pty/tty master/slave for the communication, I need this slave tty to show up to Mac applications. What would be very handy is a way to register a tty in the IO Kit Registry.
Do I really need to create a custom IOKit kext driver that gets registered at Cocoa app runtime? If so, I have a big learning curve ahead of me. Where should I start reading? Or, can I use IOKit to create a virtual serial port and register it as a usable serial port for applications without having to load any kernel extensions?
Thank you for any help you can provide,
Stateful
First of all, have you checked if you can borrow a solution from this app? It's not obvious from the website if they've managed to get their virtual serial ports fully integrated into the system.
If there is a way to do it from user space, I'm not aware of it. The user-space IOKit API generally doesn't let you create class instances, let alone new device driver classes. Maybe you can somehow otherwise persuade the Cocoa libraries to find it despite not being registered in the kernel.
I don't know if you could get away with creating a "dummy" serial port in the kernel and then move your tty into its place in /dev from your userspace daemon. Maybe that's an option.
In case you do have to do it all in the kernel:
The virtual driver itself shouldn't be too much work, at least, though it will require some time to get up to speed with kernel dev. Unfortunately, the documentation is pretty thin for serial port drivers - the key is subclassing the IOSerialDriverSync abstract class. Just about the only description I've seen is in Ole Henry Halvorsen's OSX and iOS Kernel Programming book. It also has a fragment of an example for the reading & writing operations. (disclosure: I was one of the tech reviewers for this book; I don't receive any incentives for recommending it - in this case it's literally the only documentation I know of) You can find the source for a complete serial port driver in Apple's USBCDC driver, AppleUSBCDCDMM is the class that actually represents the serial port node.
It's relatively straightforward to open a so-called "kernel control" socket in the kernel, the individual APIs are documented here; from user space you use the normal BSD socket send/recv APIs. (this is also described in the aforementioned book) Your daemon can then connect to that, and all you'd need to do is push the data between the socket and the virtual serial port device. You'll need to handle disconnect events and such correctly of course.
Still, I think this is achievable as a first kernel project for an experienced C programmer (with some C++).
I hope that helps!

Looking for a GSM modem advice

My application communicates with several GSM electric controllers, that means that I have to send anywhere between one to twenty messages every few hours. right now I'm working with HUAWEI Mobile Connect - 3G. it is a USB device that uses a comm port for the pc communication and I'm using GSMComm to send messages and read/delete messages from the device.
Every two seconds I'm checking the device's storage, and if there is any message, I will then read it and store it locally and then clear the device's storage. I'm not sure if I'm working correctly, but it seems to me as if it is a very unreliable device:
Every time I boot my machine, I must remove the device from the USB or my machine will get stuck at the BIOS start up screen (or whatever the name is).
Very frequently the comm port can become unavailable for some reason. I have to close and re open the port, and at times that may not even help.
In the production machine of my client, when he uses one of his software's that utilize the first comm port, he will get a warning message from the software about problems in the port if the device is plugged in (the device port is around 28 or something).
If you've been using a device which you consider reliable, or have been working with the same device as I work with, or you just think that I'm doing it wrong, I'd like to get an advice from you.
Thanks.
This sounds like an issue with your modem. Have you tried any other models? Consumer USB models tend to be unreliable. The preferred method, though slightly more expensive, is using a commercial grade modem in situations where you need the reliability.
Some modems to look at:
Wavecom Fastrack
Sierra Wireless Airlink
These use a serial port or ethernet to communicate with the host which is far more reliable. Serial ports may not be available in your particular situation but even a USB to RS232 adapter will be more reliable.
One further option is to use a smartphone, there are several applications that you can act as a gateway through HTTP.
SMS Gateway for Android:
https://market.android.com/details?id=eu.apksoft.android.smsgateway&hl=en
i have not used this method, but it seems like some people are having luck with it. it may not be any more reliable then your USB modem though.
Hope that answers your question.
I have used WaveCom's modem for sending messages in bulks and found it to be reliable. One difference though, in my implementation was i used Kannel as an SMSC, so my queues were automatically handled by Kannel. But sending multiple requests like 40+ per minute didnt pose any problems for me.
Hope this helps.

Resources