How to resolved Multiple Address in Bonjour based ios application? - iphone

I am trying to Implement Banjour based application in ios. I implement success fully also sending and receiving data to one iphone to another iphone.
After browsing the services all other device in the work. and display in to the Table.
Now i want to select some devices in the table view, and send data to the selected devices
For that i created only one socket in each device.
CFSocketContext socketCtxt = {0, self, NULL, NULL, NULL};
witap_socket = CFSocketCreate(kCFAllocatorDefault, PF_INET6, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, (CFSocketCallBack)&TCPServerAcceptCallBack, &socketCtxt);
if (witap_socket != NULL)
{
protocolFamily = PF_INET6;
}
else
{
witap_socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, (CFSocketCallBack)&TCPServerAcceptCallBack, &socketCtxt);
if (witap_socket != NULL)
{
protocolFamily = PF_INET;
}
}
now i want to send data to the selected devices. for that I stored selected NSNetService(ie devices) another NSMutableArray. When used Click the send button particular Action will invoked.
-(void)SendActionFunction
{
for(int idx=0;idx<[selectedSer count];idx++)
{
NSNetService *service = [self.selectedSer objectAtIndex:idx];
NSLog(#"service......%#",[service name]);
self.currentResolve = [self.selectedSer objectAtIndex:idx];
[self.currentResolve setDelegate:self];
[self.currentResolve resolveWithTimeout:0.0];
}
}
if i am trying to Resolve address for each device(above code). It will resolve only for first device. and getting error
(Error code=-72003]
one more problem if i resolved address for a device it automatically remove from Tableview.
So my doubts are:
Why the selected device revoved?
Now i create TCP based socket, How to add destination address to send data?
Is it possible to send data from single socket to multiple destination?

As per Apple's definition, A CFSocket is a communications channel implemented with a BSD socket.
You have established a socket connection between the devices. But for sending and receiving data, you must make use of NSStreams. Documentation can be found here
I see you are using Apple's sample code Witap as the reference.
For sending and receiving the data, use NSStreamDelegate also.

What about resolve and send datas 1 device per 1 device ? Sounds easier :D
BTW, there is a really nice socket library I used for a project :
https://github.com/robbiehanson/CocoaAsyncSocket

Related

Core Bluetooth CBAdvertisementDataServiceDataKey could have some custom data?

im trying to send some data between and android and iOS device with BLE, but I need to send some custom information on the side of iOS to android , I already try almost all the keys that the CBCentralManager provides , but I try to send some string with the key CBAdvertisementDataServiceDataKey but nothing happens,anyone to know how to send information in that key?
in advance I try to have that information without connection.
this is the function that I use to try to make that part that I explain before.
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
if peripheral.state == .poweredOn{
let data = CBMutableCharacteristic(type: hardCodeUUID, properties: [.read], value: userName.data(using: .utf8), permissions: [.readable])
peripherialManager.startAdvertising([ CBAdvertisementDataLocalNameKey:"Jael2522",CBAdvertisementDataServiceDataKey:userName.data(using: .utf8),CBAdvertisementDataServiceDataKey:[CBUUID(string: "Jose")]])
let serialService = CBMutableService(type: hardCodeUUID, primary: true)
serialService.characteristics = [data]
peripherialManager.add(serialService)
}
}
CBAdvertisementDataServiceDataKey is readonly in iOS. The only things you can directly advertise are the local name and the list of service UUIDs (neither of which are guaranteed to be advertised, though they will be when your app is in the foreground if they can fit in the packet).
In order to reliably send data between the devices, you need one side to actually connect and read or write to characteristics.

Ionic Bluetooth BLE read message all the time

I want read data from sensor by bluetooth all the time. I follow from documentation but I can't set my phone read data from sensor by bluetooth. First i connect mobile with sensor next I add notification by:
this.ble.startNotification(peripheral.id,SERVICE_UUID,
CHARACTERISTIC_UUID).subscribe(
data => {this.onChange(data);}
)
where onChane(data) is :
onChange(buffer :ArrayBuffer){
console.log("onChange method")
var data = new Float32Array(buffer);
console.log(data[0]); }
Next I
this.ble.read(peripheral.id,SERVICE_UUID,CHARACTERISTIC_UUID).then(
(data) => {this.onChange(data);},
(err) => {console.log(err);}
)
I have failed in this.ble.read. CHARACTERISTIC_UUID and SERVICE_UUID are const. What is wrong? How can I correct this that my phone received datas all the time?
If you're using notifications, you don't need to read the characteristic's value. Once you subscribe for notifications, the peripheral will notify you with the new value whenever the value changes. It looks like your onChange function does this.
If your characteristic supports the read property, you can optionally read the value. Look at the peripheral data returned to the connect success callback to see the characteristic properties.
Take a look at my Ionic BLE example code. The thermometer example connects to a peripheral, subscribes for notifications, and reads the value one time so IU can update the UI with the current value. See https://github.com/don/ionic-ble-examples/blob/d0acd2b47ea08011be4d1aa844c4f74426a22273/thermometer/src/pages/detail/detail.ts#L37-L55

Milo: get IP of client

Is there a way to get a Clients IP in Context of a write?
I want to get the IP of an Client that writes to my Milo-OPCUA-Server, so I can handle these writes differently based on the Clients IP (local Clients should be able to write directly on the Server, whilst other writes should get forwarded to another Server)
Okay, this is not part of any official API right now, so it almost certainly will break in the future, but:
With the OperationContext you get when implementing AttributeManager#write(WriteContext, List<WriteValue>):
context.getSession().ifPresent(session -> {
UaStackServer stackServer = context.getServer().getServer();
if (stackServer instanceof UaTcpStackServer) {
ServerSecureChannel secureChannel = ((UaTcpStackServer) stackServer)
.getSecureChannel(session.getSecureChannelId());
Channel channel = secureChannel.attr(UaTcpStackServer.BoundChannelKey).get();
SocketAddress remoteAddress = channel.remoteAddress();
}
});
I'll have to add some official API to do this, probably something hanging off the Session object.

XMPP Sending/Receving file in iphone sdk ...?

How to send/receive file in iphone sdk using xmpp framework ?
Currently i am using XEP-0065 classes, and use the following code:
ObjTURNSocket = [[TURNSocket alloc] initWithStream:((TestAppDelegate*)[[UIApplication sharedApplication] delegate]).xmppStream
toJID:chatuser.jid];
[ObjTURNSocket start:self];
And I am getting following response from the server:
<iq type="error" id="AB2ED567-B97F-4DFE-B789-7731A617C239" to="kapil#testweb/6df6dc96" from="jabber.org">
<query xmlns="http://jabber.org/protocol/disco#items"/>
<error code="404" type="cancel">
<remote-server-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>`
Any help or suggestion will be well appreciated.
First, call setProxyCandidates with an array of the possible servers that you might be able to use for proxying. The default is "jabber.org", and your server is not federated with jabber.org, which is why you are getting the disco error back.
Next, in your delegate, implement the following methods:
- (void)turnSocket:(TURNSocket *)sender didSucceed:(GCDAsyncSocket *)socket;
- (void)turnSocketDidFail:(TURNSocket *)sender;
Then, in your didSucceed implementation, send data on the socket that was passed in, using:
- (void)writeData:(NSData *)data
withTimeout:(NSTimeInterval)timeout
tag:(long)tag;
Finally, close the socket:
- (void)disconnectAfterWriting;
I figured this out by looking at the source for TURNSocket.m, looking for the hardcoded "jabber.org", then searching for [delegate to find the places the delegate was getting called. This took me back to TURNSocket.h, which had a protocol documented for the delegate to implement.
I ended up having to customize the TURNSocket class to meet my specific needs to be able to transfer a file from my iOS device to another device. If there is a proxy server available, then the TURNSocket class might work for one's needs. But if this is a direct connection where a proxy server may not be available, then some extra work is necessary to set up your device to be able to connect to another device and directly transfer a file.
I was able to receive a file using TURNSocket in its current form with only one minor modification. As the code currently stands, the id and sid are assigned the same value, which cannot be guaranteed that a received stanza will have the same unique identifier value for both the id and sid.
You should have use xep-96 to make it possible to share and receive files.
after that just initiate xmppSifiletranfer with relevant data.
like
-(void)sendToOtherDevice:(NSData *)fileData receiverJid:(XmPPJId *)senderFullID file:(NSString *)fileName{
myFileTransferID=[xmppStream generateUUID];
XMPPJID *jid =senderFullID;
sifiletransfer=[[XMPPSIFileTransfer alloc]init];
[sifiletransfer initiateFileTransferTo:jid withData:fileData file:fileName passedsid:myFileTransferID];
if ([jid.domain isEqualToString:[xmppStream myJID].domain]) {
[TURNSocket setProxyCandidates:[NSArray arrayWithObjects:jid.domain, nil]];
} else {
[TURNSocket setProxyCandidates:[NSArray arrayWithObjects:jid.domain,[xmppStream myJID].domain, nil]];
}
TURNSocket *socket = [[TURNSocket alloc] initWithStream:xmppStream toJID:jid sid:myFileTransferID];
// [socket setDataToSend:fileData];
[socket startWithDelegate:self delegateQueue:dispatch_get_main_queue()];
}
# delegater of turnsocket
- (void)turnSocket:(TURNSocket *)sender didSucceed:(GCDAsyncSocket *)socket
{
NSLog(#"Socket Suceeed Port For File Transfer: %d",socket.localPort);
DDLogInfo(#"TURN Connection succeeded!");
DDLogInfo(#"You now have a socket that you can use to send/receive data to/from the other person.");
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Hurray!!"
message:#"Conection Established"
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}
if you guys have any other issue regarding file transfer comment below.I will surely help you.

Unable to receive data sent using NSStream objects

In my app I doing something very similar to what is done in the WiTap project. I use Bonjour to discover peers and then send data over the socket to perform an initial handshake.
I'm able to see the data being sent OTA using Cocoa Packet Analyzer. But the stream: handleEvent: function is never called on the receiving peer side.
What I am able to see is:
Sometimes, when the peer that sent the data exits, the receiver peer seems to get the data.
Sometimes I am able to see an NSStreamEventErrorOccurred error in the handler function.
I'm unable to see any noticeable pattern on when the above behavior occurs.
Here is a bit of the code that might be helpful.
PacketSender and PacketReceiver objects are singletons.
I have verified multiple times that the correct (and the only) instance of these objects are set as delegates while debugging:
if (![netService getInputStream:&_inStream outputStream:&_outStream])
{
[Utilities showAlert:#"Failed connecting to server"];
return BM_ERROR_NETSERVICE_STREAM_FAIL;
}
if(!sharedProtocolManager.mPacketSender)
{
sharedProtocolManager.mPacketSender = [PacketSender sharedSender];
}
if(!sharedProtocolManager.mPacketReceiver)
{
sharedProtocolManager.mPacketReceiver = [PacketReceiver sharedReceiver];
}
if(!sharedProtocolManager.mPacketSender || !sharedProtocolManager.mPacketReceiver)
{
return BM_ERROR_FAIL;
}
[PacketReceiver setupInStream:_inStream];
[PacketSender setupOutStream:_outStream];
}
Inside the PacketReceiver setupInStream: function I have:
if (sharedPacketReceiver->mInStream != inStream)
{
[sharedPacketReceiver->mInStream release];
sharedPacketReceiver->mInStream = [inStream retain];
}
sharedPacketReceiver->mInStream.delegate = sharedPacketReceiver;
Any answers or even suggestions on ways to debug this further would be greatly appreciated.
Thanks!