Send hexString Data through UDP - ios

I'm developing an iOS app. I've come across a problem.
I am trying to send a hexString data through UDP to an wifi camera, which will response while getting correct data. My code is shown below. However I can't get any response from my wifi camera. (I'm using
https://github.com/robbiehanson/CocoaAsyncSocket)
NSString *sendMsg = #"6745000005000000000000000000000000000000000000001400000067450000140000000A";
NSData *bytes = [sendMsg dataUsingEncoding:NSUTF16BigEndianStringEncoding];
NSString *host = #"255.255.255.255";
[self.udpSocket sendData:bytes toHost:host port:ListenPort withTimeout:-1 tag:1];
Beside, I've try send my data through PacketSender (an app can send UDP data), which has a correct response.
enter image description here

Problem has been solved. The problem is while converting NSString to NSData. It's hex string which need to convert to NSData. Below is my code which works.
- (NSData *)dataFromHexString:(NSString *)hexString {
NSAssert((hexString.length > 0) && (hexString.length % 2 == 0), #"hexString.length mod 2 != 0");
NSMutableData *data = [[NSMutableData alloc] init];
for (NSUInteger i=0; i<hexString.length; i+=2) {
NSRange tempRange = NSMakeRange(i, 2);
NSString *tempStr = [hexString substringWithRange:tempRange];
NSScanner *scanner = [NSScanner scannerWithString:tempStr];
unsigned int tempIntValue;
[scanner scanHexInt:&tempIntValue];
[data appendBytes:&tempIntValue length:1];
}
return data;}

Related

We are facing problem while creating compressed file of transferred socket data in hex string to converting to .tgz file in iOS App

We are facing problem while creating compressed file at iOS Device Document Directory, .tgz file is in Hex string transferring from pin-pad device to iPad iOS App at TCP socket layer. We used below HexToString function to convert that hex string and make file with .tgz. but at the end file is corrupted.
Can anyone please help us here, how to create compress file at iOS level with below hex string ? Please suggest us any code changes.
Note :- we had tried multiple NSStringEncoding technique, like ASCII, Unicode, Utf8, etc.
HEX String:-
1F8B08003058A8620203EDCA3B0A80301045D1594A5660265FB7E036065422A8453282CB57B4B2B112419CD3DCE2BD6966DD8F54925E4A975B62D22551EE741A2A5E199E80BBE8F1681DFDA5270BC6DB60D1398735A0092E0650082F580A53566A6F36F7BFFBFDA39A01841042FCD0062C8057FA00080000
we are using Xcode Version:13.1 and IOS Version 15.1 and above.
//Below function we used for creating .tgz file
//fileName here is abc.tgz which is compress file type
//content here is hex string mention aboved
+ (void)writeToLogFile:(NSString*)content fileName:(NSString*)fileNameString{
content = [NSString stringWithFormat:#"%#",content];
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:fileNameString];
NSData *fileOriginalString = [self HextoString:content];
NSData *fileData = [fileOriginalString dataUsingEncoding:NSASCIIStringEncoding];
***//In alternative we also tried direct hex string to NSData type by calling below commentented method but it still failing
//NSData *fileData = [self dataFromHexString:content];***
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSError *error = nil;
[fileData writeToFile:fileName options:NSDataWritingAtomic error:&error];
NSLog(#"Write returned error: %#", [error localizedDescription]);
});
}
//Below function we used for Hex to String conversion
+(NSString*)HextoString:(NSString*)string{
#try{
NSMutableString * StrResult = [[NSMutableString alloc] init];
int i = 0;
while (i < [string length]){
NSString * hexChar = [string substringWithRange: NSMakeRange(i, 2)];
int value = 0;
sscanf([hexChar cStringUsingEncoding:NSASCIIStringEncoding], "%x", &value);
[StrResult appendFormat:#"%c", (char)value];
i+=2;
}
return StrResult;
}
#catch (NSException *exception){
[AELoggerManager info:[NSString stringWithFormat:#" %s EXCEPTION ::%#",__FUNCTION__,exception]];
}
}
+ (NSData *)dataFromHexString:(NSString *) string {
if([string length] % 2 == 1){
string = [#"0"stringByAppendingString:string];
}
const char *chars = [string UTF8String];
int i = 0, len = (int)[string length];
NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[3] = {'\0','\0','\0'};
unsigned long wholeByte;
while (i < len) {
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:2];
}
return data;
}

I am converting NSString a=#"0x401A" into int16_t?

Why when I am trying to convert it converts hexadecimal value into integer?
unsigned int outVal;
NSScanner* scanner = [NSScanner scannerWithString:final1];
[scanner scanHexInt:&outVal];
NSLog(#"%u",outVal);
Another way I am trying to do is converting it to normal integer it gives me 0 value.
I just want the same characters:
int16_t a=0x401A;
I am getting this number from user so dont have the control to define it myself. I want removed quotations and datatype int16_t so I can execute command.
I got the solution myself
first the function which converts the data into bytes
- (NSData *)dataWithString:(NSString *)hexstring
{
NSMutableData* data = [NSMutableData data];
int idx;
for (idx = 0; idx+2 <= hexstring.length; idx+=2) {
NSRange range = NSMakeRange(idx, 2);
NSString* hexStr = [hexstring substringWithRange:range];
NSScanner* scanner = [NSScanner scannerWithString:hexStr];
unsigned int intValue;
[scanner scanHexInt:&intValue];
[data appendBytes:&intValue length:1];
}
return data;
}
and call the function by giving parameters in the command which will be sent to BLE
NSData * data = [self dataWithString: #"401A"];
[peripheral writeValue:data forCharacteristic:characteristic
type:CBCharacteristicWriteWithResponse];
Through this code anybody can sent string to BLE device. Thanks and Cheers

IOS Core Bluetooth : Writing NSData for Characteristic

I am using the following code to write the 0xDE value for a Bluetooth Caracteristic (Reset Device) using the IOS Core Bluetooth :
...
NSData *bytes = [#"0xDE" dataUsingEncoding:NSUTF8StringEncoding];
[peripheral writeValue:bytes
forCharacteristic:characteristic
type:CBCharacteristicWriteWithResponse];
...
is there any mistake in my code because the value is not written properly?
Swift 3.0: In case anyone is wondering the format for Swift is slightly different as writeValue can get the count from the array.
let value: UInt8 = 0xDE
let data = Data(bytes: [value])
peripheral.writeValue(data, for: characteristic, type: .withResponse)
Try creating your data with an array of single byte values.
const uint8_t bytes[] = {0xDE};
NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];
This is a useful approach for creating arbitrary constant data. For more bytes,
const uint8_t bytes[] = {0x01,0x02,0x03,0x04,0x05};
NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];
If you want to create data to send using variables, I would recommend using NSMutableData and appending the bytes that you need. It isn't very pretty, but it is easy to read / understand, especially when you are matching a packed struct on the embedded side. Example below is from a BLE project where we were making a simple communication protocol.
NSMutableData *data = [[NSMutableData alloc] init];
//pull out each of the fields in order to correctly
//serialize into a correctly ordered byte stream
const uint8_t start = PKT_START_BYTE;
const uint8_t bitfield = (uint8_t)self.bitfield;
const uint8_t frame = (uint8_t)self.frameNumber;
const uint8_t size = (uint8_t)self.size;
//append the individual bytes to the data chunk
[data appendBytes:&start length:1];
[data appendBytes:&bitfield length:1];
[data appendBytes:&frame length:1];
[data appendBytes:&size length:1];
The answer by bensarz is almost correct. Except one thing: you shouldn't use sizeof(int) as the length for NSData. The size of int is 4 or 8 bytes (depending on the architecture). As you want to send 1 byte, use uint8_t or Byte instead:
uint8_t byteToWrite = 0xDE;
NSData *data = [[NSData alloc] initWithBytes:&byteToWrite length:sizeof(&byteToWrite)];
[peripheral writeValue:data
forCharacteristic:characteristic
type:CBCharacteristicWriteWithResponse];
Of courser you could also use int as the variable's type, but you have to initialize NSData with the length of 1.
This code will fix the problem :
NSData * data = [self dataWithHexString: #"DE"];
[peripheral writeValue:data forCharacteristic:characteristic
type:CBCharacteristicWriteWithResponse];
dataWithHexString implementation :
- (NSData *)dataWithHexString:(NSString *)hexstring
{
NSMutableData* data = [NSMutableData data];
int idx;
for (idx = 0; idx+2 <= hexstring.length; idx+=2) {
NSRange range = NSMakeRange(idx, 2);
NSString* hexStr = [hexstring substringWithRange:range];
NSScanner* scanner = [NSScanner scannerWithString:hexStr];
unsigned int intValue;
[scanner scanHexInt:&intValue];
[data appendBytes:&intValue length:1];
}
return data;
}
What you are, in fact, doing here is writing the string "0xDE" to the characteristic. If you want to use binary/octal notation, you need to stay away from strings.
int integer = 0xDE;
NSData *data = [[NSData alloc] initWithBytes:&integer length:sizeof(integer)];
[peripheral writeValue:data
forCharacteristic:characteristic
type:CBCharacteristicWriteWithResponse];

HMAC SHA 384 on iOS

My code looks like this (using CommonCrypto/CommonHMAC.h):
- (NSString*) preperingCryptedData: (NSString*) data withKey: (NSString*) key {
NSData* dataToHash = [data dataUsingEncoding:NSUTF8StringEncoding];
NSData* keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"Utility: preperingCryptedData - Data to Crypt: %# and key %#\n...\n...\n...\n",dataToHash,keyData);
NSMutableData *dataHash = [NSMutableData dataWithLength:CC_SHA384_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA384, keyData.bytes, keyData.length, dataToHash.bytes, dataToHash.length, dataHash.mutableBytes);
NSString* readyString = [[NSString alloc] initWithData:dataToHash encoding:NSUTF8StringEncoding];
NSLog(#"Utility: preperingCryptedData call, result :%#\n...\n...\n...\n",readyString);
return readyString;
}
When I used code from: Here I got my string decoded without the Key. What am I doing wrong? How it's possible to encode message without the key?
There are two problem with the code:
1) You are using dataToHash as the output instead of dataHash.
2) dataHash is not a UTF8 data representation so it can not be successfully converted into a NSString.
Agree with the accepted answer. Provide working code.
- (NSString *)sha384:(NSString*)data withKey:(NSString *)key {
NSData* dataToHash = [data dataUsingEncoding:NSUTF8StringEncoding];
NSData* keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
unsigned char digest[CC_SHA384_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA384, keyData.bytes, keyData.length, dataToHash.bytes, dataToHash.length, digest);
NSString *sha384Str;
NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA384_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA384_DIGEST_LENGTH; i++)
[output appendFormat:#"%02x", digest[i]];
sha384Str = output;
return sha384Str;
}

Converting an Sha256 hashed value into NSString

I have a requirement to integrate with a web service that serves as a login. The hash needs to be generated on the client. I am able to produce the correct hash as NSMutableData, but then I need to convert it to a string, without the spaces or brackets produced when the NSMutableData object is rendered as a string in the output console. I have read several posts, all seeming to say the same thing:
NSString *newstring = [[NSString alloc] initWithDSata:dataToConvert encoding:NSUTF8StringEncoding];
Unfortunately, this doesnt work for me. Using NSUTF8StringEncoding returns null. NSASCIIStringEncoding is even worse.
Here is my code:
NSString *password = [NSString stringWithFormat:#"%#%#", kPrefix, [self.txtPassword text]];
NSLog(#"PLAIN: %#", password);
NSData *data = [password dataUsingEncoding:NSASCIIStringEncoding];
NSMutableData *sha256Out = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
CC_SHA256(data.bytes, data.length, sha256Out.mutableBytes);
NSString *preppedPassword = [[NSString alloc] initWithData:sha256Out encoding:NSASCIIStringEncoding];
NSLog(#"HASH: %#\n", preppedPassword);
How can I convert the NSMutableData to string?
My problem is that I need to from this
<7e8df5b3 17c99263 e4fe6220 bb75b798 4a41de45 44464ba8 06266397 f165742e>
to this
7e8df5b317c99263e4fe6220bb75b7984a41de4544464ba806266397f165742e
See How to convert an NSData into an NSString Hex string?
I use a slightly modified version myself:
#implementation NSData (Hex)
- (NSString *)hexRepresentationWithSpaces:(BOOL)spaces uppercase:(BOOL)uppercase {
const unsigned char *bytes = (const unsigned char *)[self bytes];
NSUInteger nbBytes = [self length];
// If spaces is true, insert a space every this many input bytes (twice this many output characters).
static const NSUInteger spaceEveryThisManyBytes = 4UL;
// If spaces is true, insert a line-break instead of a space every this many spaces.
static const NSUInteger lineBreakEveryThisManySpaces = 4UL;
const NSUInteger lineBreakEveryThisManyBytes = spaceEveryThisManyBytes * lineBreakEveryThisManySpaces;
NSUInteger strLen = 2 * nbBytes + (spaces ? nbBytes / spaceEveryThisManyBytes : 0);
NSMutableString *hex = [[NSMutableString alloc] initWithCapacity:strLen];
for (NSUInteger i = 0; i < nbBytes; ) {
if (uppercase) {
[hex appendFormat:#"%02X", bytes[i]];
} else {
[hex appendFormat:#"%02x", bytes[i]];
}
// We need to increment here so that the every-n-bytes computations are right.
++i;
if (spaces) {
if (i % lineBreakEveryThisManyBytes == 0) {
[hex appendString:#"\n"];
} else if (i % spaceEveryThisManyBytes == 0) {
[hex appendString:#" "];
}
}
}
return hex;
}
#end

Resources