Stdout redirection not working in iOS without debugger - iphone

I am trying to redirect output so I can send it over the network. For some reason if you run the code while debugger attached it works perfectly. Once you start the application in normal way the code freezes on the read function and never returns. If someone has any pointers I will highly appreciate it.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^(void) {
static int pipePair[2];
if ( pipe(pipePair) != 0) {
return;
}
dup2(pipePair[1],STDOUT_FILENO);
while (true) {
char * buffer = calloc(sizeof(char), 1024);
ssize_t readCount = read(pipePair[0],buffer,1023);
if (readCount > 0) {
buffer[readCount] = 0;
NSString * log = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];
//sent it over network
}
if (readCount == -1) {
return;
}
}
});

Apparently in iOS 5.1 writing to stdout was disallowed. http://spouliot.wordpress.com/2012/03/13/ios-5-1-vs-stdout/

Related

ESP32-CAM buffer

When I initialize the camera I use this:
#include "esp_camera.h"
bool initCamera(){
Serial.print("Iniciando Cámara ...");
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
...
...
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_XGA;
config.jpeg_quality = 8;
config.fb_count = 1;
config.grab_mode = CAMERA_GRAB_LATEST; <<<<<<<
// camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK){
Serial.printf("... error 0x%x", err);
return false;
}
sensor_t *s = esp_camera_sensor_get();
Serial.println("... OK");
CAMARA_OK = true;
return true;
}
But when I ask for a capture:
static esp_err_t capture_handler(httpd_req_t *req){
cambiosConfiguracion(req);
camera_fb_t *fb = NULL;
esp_err_t res = ESP_OK;
fb = esp_camera_fb_get();
if (!fb){
Serial.println("Camera capture failed");
httpd_resp_send_500(req);
return ESP_FAIL;
}
...
the image it shows me is from before, it takes a delayed capture.
I want that when I ask for a capture, it gives me the one from that moment, not the one stored in the buffer
I have the same problem, I've been looking for the solution for days and although it seems to be fine, it doesn't do what it's supposed to do.
At the moment I am using this "trick":
fb = esp_camera_fb_get();
esp_camera_fb_return(fb);
fb = esp_camera_fb_get();
I ask for a capture, I discard it and then I ask for another one, which is current

How can I print on this POS using Flutter

I try this function but doesn't work
Future<void> _connect(BluetoothDevice device) async {
if (device == null) {
show('No device selected.');
} else {
bluetooth.isConnected.then((isConnected) {
if (!isConnected!) {
bluetooth.printCustom("thermal pinter", 0, 1);
for (int i = 0; i < 2; i++) {
bluetooth.printCustom("Welcome", 0, 1);
bluetooth.printNewLine();
}
}
});
}
}
Hello and welcome on SO!
I don't know much about bluetooth printing or if the methods you're using exists and are used correctly, but at least I can notice that your code is sending the order to print when the printer is NOT connected.
See here:
if (!isConnected!) {
//the code below is executed only if isConnected is false, but seems like you want it to be the opposite
bluetooth.printCustom("thermal pinter", 0, 1);
for (int i = 0; i < 2; i++) {
bluetooth.printCustom("Welcome", 0, 1);
bluetooth.printNewLine();
}
}
Taking for granted that the code is correct, the line if (!isConnected!) will perform the code in the {} that follows only when the printer is not connected. Try removing the ! before isConnected and see if it works. Again, this is simply a wild guess judging on your variables name and such, I can't really say that the problem lies there.

I have two i2c devices. Both alone work well, but when I read from one, and then write to the other, the second one is not an ancknowledging

I have two devices MPU6050 and EEPROM 24C256. I can write and read from both alone. But when I try to read from MPU6050 and than write data to EEPROM in the same session, the EEPROM does not respond. I am using mbed OS libraries. And my question is.. Is it library, code or hardware problem?
MPU6050 read sequence:
enter image description here
EEPROM write page sequance:
enter image description here
//CODE
const char imuAddress = 0x68<<1;
const char imuDataAddress = 0x3B;
const char eepAddress = 0xA0;
const char data[3] = {1.1, 2.2, 3.3};
char acc[3];
//reading acceleration data from IMU
while(true){
i2c.start();
if(i2c.write(imuAddress) != 1){
i2c.stop();
continue;
}
if(i2c.write(imuDataAddress) != 1){
i2c.stop();
continue;
}
i2c.start();
if(i2c.write(imuAddress | 0x01) != 1){
i2c.stop();
continue;
}
for (int i = 0; i < 2; i++){
i2c.read(1); //read and respond ACK to continue
}
i2c.read(0); //read and respond NACK to stop reading
i2c.stop();
break;
}
//write data to EEPROM
while(true){
i2c.start();
if(i2c.write(eepAddress) != 1){ //here is the problem (EEPROM does not respond)
i2c.stop();
continue;
}
if(i2c.write(0x00) != 1){
i2c.stop();
continue;
}
if(i2c.write(0x00) != 1){
i2c.stop();
continue;
}
bool ack = true;
for(int i = 0; i < 3; i++){
if(i2c.write(data[i]) != 1){
i2c.stop();
ack = false;
break;
}
}
if (ack == true){
i2c.stop();
break;
}
}
I have a couple initial thoughts, but do you have access to an oscilloscope? It is odd that each one works individually. This makes me think that it may be an issue between the transition. (Possibly try a delay between each one? Also, possibly remove the stops in the initial read as they aren't necessary)
I think the best way to figure this out is to post a scope trace of the messaging for each one running individually and a trace of them running back to back.

can checking the hits from a raycast cause the game to crash?

so i am trying to detect if i click on a object with tag "solarsystem" and if so, then load that solarsystem onto the other scene. this code worked perfectly fine before, but now it crashes in such a way that i have to end unity from the task manager with the end task button to even close it. it just stops responding completely.
here is the code where i believe to have found the error after messing around with many Debug.log s to find where the code stopped and therefore find out where unity stops responding:
RaycastHit[] hit = Physics.RaycastAll(cursorPosition, Vector3.forward,15f);
Debug.Log("test2");//this is printed to the console - code crashes below this line
for(int i = 0; i < hit.Length; i++)
{
Debug.Log("hit"); // this is never printed to console - code crashes above this line
if(currentScene == "Universe")
{
if(hit[i].collider.gameObject.tag == "SolarSystem")
{
ChangeScene("SolarSystem");
SolarSystem clickedSolarSystem = hit[i].collider.gameObject.GetComponent<SystemObjectLink>().LinkedClass;
SolarSystem LoadedSolarSystem = SolarSystemCamera.GetComponent<SolarSystem>() as SolarSystem;
LoadedSolarSystem = clickedSolarSystem;
Debug.Log("generating system clicked on");
if (LoadedSolarSystem.preGenerated == false)
{
LoadedSolarSystem.Generate();
}
else
{
LoadedSolarSystem.Regenerate();
}
break;
}
}
if(currentScene == "SolarSystem")
{
if (hit[i].collider != null)
{
if (hit[i].collider.gameObject.tag == "Planet")
{
Target = hit[i].collider.gameObject;
break;
}
else if (hit[i].collider.gameObject.tag == "Moon")
{
Target = hit[i].collider.gameObject;
break;
}
Target = hit[i].collider.gameObject;
}
}
}
i had an for(;;) statement with a hardcoded
if(<state>){
break:
}
statement to break the infinite loop. but as i click on an object in the game. it checks the code for any errors before running it. when it does this it gets caught in the infinite loop and so to fix it i did this
for(;errorIndex<99; errorIndex++){
}
my mistake and what i learned:
never use a while(true) loop or a for loop without a way of getting out of itself (for(;;))
if the unity engine/editor ever stops responding it is because it is cought in an infinite loop- look over your code and ensure there is no possible way any of your loops can go on forever

How to simulate a click on home screen of (jailbroken) iPhone?

I want to simulate a click on the icon of an app on the home screen of jailbroken iPhone. I used the code below, but it could not take effect. Did I do something wrong?
Is the method to getFrontMostAppPort() right? Event if I tried to use GSSendSystemEvent(), it had no effect.
BTW, I mean jailbroken device. Could anyone give me a help? I very much appreciate it.
// Framework Paths
#define SBSERVPATH "/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices"
static mach_port_t getFrontMostAppPort() {
bool locked;
bool passcode;
mach_port_t *port;
void *lib = dlopen(SBSERVPATH, RTLD_LAZY);
int (*SBSSpringBoardServerPort)() = dlsym(lib, "SBSSpringBoardServerPort");
void* (*SBGetScreenLockStatus)(mach_port_t* port, bool *lockStatus, bool *passcodeEnabled) = dlsym(lib, "SBGetScreenLockStatus");
port = (mach_port_t *)SBSSpringBoardServerPort();
dlclose(lib);
SBGetScreenLockStatus(port, &locked, &passcode);
void *(*SBFrontmostApplicationDisplayIdentifier)(mach_port_t *port, char *result) = dlsym(lib, "SBFrontmostApplicationDisplayIdentifier");
char appId[256];
memset(appId, 0, sizeof(appId));
SBFrontmostApplicationDisplayIdentifier(port, appId);
NSString * frontmostApp=[NSString stringWithFormat:#"%s",appId];
if([frontmostApp length] == 0 || locked)
return GSGetPurpleSystemEventPort();
else
return GSCopyPurpleNamedPort(appId);
}
static void sendTouchEvent(GSHandInfoType handInfoType, CGPoint point) {
uint8_t touchEvent[sizeof(GSEventRecord) + sizeof(GSHandInfo) + sizeof(GSPathInfo)];
// structure of touch GSEvent
struct GSTouchEvent {
GSEventRecord record;
GSHandInfo handInfo;
} * event = (struct GSTouchEvent*) &touchEvent;
bzero(touchEvent, sizeof(touchEvent));
// set up GSEvent
event->record.type = kGSEventHand;
event->record.subtype = kGSEventSubTypeUnknown;
event->record.windowLocation = point;
event->record.timestamp = GSCurrentEventTimestamp();
event->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
event->handInfo.type = handInfoType;
event->handInfo.x52 = 1;
bzero(&event->handInfo.pathInfos[0], sizeof(GSPathInfo));
event->handInfo.pathInfos[0].pathIndex = 1;
event->handInfo.pathInfos[0].pathIdentity = 2;
event->handInfo.pathInfos[0].pathProximity = (handInfoType == kGSHandInfoTypeTouchDown || handInfoType == kGSHandInfoTypeTouchDragged || handInfoType == kGSHandInfoTypeTouchMoved) ? 0x03 : 0x00;;
event->handInfo.pathInfos[0].pathLocation = point;
mach_port_t port = (mach_port_t)getFrontMostAppPort();
GSSendEvent((GSEventRecord *)event, port);
}
// why nothing happened?
static clickOnHome() {
sendTouchEvent(kGSHandInfoTypeTouchDown, CGPointMake(100, 200));
sleep(1);
sendTouchEvent(kGSHandInfoTypeTouchUp, CGPointMake(100, 200));
}
Yes, I think your getFrontMostAppPort() method is fine, if you got it from here.
I'm trying to understand what you want:
If you simply want to open up a particular app (by bundleId), then I would recommend using the command-line open utility available on Cydia. You can call this programmatically with system(), or an exec call. Or, if you want to build this "open" capability into your own app, see my answer here.
Now, maybe you are writing code for an app or tweak that's in the background, not the foreground app. And, maybe you really do need to touch a specific {x,y} coordinate, not open an app by its bundleId. If you really want that, this code works for me (based on this answer ... with corrections):
static void sendTouchEvent(GSHandInfoType handInfoType, CGPoint point) {
uint8_t gsTouchEvent[sizeof(GSEventRecord) + sizeof(GSHandInfo) + sizeof(GSPathInfo)];
// structure of touch GSEvent
struct GSTouchEvent {
GSEventRecord record;
GSHandInfo handInfo;
} * touchEvent = (struct GSTouchEvent*) &gsTouchEvent;
bzero(touchEvent, sizeof(touchEvent));
touchEvent->record.type = kGSEventHand;
touchEvent->record.subtype = kGSEventSubTypeUnknown;
touchEvent->record.location = point;
touchEvent->record.windowLocation = point;
touchEvent->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
touchEvent->record.timestamp = GSCurrentEventTimestamp();
//touchEvent->record.window = winRef;
//touchEvent->record.senderPID = 919;
bzero(&touchEvent->handInfo, sizeof(GSHandInfo));
bzero(&touchEvent->handInfo.pathInfos[0], sizeof(GSPathInfo));
GSHandInfo touchEventHandInfo;
touchEventHandInfo._0x5C = 0;
touchEventHandInfo.deltaX = 0;
touchEventHandInfo.deltaY = 0;
touchEventHandInfo.height = 0;
touchEventHandInfo.width = 0;
touchEvent->handInfo = touchEventHandInfo;
touchEvent->handInfo.type = (handInfoType == kGSHandInfoTypeTouchDown) ? 2 : 1;
touchEvent->handInfo.deltaX = 1;
touchEvent->handInfo.deltaY = 1;
touchEvent->handInfo.pathInfosCount = 0;
touchEvent->handInfo.pathInfos[0].pathIndex = 1;
touchEvent->handInfo.pathInfos[0].pathIdentity = 2;
touchEvent->handInfo.pathInfos[0].pathProximity = (handInfoType == kGSHandInfoTypeTouchDown || handInfoType == kGSHandInfoTypeTouchDragged || handInfoType == kGSHandInfoTypeTouchMoved) ? 0x03: 0x00;
touchEvent->handInfo.x52 = 1; // iOS 5+, I believe
touchEvent->handInfo.pathInfos[0].pathLocation = point;
//touchEvent->handInfo.pathInfos[0].pathWindow = winRef;
GSEventRecord* record = (GSEventRecord*) touchEvent;
record->timestamp = GSCurrentEventTimestamp();
GSSendEvent(record, getFrontMostAppPort());
}
- (void) simulateHomeScreenTouch {
CGPoint location = CGPointMake(50, 50);
sendTouchEvent(kGSHandInfoTypeTouchDown, location);
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
sendTouchEvent(kGSHandInfoTypeTouchUp, location);
});
}
This will send a touch down/up event pair to SpringBoard, as long as SpringBoard is the frontmost app (no other app open). Also, you can see where the handInfoType value is mapped to 2 or 1 for touch down and up events. The code above assumes that those are the only two types of events you're generating.
Note: I first tried with your coordinates of x=100, y=200, and nothing happened. I think that coordinate is between two home screen icons. Using other coordinates (e.g. x=50, y=50) works fine.
Note II: I don't believe this solution actually requires jailbreaking. It uses Private APIs, so it can't be submitted to the App Store, but this should work for jailed phones in an enterprise, or hobbyist deployment.