What data type should I use to store an IP Address? - iphone

I suddenly just thought of this and got stuck deciding which data type should I use to store an IP Address?
I have thought of NSString; But if I would need the last digit for identifications, should I use float or double? And that is also another problem, since when can float or double have more than 1 decimal point?
I am probably asking the question wrongly, because I really don't know how to ask this.
The IP Address comes from an XML format <IP>192.168.1.1</IP>. Any idea how I should do this?

Use NSString. You are not going to do arithmetic with it. If you need the separate components you can use NSArray, but NSString will serve you well for just storing the IP address.
In response to your needs, you can always obtain the last character in your string using the NSString method:
NSString *lastCharacter = [ip_string substringFromIndex: [ip_string length] - 1];
Where ip_string is the string holding the IP address.
Edit in response to comment:
Logan's code is storing each element in the IP address separated by a period into an array. So if the IP address is 192.168.1.1, the array will equal (192, 168, 1, 1).
My code is storing the entire IP address in a string, and then obtaining the last character in that string. [ip_string substringFromIndex: [ip_string length] - 1] is just obtaining the last character in the string containing the IP address. The last character can be found at minus one character.
So if the IP address is 192.168.1.1, the lastCharacter string will just contain the number 1.
I suggested that code because you stated that you needed to do something with the last character in your IP address string, and my code shows how you can obtain the last character.

Use a string. You don't need to perform arithmetic on the IP do you?

It is typical to store IP addresses as strings, or arrays of integers. Another option is to store it as a 32 bit integer. It really comes down to what you want to do.

I would use NSString. If you need to get it piece by piece, use:
NSArray *pieces = [ipAddress componentsSeparatedByString: #"."];

192.168.1.1 is considered the default IP for numerous home high-speed wireless routers. It had been initially utilized by Linksys and yet has been seen used in a number of other home network products including some of those manufactured by Netgear and also Westell among others.
Even though IP address stands out as the default ip for a lot of high speed broadband wireless routers, this does not essentially has to be. A large number of producers set the default IP address to 192.168.1.1 as a way to market a standard precessing conditions and to make it simpler for very first time clients to setup their own networking systems simply and efficiently.
May only Linksys as well as other wireless routers operate using the 192.168.1.1 IP?
Certainly no, given that 192.168.1.1 is definitely a non-public IPv4 address, any type of laptop or computer, modem, switch, or another web system might be devised to work with this unique IP. Nonetheless, it's not in most cases advisable because there are lots of products which default to 192.168.1.1 which in turn interaction issues can occur soon after from many different products utilizing the same IP. It's also really important to consider that a single network equipment might have just one single Ip, if you own numerous units using private IP address, basically at least one has to be adjusted to an alternative location.

Related

How to read Analog Output Holding Registers on Advantech ADAM 6717 through ModBus TCP

I've been exploring the ADAM 6717 from Advantech.
This is the ModBus address table for said device:
At first I wanted to modify the value of the Digital output channel 0(DO0), so, as can be seen from the picture above, such address is the 0x0017.
I succeed at this by using a ModBus tool and the following settings:
Sending either "On" or "Off", turns On and off a LED connected to that output. Everything runs smoothly according to my expectation up to this point.
The problem arises when I want to read the Analog Input channel 6 or equivalently, address 400431~40044.
Since that address lies on the Analog Output Holding Registers part of the address table, I though that the following settings would accomplish the job:
However, as can be seen above, the reading shows 0.0 when there is actually 6V connected to that input (a potentiometer)
It is worth mentioning that I've made sure to enable the AI6 channel as well as setting it to Voltage mode instead of current. Also, the web utility for the device shows the AI6 reading correctly as I change the potentiometer's resistance value.
So the problem doesn't lie in the connection from the potentiometer to the AI6 but somewhere else.
Out of nothing and leaving aside what I think I know on this topic, I though of changing the function from 0x03 to 0x04
However, the response is exactly the same.
It bugs me that I can read and write values to the output coils but not the Analog output holding registers.
Is there any configuration that I might be missing over here?
Thanks in advance.
Device settings:
IP address: 10.0.0.1
Port in which the ModBus service is running: 5020

J1939 - Yamaha Rudder Position ADDRESS

Using a PCAN VIEW, I determined the "rudder position" address (Yamaha Outboard), to be 166792448, and using CAN_Rx_MessageProc_ST_0 got the outboard position from bytes 4 and 5 of the 8 byte array:
RUDDER_ANGLE_RAW := WORD_TO_INT((256*MESSAGE_RX_NMEA[5]) + MESSAGE_RX_NMEA[4]);
I assumed that this Address would stay constant, but when the outboard changed, the address also changed - new address was 166792453. And further to this, after a power cycle, the address changed again to 166792456.
Assuming this has to do with address claiming, conflict, and the address changing.
The questions I have (and I have tried to grasp concepts but as a newby here am struggling) are thus:
1 Is there a range within in which this address will stay?
2 Can I get information out of the 8 byte received data (such as "yamaha outboard" or manufacturer specific info) that I could use to determine what the actual address is?
IF there is a range, I could write a procedure to scan the range, looking for the manufacturer ID, and thus determine the correct address.
Any help appreciated would be appreciated!

Confusion over CoreMIDI Destinations

Given the following code if I use the first method in the if branch to obtain a MIDIDestination the code works correctly, and MIDI data is sent. If I use the second method from the else branch, no data is sent.
var client = MIDIClientRef()
var port = MIDIPortRef()
var dest = MIDIEndpointRef()
MIDIClientCreate("jveditor" as CFString, nil, nil, &client)
MIDIOutputPortCreate(client, "output" as CFString, &port)
if false {
dest = MIDIGetDestination(1)
} else {
var device = MIDIGetExternalDevice(0)
var entity = MIDIDeviceGetEntity(device, 0)
dest = MIDIEntityGetDestination(entity, 0)
}
var name: Unmanaged<CFString>?
MIDIObjectGetStringProperty(dest, kMIDIPropertyDisplayName, &name)
print(name?.takeUnretainedValue() as! String)
var gmOn : [UInt8] = [ 0xf0, 0x7e, 0x7f, 0x09, 0x01, 0xf7 ]
var pktlist = MIDIPacketList()
var current = MIDIPacketListInit(&pktlist)
current = MIDIPacketListAdd(&pktlist, MemoryLayout<MIDIPacketList>.stride, current, 0, gmOn.count, &gmOn)
MIDISend(port, dest, &pktlist)
In both cases the printed device name is correct, and the status of every call is noErr.
I have noticed that if I ask for the kMIDIManufacturerName property that I get different results - specifically using the first method I get Generic, from the USB MIDI interface to which the MIDI device is connected, and with the second method I get the value of Roland configured via the Audio MIDI Setup app.
The reason I want to use the second method is specifically so that I can filter out devices that don't have the desired manufacturer name, but as above I can't then get working output.
Can anyone explain the difference between these two methods, and why the latter doesn't work, and ideally offer a suggestion as to how I can work around that?
It sounds like you want to find only the MIDI destination endpoints to talk to a certain manufacturer's devices. Unfortunately that isn't really possible, since there is no protocol for discovering what MIDI devices exist, what their attributes are, and how they are connected to the computer.
(Remember that MIDI is primitive 1980s technology. It doesn't even require bidirectional communication. There are perfectly valid MIDI setups with MIDI devices that you can send data to, but can never receive data from, and vice versa.)
The computer knows what MIDI interfaces are connected to it (for instance, a USB-MIDI interface). CoreMIDI calls these "Devices". You can find out how many there are, how many ports each has, etc. But there is no way to find out anything about the physical MIDI devices like keyboards and synthesizers that are connected to them.
"External devices" are an attempt to get around the discovery problem. They are the things that appear in Audio MIDI Setup when you press the "Add Device" button. That's all!
Ideally your users would create an external device for each physical MIDI device in their setup, enter all the attributes of each one, and set up all the connections in a way that perfectly mirrors their physical MIDI cables.
Unfortunately, in reality:
There may not be any external devices. There is not much benefit to creating them in Audio MIDI Setup, and it's a lot of boring data entry, so most people don't bother.
If there are external devices, you can't trust any of the information that the users added. The manufacturer might not be right, or might be spelled wrong, for instance.
It's pretty unfriendly to force your users to set things up in Audio MIDI Setup before they can use your software. Therefore, no apps do that... and therefore nobody sets anything up in Audio MIDI Setup. It's a chicken-and-egg problem.
Even if there are external devices, your users might want to send MIDI to other endpoints (like virtual endpoints created by other apps) that are not apparently connected to external devices. You should let them do what they want.
The documentation for MIDIGetDevice() makes a good suggestion:
If a client iterates through the devices and entities in the system, it will not ever visit any virtual sources and destinations created by other clients. Also, a device iteration will return devices which are "offline" (were present in the past but are not currently present), while iterations through the system's sources and destinations will not include the endpoints of offline devices.
Thus clients should usually use MIDIGetNumberOfSources, MIDIGetSource, MIDIGetNumberOfDestinations and MIDIGetDestination, rather iterating through devices and entities to locate endpoints.
In other words: use MIDIGetNumberOfDestinations and MIDIGetDestination to get the possible destinations, then let your users pick one of them. That's all.
If you really want to do more:
Given a destination endpoint, you can use MIDIEndpointGetEntity and MIDIEndpointGetDevice to get to the MIDI interface.
Given any MIDI object, you can find its connections to other objects. Use MIDIObjectGetDataProperty to get the value of property kMIDIPropertyConnectionUniqueID, which is an array of the unique IDs of connected objects. Then use MIDIObjectFindByUniqueID to get to the object. The outObjectType will tell you what kind of object it is.
But that's pretty awkward, and you're not guaranteed to find any useful information.
Based on a hint from Kurt Revis's answer, I've found the solution.
The destination that I needed to find is associated with the source of the external device, with the connection between them found using the kMIDIPropertyConnectionUniqueID property of that source.
Replacing the code in the if / else branch in the question with the code below works:
var external = MIDIGetExternalDevice(0)
var entity = MIDIDeviceGetEntity(external, 0)
var src = MIDIEntityGetSource(entity, 0)
var connID : Int32 = 0
var dest = MIDIObjectRef()
var type = MIDIObjectType.other
MIDIObjectGetIntegerProperty(src, kMIDIPropertyConnectionUniqueID, &connID)
MIDIObjectFindByUniqueID(connID, &dest, &type)
A property dump suggests that the connection Unique ID property is really a data property (perhaps containing multiple IDs) but the resulting CFData appears to be in big-endian format so reading it as an integer property instead seems to work fine.

Assigning MAC addresses from unbought oui

I'm a freelancer. I have finished a project for a company that uses Ethernet (TCP+UDP) with a STM32F4 Device.
While I was testing I used MACs in the space 00:00:00:00:00:xx , but now we need to assign final MACs.
The question here is that the company that pays the project dont want to buy OUI mac space. They say that is it practically impossible to have 2 cards in the same network with the same MAC address.
Another reason that they are telling me is that they will use this ethernet device card in places where no more ethernet device except a WIFI router and maybe more of our cards would be connected.
I found on internet places telling that you can use FF:FF:FF:FF:FF:FF as null mac address, I have been testing it without any problem (i thought that ARP would fail but it is working), but they would not be able to connnect 2 cards together in this case.
I have some questions about this.
Is it legal to use MACs from other companies or even non assigned MACs addresses?
Is there any interval of MACs that they can use freely without paying
Any reason to convince them to buy the OUI space would be welcomed too.
I don't think using non-asigned OUI is good, but MAC addresses with second bit 1 are called "locally administered addresses" and can be used without registering to IEEE.
This mean that you can use MAC addresses like x2:xx:xx:xx:xx:xx, x6:xx:xx:xx:xx:xx, etc. to stand for your NIC.
Notr that MAC addresses with first bit 1 are for multicasting, not for standing fir single NIC, and that MAC address FF:FF:FF:FF:FF:FF is for broadcasting, not null.
MAC address - Wikipedia, the free encyclopedia
To clarify MikeCAT's answer - it is the two least significant bits of the 1st byte of the MAC address that are important - what I think of as the 7th and 8th bit:
??????XY:????????:???????? ????????:????????:????????
where ? represents any bit in the mac address, and X is the U/L bit and Y is the Uni/multi cast bit
If the the eighth bit of a MAC address is 1, devices may have trouble getting IP addresses using DHCP. If the eighth bit of a MAC address is 0, you may have more luck.
The 7th and 8th bit of MAC addresses are special:
Bit 8 == 0 for unicast
Bit 8 == 1 for multicast
Bit 7 is also special - 0 = globally unique (assigned to a manufacturer to use) and 1 = locally administered (we should use these addresses!)

UDP socket, select one of multiple clients

here's what I'm trying to do:
I have 4 clocks and one PC on the network. I (PC) want to get the time from any of the clocks.
The idea:
Every clock uses UDP Broadcast (broadcast because I don't know the PC's IP). The PC gets a first dataset(time) and from then on only looks at datasets from this clock. (To not get confused by slight timedifferences between the clocks)
Clocks=Clients:
- socket
- bind to port 1234
- sendto(broadcast,'1234')
PC=Server
- socket
- bind to port 1234
- recvfrom(data,client_addr) //extract client_addr from first received data
- connect(client_addr) //to only receive data from this client
- recvfrom()
1: Is this the correct way to do this? Or is there a better option?
2: What can I do, if I want more than one application on the PC to get the time-data? Can I just copy the code and use it? My impression was, that port 1234 is now blocked from the first application that gets the bind.
(I guess SO_REUSEADDR won't work because only ONE application then gets the data AND I don't know which one it is going to be)
Regards
1: Is this the correct way to do this?
Yes.
Or is there a better option?
Can't think of one off-hand.
2: What can I do, if I want more than one application on the PC to get the time-data?
Use SO_REUSEADDR.
Can I just copy the code and use it?
Yes.
My impression was, that port 1234 is now blocked from the first application that gets the bind.
No.
(I guess SO_REUSEADDR won't work because only ONE application then gets the data AND I don't know which one it is going to be)
Wrong guess. Why guess about it at all? Why not try it? Much more reliable than guessing, and quicker than asking questions here too.