Getting RSSIValue from IOBluetoothHostController - objective-c

I'm trying to write a simple application that gathers the RSSIValue and displays it via NSLog, my code is as follows:
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import <IOBluetooth/objc/IOBluetoothDeviceInquiry.h>
#import <IOBluetooth/objc/IOBluetoothDevice.h>
#import <IOBluetooth/objc/IOBluetoothHostController.h>
#import <IOBluetooth/IOBluetoothUtilities.h>
#interface getRSSI: NSObject {}
-(void) readRSSIForDeviceComplete:(id)controller device:(IOBluetoothDevice*)device
info:(BluetoothHCIRSSIInfo*)info error:(IOReturn)error;
#end
#implementation getRSSI
- (void) readRSSIForDeviceComplete:(id)controller device:(IOBluetoothDevice*)device
info:(BluetoothHCIRSSIInfo*)info error:(IOReturn)error
{
if (error != kIOReturnSuccess) {
NSLog(#"readRSSIForDeviceComplete return error");
CFRunLoopStop(CFRunLoopGetCurrent());
}
if (info->handle == kBluetoothConnectionHandleNone) {
NSLog(#"readRSSIForDeviceComplete no handle");
CFRunLoopStop(CFRunLoopGetCurrent());
}
NSLog(#"RSSI = %i dBm ", info->RSSIValue);
[NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 5]];
[device closeConnection];
[device openConnection];
[controller readRSSIForDevice:device];
}
#end
int main (int argc, const char * argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog(#"start");
IOBluetoothHostController *hci = [IOBluetoothHostController defaultController];
NSString *addrStr = #"xx:xx:xx:xx:xx:xx";
BluetoothDeviceAddress addr;
IOBluetoothNSStringToDeviceAddress(addrStr, &addr);
IOBluetoothDevice *device = [[IOBluetoothDevice alloc] init];
device = [IOBluetoothDevice withAddress:&addr];
[device retain];
[device openConnection];
getRSSI *rssi = [[getRSSI alloc] init];
[hci setDelegate:rssi];
[hci readRSSIForDevice:device];
CFRunLoopRun();
[hci release];
[rssi release];
[pool release];
return 0;
}
The problem I am facing is that the readRSSIForDeviceComplete seems to work just fine, info passes along a value. The problem is that the RSSI value is drastically different from the one I can view from OS X via option clicking the bluetooth icon at the top. It is typical for my application to print off 1,2,-1,-8,etc while the menu displays -64 dBm, -66, -70, -42, etc.
I would really appreciate some guidance.

The value you get from readRSSIForDeviceComplete is the RSSI value. The value shown via OS X when option/alt-clicking the BlueTooth menu is the Raw RSSI value.
Assuming you have the Developer Tools you can see both values by using "Bluetooth Explorer" (/Developer/Applications/Bluetooth/Bluetooth Explorer). I have no idea what meaningful difference there is between the two values but for me they seem to constantly differ by a value of -60.
So your RSSI values of 1, 2, -1, -8 would correspond to Raw RSSI values of -59, -58, -61, -68.

Related

Setting media playback info in MacOs not working

I'm a newbie in ObjC and MacOs development.
My final goal is understand how setting playback info works from ObjC to try to implement that later on Rust (using generated ObjC runtime bindings).
So right now I'm trying to write small piece of code on ObjC that would set playback info (without actually playing anything).
I have found https://github.com/MarshallOfSound/electron-media-service/blob/master/src/darwin/service.mm and used it as a base.
Here's code I have right now:
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <objc/runtime.h>
#include "MediaPlayer/MPNowPlayingInfoCenter.h"
#include "MediaPlayer/MPRemoteCommandCenter.h"
#include "MediaPlayer/MPRemoteCommand.h"
#include "MediaPlayer/MPMediaItem.h"
#include "MediaPlayer/MPRemoteCommandEvent.h"
#interface NativeMediaController : NSObject { }
#end
#implementation NativeMediaController
- (MPRemoteCommandHandlerStatus)remotePlay {
NSLog(#"Play");
return MPRemoteCommandHandlerStatusSuccess;
}
- (MPRemoteCommandHandlerStatus)remotePause {
NSLog(#"Pause");
return MPRemoteCommandHandlerStatusSuccess;
}
- (MPRemoteCommandHandlerStatus)remoteTogglePlayPause {
NSLog(#"PlayPause");
return MPRemoteCommandHandlerStatusSuccess;
}
- (MPRemoteCommandHandlerStatus)remoteNext {
NSLog(#"Next");
return MPRemoteCommandHandlerStatusSuccess;
}
- (MPRemoteCommandHandlerStatus)remotePrev {
NSLog(#"Previous");
return MPRemoteCommandHandlerStatusSuccess;
}
- (MPRemoteCommandHandlerStatus)remoteChangePlaybackPosition:(MPChangePlaybackPositionCommandEvent*)event {
NSLog(#"ChangePlaybackPosition");
return MPRemoteCommandHandlerStatusSuccess;
}
- (MPRemoteCommandHandlerStatus)move:(MPChangePlaybackPositionCommandEvent*)event {
NSLog(#"Move");
return MPRemoteCommandHandlerStatusSuccess;
}
#end
int main(int argc, const char * argv[]) {
#autoreleasepool {
// insert code here...
NSLog(#"Hello, World!");
NativeMediaController* controller = [[NativeMediaController alloc] init];
MPRemoteCommandCenter *remoteCommandCenter = [MPRemoteCommandCenter sharedCommandCenter];
[remoteCommandCenter playCommand].enabled = true;
[remoteCommandCenter pauseCommand].enabled = true;
[remoteCommandCenter togglePlayPauseCommand].enabled = true;
[remoteCommandCenter changePlaybackPositionCommand].enabled = true;
[remoteCommandCenter nextTrackCommand].enabled = true;
[remoteCommandCenter previousTrackCommand].enabled = true;
[[remoteCommandCenter playCommand] addTarget:controller action:#selector(remotePlay)];
[[remoteCommandCenter pauseCommand] addTarget:controller action:#selector(remotePause)];
[[remoteCommandCenter togglePlayPauseCommand] addTarget:controller action:#selector(remoteTogglePlayPause)];
[[remoteCommandCenter changePlaybackPositionCommand] addTarget:controller action:#selector(remoteChangePlaybackPosition:)];
[[remoteCommandCenter nextTrackCommand] addTarget:controller action:#selector(remoteNext)];
[[remoteCommandCenter previousTrackCommand] addTarget:controller action:#selector(remotePrev)];
NSMutableDictionary *songInfo = [[NSMutableDictionary alloc] init];
[songInfo setObject:[NSString stringWithUTF8String:"Test title"] forKey:MPMediaItemPropertyTitle];
[songInfo setObject:[NSString stringWithUTF8String:"Test artist"] forKey:MPMediaItemPropertyArtist];
[songInfo setObject:[NSString stringWithUTF8String:"Test albumtitle"] forKey:MPMediaItemPropertyAlbumTitle];
[songInfo setObject:[NSNumber numberWithFloat:60.0] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
[songInfo setObject:[NSNumber numberWithFloat:360.0] forKey:MPMediaItemPropertyPlaybackDuration];
[songInfo setObject:[NSNumber numberWithFloat:112233] forKey:MPMediaItemPropertyPersistentID];
[MPNowPlayingInfoCenter defaultCenter].playbackState = MPNowPlayingPlaybackStatePlaying;
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songInfo];
NSLog(#"End!");
char input[50] = {0};
printf("Enter anything to quit: ");
scanf("%s", input);
}
return 0;
}
When this code is executed I see no effect in MacOs playing info widget.
Unfortunately right now I have no idea how to debug this or where can I find better ObjC example.
Finally, I found the reason that caused my problem playing with Apple Swift example.
There're two requirements to show playback widget (i didn't find them documented anywhere) that have been missing:
You should register a callback for at least one action (play, pause)
You should build your application as an App, not as Console. If your program is not shown in the dock as a running app - the playback widget wouldn't work.

New in Objective C. Simple bug at runtime. Thread 1: breakpoint 1.1

I am learning Objective C and I have tried to override my superclass (NSObject) description method in my BNRItem class. Though it seems like I have done everything right, my NSLog does not seem to use my overridden description method. Instead I see a Thread 1 Breakpoint 1.1 in my definition of the description method and more precisely, where I defined the descriptionString.
Here is my console output.
2015-08-30 20:49:00.622 RandomItems[46034:1002101] Zero
2015-08-30 20:49:00.623 RandomItems[46034:1002101] One
2015-08-30 20:49:00.623 RandomItems[46034:1002101] Two
2015-08-30 20:49:00.623 RandomItems[46034:1002101] Three
(lldb)
My main.m file:
#import <Foundation/Foundation.h>
#import "BNRItem.h"
int main(int argc, const char * argv[]) {
#autoreleasepool {
// Create a mutable array object, store its address in items variable...
NSMutableArray *items = [[NSMutableArray alloc] init];
//Send the message addObject: to the NSMutableArray pointed
//by the variable item, passing a string each time
[items addObject:#"One"];
[items addObject: #"Two"];
[items addObject: #"Three"];
// Send another message, insertObject:atIndex;, to that same array object
[items insertObject:#"Zero" atIndex:0];
// For every item in the items array ...
for (NSString *item in items){
//Log the description of item
NSLog(#"%#", item);
}
// Create a BNRItem instance and log its instance variables in the console
BNRItem *item = [[BNRItem alloc] init];
// Set item name to Red Sofa
item.itemName = #"Red Sofa";
item.serialNumber= #"A1B2C";
item.valueInDollards = 100;
//
NSLog(#"%#", item);
//Destroy the mutable array object
items = nil ;
}
return 0;
}
My header file:
#import <Foundation/Foundation.h>
#interface BNRItem : NSObject
{
NSString *_itemName;
NSString *_serialNumber;
int _valueInDollards;
NSDate *_dateCreated;
}
- (void)setItemName:(NSString *)str;
- (NSString *)itemName;
- (void)setSerialNumber:(NSString *)str;
- (NSString *)serialNumber;
- (void)setValueInDollards:(int)v;
- (int)valueInDollards;
- (NSDate *)dateCreated;
#end
And finally, my implementation file:
#import "BNRItem.h"
#implementation BNRItem
- (void)setItemName:(NSString *)str
{
_itemName = str;
}
- (NSString *)itemName
{
return _itemName;
}
- (void)setSerialNumber:(NSString *)str
{
_serialNumber = str;
}
- (NSString *)serialNumber
{
return _serialNumber;
}
- ( void )setValueInDollards:(int)v
{
_valueInDollards = v;
}
- ( int )valueInDollards
{
return _valueInDollards;
}
-( NSDate * )dateCreated
{
return _dateCreated;
}
- ( NSString * )description
{
NSString *descriptionString = [[NSString alloc] initWithFormat:#"%# (%#): Worth %d, recorded on %#", self.itemName, self.serialNumber, self.valueInDollards, self.dateCreated];
return descriptionString;
}
#end
It sounds like you have simply set a breakpoint on a line in your -description method. The debugger is stopping your program at the breakpoint. There's no indication of an actual error.
If you hit the continue button in Xcode, your program would probably proceed just fine.
You can disable the breakpoint, tell Xcode to ignore all breakpoints, or delete the breakpoint if you don't want to break there. The breakpoint will look like a blue arrow in the margins to the left of your code. Right-click or Control-click on it to see options.
To make Xcode ignore breakpoints, toggle the breakpoint button in the debugging toolbar. It also looks like a right-pointing arrow. It will be filled in blue if breakpoints are enabled. It will be an outline if they're disabled.

Using NSUInteger Input to insertObject:___ atIndex:___

I'm trying to create a simple commandline tic-tac-toe game using an NSMutableArray.
Created a class called "Board" with the method "getPosition"
(I'm assuming this is the best way to get a user input)
I'm asking for position, then casting from int to NSUInteger)
#import "Board.h"
#implementation Board
-(void)getPosition;
{
int enteredPosition;
scanf("%i", &enteredPosition);
NSUInteger nsEnteredPosition = (NSUInteger ) enteredPosition;
NSLog(#"Position = %lu", (unsigned long)nsEnteredPosition);
}
#import <Foundation/Foundation.h>
#import "Board.h"
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSString *currentPlayer;
NSMutableArray *gameBoard=[[NSMutableArray alloc] initWithCapacity:9];
for(int i; i<=2; i++)
{
if(i %2)
{
currentPlayer=#"X";
}
else
{
currentPlayer=#"O";
}
NSLog(#"Player %#, select an open spot 1 - 9 on the board", currentPlayer);
Board *currentPosition = [[Board alloc] init];
[currentPosition getPosition];
[gameBoard insertObject:currentPlayer atIndex:currentPosition]; //this is where i have a problem
}
As I understand it atIndex requires an NSUInteger parameter, but I'm receiving the error message:
"Incompatible pointer to integer conversion sending 'Board *_strong"
to parameter of type 'NSUInteger' (aka 'unassigned long')
You're using currentPosition as your index which is a Board object. Perhaps [currentPosition getPosition] is supposed to return an NSUInteger. If so, try rewriting the last portion of your code like this:
Board *theBoard = [[Board alloc] init];
NSUInteger currentPosition = [theBoard getPosition];
[gameBoard insertObject:currentPlayer atIndex:currentPosition]; //this is where i have a problem

Trying to put a global NSMutable Array in Objective C

I`m making an exercise, i have 2 classes Songs and Playlist, in the program i can put songs in playlist and everything is working fine, but i need to make a master playlist with all the songs that are in all the normal playlist and there is the problem.
Here is the code
//
// main.m
// MyItunes
//
// Created by Rodrigo López on 6/29/12.
// Copyright (c) 2012 ITQ. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Songs.h"
#import "PlayList.h"
int main (int argc, const char * argv[])
{
#autoreleasepool {
Songs *mySong1 = [Songs new];
Songs *mySong2 = [Songs new];
Songs *mySong3 = [Songs new];
PlayList *myPlayList1=[[PlayList alloc]initWithName:#"First"];
PlayList *myPlayList2=[[PlayList alloc]initWithName:#"Second"];
[mySong1 setTitle:#"Back In Black" setArtist:#"AC/DC" setAlbum:#"Back In Black" setPlayt:#"4:16"];
[mySong2 setTitle:#"Medicate" setArtist:#"AFI" setAlbum:#"Crash Love" setPlayt:#"4:21"];
[mySong3 setTitle:#"Rucci" setArtist:#"Austin TV" setAlbum:#"La ultima noche" setPlayt:#"4:39"];
[myPlayList1 addSong:mySong1];
[myPlayList1 addSong:mySong2];
[myPlayList2 addSong:mySong3];
[myPlayList1 showPlayList];
[myPlayList2 showPlayList];
[myPlayList1 showPlayList];
[myPlayList1 showAllSongs];
}
return 0;
}
//
// PlayList.m
// MyItunes
//
// Created by Rodrigo López on 6/29/12.
// Copyright (c) 2012 ITQ. All rights reserved.
//
#import "PlayList.h"
#implementation PlayList
#synthesize playListarray,playListName;
-(id) initWithName: (NSString *) name
{
if(self)
{
playListName = [NSString stringWithString: name];
playListarray = [NSMutableArray array];
playlistMaster=[NSMutableArray array ];
}
return self;
}
-(void) addSong: (Songs *) theSong
{
[playListarray addObject:theSong];
[playlistMaster addObject:theSong];
}
-(void) showPlayList
{
NSLog(#"Play List: %#", self.playListName);
for(Songs *theSong in playListarray)
{
NSLog(#"%#", theSong.title);
}
}
-(void) showAllSongs
{
NSLog(#"Play List: Master");
for(Songs *theSong in playlistMaster)
{
NSLog(#"%#", theSong.title);
}
}
-(NSUInteger) entries
{
return [playListarray count];
}
-(void) remove: (Songs *) theSong
{
[playListarray removeObjectIdenticalTo:theSong];
}
#end
The problem is with the NSMutable array, i want to declare the array globally, but i dont know how to do it, here is the output of this program:
2012-06-29 19:24:06.061 MyItunes[17184:707] Play List: First
2012-06-29 19:24:06.080 MyItunes[17184:707] Back In Black
2012-06-29 19:24:06.083 MyItunes[17184:707] Medicate
2012-06-29 19:24:06.084 MyItunes[17184:707] Play List: Second
2012-06-29 19:24:06.085 MyItunes[17184:707] Rucci
2012-06-29 19:24:06.089 MyItunes[17184:707] Play List: First
2012-06-29 19:24:06.090 MyItunes[17184:707] Back In Black
2012-06-29 19:24:06.091 MyItunes[17184:707] Medicate
2012-06-29 19:24:06.091 MyItunes[17184:707] Play List: Master
2012-06-29 19:24:06.092 MyItunes[17184:707] Back In Black
2012-06-29 19:24:06.093 MyItunes[17184:707] Medicate
So in play list master, its missing Rucci song, hope you can help me, thank you very much, i appreciate it
I would make your playlistMaster a "static variable" of the PlayList implementation file as described at: Objective C Static Class Level variables. You just declare and initialize it the .m file outside of any other methods. (Don't forget to make sure it is retained.)
I should also note that there are some memory issues in your PlayList class. In particular, your initializer code should retain the member variables, like:
-(id) initWithName: (NSString *) name
{
if (self = [super init]) {
playListName = [[NSString stringWithString: name] retain]; // NOTE: You could also do: [[NSString alloc] initWithString: name];
playListarray = [[NSMutableArray array] retain]; // NOTE: You could also do: [[NSMutableArray alloc] init];
playlistMaster = [[NSMutableArray array] retain]; // ditto
}
return self;
}
If you do this, you will need to add a dealloc method that releases each of these. But if you don't they may be released before you try to use them.

Lua and Objective C not running script

I am trying to create an objective c interface that encapsulates the functionality of storing and running a lua script (compiled or not.) My code for the script interface is as follows:
#import <Cocoa/Cocoa.h>
#import "Types.h"
#import "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#interface Script : NSObject<NSCoding> {
#public
s32 size;
s8* data;
BOOL done;
}
#property s32 size;
#property s8* data;
#property BOOL done;
- (id) initWithScript: (u8*)data andSize:(s32)size;
- (id) initFromFile: (const char*)file;
- (void) runWithState: (lua_State*)state;
- (void) encodeWithCoder: (NSCoder*)coder;
- (id) initWithCoder: (NSCoder*)coder;
#end
#import "Script.h"
#implementation Script
#synthesize size;
#synthesize data;
#synthesize done;
- (id) initWithScript: (s8*)d andSize:(s32)s
{
self = [super init];
self->size = s;
self->data = d;
return self;
}
- (id) initFromFile:(const char *)file
{
FILE* p;
p = fopen(file, "rb");
if(p == NULL) return [super init];
fseek(p, 0, SEEK_END);
s32 fs = ftell(p);
rewind(p);
u8* buffer = (u8*)malloc(fs);
fread(buffer, 1, fs, p);
fclose(p);
return [self initWithScript:buffer andSize:size];
}
- (void) runWithState: (lua_State*)state
{
if(luaL_loadbuffer(state, [self data], [self size], "Script") != 0)
{
NSLog(#"Error loading lua chunk.");
return;
}
lua_pcall(state, 0, LUA_MULTRET, 0);
}
- (void) encodeWithCoder: (NSCoder*)coder
{
[coder encodeInt: size forKey: #"Script.size"];
[coder encodeBytes:data length:size forKey:#"Script.data"];
}
- (id) initWithCoder: (NSCoder*)coder
{
self = [super init];
NSUInteger actualSize;
size = [coder decodeIntForKey: #"Script.size"];
data = [[coder decodeBytesForKey:#"Script.data" returnedLength:&actualSize] retain];
return self;
}
#end
Here is the main method:
#import "Script.h"
int main(int argc, char* argv[])
{
Script* script = [[Script alloc] initFromFile:"./test.lua"];
lua_State* state = luaL_newstate();
luaL_openlibs(state);
luaL_dostring(state, "print(_VERSION)");
[script runWithState:state];
luaL_dostring(state, "print(_VERSION)");
lua_close(state);
}
And the lua script is just:
print("O Hai World!")
Loading the file is correct, but I think it messes up at pcall.
Any Help is greatly appreciated.
Heading
Your code is so complex that there are no obvious faults. However, your next step should be to check the return value from lua_pcall. If it is nonzero, there will be an error message on the top of the stack which you can print via
fprintf(stderr, "Pcall failed: %s\n", lua_tostring(state, -1));
If you don't get a useful error message, my next step would be to dump the Lua stack. How many elements are on it? What is the (Lua) type of each element? What is the value. Functions lua_top, and luaL_typename will be useful. To print the value you will have to switch on the results of lua_type. Good luck.
I didn't run your code. But at first glance, I found that the signature of initWithScript: are different between header file (using u8*) and source file (using s8*).