예제 #1
0
파일: main.cpp 프로젝트: Felard/MoSync
void testReadOverload(const char* url) {
	Handle conn = maConnect(url);
	if(conn < 0) {
		printf("maConnect error %i\n", conn);
		return;
	}

	int result = 0;
	char buffer[1024];
	while(result >= 0) {
		EVENT event;
		while(maGetEvent(&event)) {
			if(event.type == EVENT_TYPE_CLOSE ||
				(event.type == EVENT_TYPE_KEY_PRESSED && event.key == MAK_0))
			{
				maExit(0);
			} else if(event.type == EVENT_TYPE_CONN) {
				printf("Op %i result %i\n", event.conn.opType, event.conn.result);
				MAASSERT(event.conn.handle == conn);
				result = event.conn.result;
				MAASSERT(result != 0);
			}
		}
		if(result == 0) {
			maWait(0);
		} else {
			maConnRead(conn, buffer, sizeof(buffer));
		}
	}
	printf("Done.\n");
}
예제 #2
0
파일: main.cpp 프로젝트: Felard/MoSync
// Reads a log file from a s60v3 debug runtime.
static bool tryToRead() {
	MAUtil::String filename = "C:/Data/msrlogold.txt";
	printf("Open '%s'\n", filename.c_str());
	MAHandle file = maFileOpen(filename.c_str(), MA_ACCESS_READ);
	if(file < 0) {
		printf("Error %i\n", file);
		return false;
	}
	int res = maFileExists(file);
	MAASSERT(res >= 0);
	if(!res) {
		printf("File does not exist.\n");
		return false;
	}
	int size = maFileSize(file);
	printf("Size: %i\n", size);
	MAASSERT(size >= 0);
	static char data[32*1024];
	MAASSERT(size < (int)sizeof(data));
	res = maFileRead(file, data, size);
	MAASSERT(res == 0);
	data[32] = 0;
	printf("%s\n", data);
	printf("Closing...\n");
	res = maFileClose(file);
	MAASSERT(res == 0);
	printf("Done.\n");
	return true;
}
예제 #3
0
//returns false on failure
bool Database::readDevice(DataHandler& data, DEVICE& dev) {
	//address
	TEST(data.read(&dev.address, BTADDR_LEN));

	//name
	int strLen;
	TEST(data.read(&strLen, sizeof(int)));
	StringData<char>* sd = new StringData<char>(strLen);
	dev.name.setData(sd);
	MAASSERT(sd->getRefCount() == 1);
	TEST(data.read(sd->pointer(), strLen));
	dev.name[strLen] = 0;

	//services
	int nServ;
	TEST(data.read(&nServ, sizeof(int)));
	dev.services.resize(nServ);
	for(int i=0; i<nServ; i++) {
		BtService& serv(dev.services[i]);
		TEST(data.read(&serv.port, sizeof(int)));
		TEST(data.read(&strLen, sizeof(int)));
		sd = new StringData<char>(strLen);
		serv.name.setData(sd);
		MAASSERT(sd->getRefCount() == 1);
		TEST(data.read(sd->pointer(), strLen));
		serv.name[strLen] = 0;
	}
	mNServices += nServ;
	return true;
}
예제 #4
0
static bool cleanOut(const char* dir) {
	printf("cleanOut(%s)\n", dir);
	MAHandle list = maFileListStart(dir, "*");
	MAT(list);
	char buf[2048];
	int dirLen = strlen(dir);
	strcpy(buf, dir);
	int freeBufSpace = sizeof(buf) - dirLen;
	while(1) {
		int res;
		MAHandle fh;
		char* fileName = buf + dirLen;
		res = maFileListNext(list, fileName, freeBufSpace);
		MAT_CUSTOM(res, (_res < 0 || _res >= freeBufSpace));
		if(res == 0)
			return true;
		if(fileName[res-1] == '/') {
			if(!cleanOut(buf))
				return false;
		}
		MAT(fh = maFileOpen(buf, MA_ACCESS_READ_WRITE));
		res = maFileDelete(fh);
		MAASSERT(maFileClose(fh) == 0);
		MAT(res);
	}
	MAASSERT(maFileListClose(list) == 0);
	return true;
}
예제 #5
0
파일: main.cpp 프로젝트: ronald132/MoSync
static bool tryToWrite(const MAUtil::String& dir) {
    MAUtil::String filename = dir + "test.txt";
    printf("Open '%s'\n", filename.c_str());
    MAHandle file = maFileOpen(filename.c_str(), MA_ACCESS_READ_WRITE);
    if(file < 0) {
        printf("Error %i\n", file);
        return false;
    }
    int res = maFileExists(file);
    MAASSERT(res >= 0);
    if(res) {
        printf("File exists.\n");
    } else {
        printf("Creating file...\n");
        res = maFileCreate(file);
        if(res < 0) {
            printf("Error %i\n", res);
            return false;
        }
    }
    static const char data[] = "asfihu89ph4nma98fjioan9phadf89h239hdad9h89p\n";
    printf("Writing %lu bytes...\n", sizeof(data));
    res = maFileWrite(file, data, sizeof(data));
    MAASSERT(res == 0);
    printf("Closing...\n");
    res = maFileClose(file);
    MAASSERT(res == 0);
    printf("Done.\n");
    return true;
}
예제 #6
0
int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...) {
  va_list ap;
  int str_l;

  *ptr = NULL;
  va_start(ap, fmt);                            /* measure the required size */
  str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap);
  va_end(ap);
  MAASSERT(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */
  if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1;      /* truncate */
  /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */
  if (str_m == 0) {  /* not interested in resulting string, just return size */
  } else {
    *ptr = (char *) malloc(str_m);
    if (*ptr == NULL) { str_l = -1; }
    else {
      int str_l2;
      va_start(ap, fmt);
      str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
      va_end(ap);
      MAASSERT(str_l2 == str_l);
    }
  }
  return str_l;
}
예제 #7
0
파일: main.cpp 프로젝트: Felard/MoSync
void testConnectOverload(const char* url, bool acceptSuccess) {
	int connects = 0, events = 0;
	int result = 0;
	int conn;
	bool hasConn = false;
	MAUtil::Vector<Handle> conns;
	do {
		EVENT event;
		while(maGetEvent(&event)) {
			if(event.type == EVENT_TYPE_CLOSE ||
				(event.type == EVENT_TYPE_KEY_PRESSED && event.key == MAK_0))
			{
				maExit(0);
			} else if(event.type == EVENT_TYPE_CONN) {
				printf("Op %i conn %i result %i\n", event.conn.opType, event.conn.handle, event.conn.result);
				MAASSERT(event.conn.opType == CONNOP_CONNECT);
				conn = event.conn.handle;
				if(acceptSuccess) {
					if(event.conn.result < 0) {
						result = event.conn.result;
					}
				} else {
					result = event.conn.result;
				}
				MAASSERT(event.conn.result != 0);
				hasConn = true;
				events++;
				printf("Event %i\n", events);
				break;
			}
		}
		if(result == 0) {
			conn = maConnect(url);
			conns.add(conn);
			if(conn < 0) {
				printf("maConnect error %i\n", conn);
				result = conn;
				hasConn = false;
			} else {
				connects++;
				printf("Connect %i\n", connects);
			}
		} else if(events != connects)
			maWait(0);
	} while(events != connects);// && connects < 3);
	if(hasConn) {
		printf("Result %i on handle %i after %i connects\n", result, conn, connects);
	} else {
		printf("Result %i after %i connects\n", result, connects);
	}
	printf("Closing %i handles\n", conns.size());
	for(int i=0; i<conns.size(); i++) {
		maConnClose(conns[i]);
	}
	printf("Done.\n");
}
void SettingsScreen::saveSettings() {
	//return;
	// Construct the filename.
	this->mScreen->initalizeHelper(mAppCodeBox->getText(), mAppUniqBox->getText(), Cloudbase::MD5(mAppPwdBox->getText()).hexdigest());
	return;

	MAUtil::String filename = getLocalPath() + SETTINGS_FILE_NAME;

	// Open the file handle.
	printf("Open '%s'\n", filename.c_str());
	MAHandle file = maFileOpen(filename.c_str(), MA_ACCESS_READ_WRITE);
	if(file < 0) {
		printf("Error opening file %i\n", file);
		return;
	}

	// If the file exists...
	int res = maFileExists(file);
	MAASSERT(res >= 0);
	if(res) {
		// Truncate it, deleting any old data.
		printf("Truncating file...\n");
		res = maFileTruncate(file, 0);
		MAASSERT(res == 0);
	} else {
		// Otherwise, create it.
		printf("Creating file...\n");
		res = maFileCreate(file);
		MAASSERT(res >= 0);
	}
	// In either case, we now have an empty file at our disposal.

	// Write some data.
	MAUtil::String settingsData = "";
	settingsData += mAppCodeBox->getText();
	settingsData += ",";
	settingsData += mAppUniqBox->getText();
	settingsData += ",";
	settingsData += Cloudbase::MD5(mAppPwdBox->getText()).hexdigest();

	//static const char data[] = strdup(settingsData.c_str());

	res = maFileWrite(file, settingsData.c_str(), settingsData.length());
	MAASSERT(res == 0);

	// Close the file.
	printf("Closing...\n");
	res = maFileClose(file);
	MAASSERT(res == 0);

	printf("Done.\n");
	this->loadSettings();
	//return true;
}
예제 #9
0
// each record has this format: {
// char name[];	// null-terminated
// byte data[];	// terminated by end of record.
// }
void setup_filesystem() {
	printf("setup_filesystem\n");
	// first, we must find a temporary directory which we can work out of.
	// we'll probably want to chroot() to it, too.
	char newRoot[MAX_PATH] = "";
	MAASSERT(makeDir(newRoot, 0, "mosync_root/", sizeof(newRoot)));
	int newRootLen = strlen(newRoot);
	MAASSERT(chdir(newRoot) == 0);
	MAASSERT(chroot(".") == 0);
	// now we have the root of a unix file-system.
	
	const MAHandle start = maFindLabel("start");
	const MAHandle end = maFindLabel("end");
	MAASSERT(start > 0 && end > 0);
	printf("%i files:\n", end - (start+1));
	
	for(MAHandle i=start+1; i<end; i++) {
		char buf[MAX_PATH];
		int size = maGetDataSize(i);
		int pathlen = MIN(MAX_PATH, size);
		maReadData(i, buf, 0, pathlen);
		const char* name = buf;
		int namelen = strlen(name);
		MAASSERT(namelen < MAX_PATH);
		int dataOffset = namelen+1;
		int dataLen = size - dataOffset;
		printf("%i: %s (%i bytes)\n", i, name, dataLen);
		
		bool isDirectory = name[namelen-1] == '/';
		if(isDirectory) {
			// there can be no data in a directory.
			MAASSERT(dataLen == 0);
			MAASSERT(!mkdir(name, 0755));
		} else {
			// Because we want to use maFileWriteFromData(), we can't use open() here.
			char realName[MAX_PATH];
			MAHandle fh;
			bool res;
			
			memcpy(realName, newRoot, newRootLen);
			// overwrite the slash in newRoot, so we don't get double slashes.
			memcpy(realName + newRootLen - 1, name, namelen + 1);
			
			MAASSERT((fh = maFileOpen(realName, MA_ACCESS_READ_WRITE)) > 0);
			res = writeFile(fh, i, dataOffset, dataLen);
			MAASSERT(maFileClose(fh) >= 0);
			MAASSERT(res);
		}
	}
}
예제 #10
0
void FileLister::close() {
	if(mList > 0) {
		int res = maFileListClose(mList);
		MAASSERT(res == 0);
		mList = -1;
	}
}
예제 #11
0
void SoapRequest::httpFinished(HttpConnection* http, int result) {
	MAASSERT(http == &mHttp);
	if(result < 200 || result >= 300) {
		mListener->soapError(result);
		return;
	}
	MAASSERT(mState == eFinishing);

	LOG("recv\n");
	mResponsePtr = mResponseBuffer;
	mHttp.recv(mResponseBuffer, BUFLEN - 1);	// -1 for null terminator
	mState = eReading;

	mContext.init(this, this);
	mInBody = false;
}
예제 #12
0
// Uses root buffer as scratch space.
// On success, writes full path of created directory to root.
// \param root Buffer that, on entry, contains directory path where searching should start.
// \param rootLen Length of string in root, excluding the terminating zero.
// \param name Name of the directory to create. Must end with '/'.
// \param bufLen Length of the buffer pointed to by \a root, in bytes.
static bool makeDir(char* root, int rootLen, const char* name, int bufLen) {
	// find a root path
	printf("makeDir(%s)\n", root);
	MAHandle list = maFileListStart(root, "*");
	MAT(list);
	int freeBufSpace = bufLen - rootLen;
	while(1) {
		int res;
		res = maFileListNext(list, root + rootLen, freeBufSpace);
		MAT_CUSTOM(res, _res < 0 || _res >= freeBufSpace);
		if(res == 0)
			return false;
		int resLen = rootLen + res;
		if(root[resLen-1] == '/') {
			MAASSERT(resLen + (int)strlen(name) < bufLen);
			//printf("Dir: '%s'\n", file.c_str());
			strcpy(root + resLen, name);
			if(tryToMake(root))
				return true;
			root[resLen] = 0;
			if(makeDir(root, resLen, name, bufLen))
				return true;
		}
	}
}
예제 #13
0
int FileLister::next(MAUtil::String& dst) {
	int len = maFileListNext(mList, NULL, 0);
	if(len <= 0)
		return len;
	dst.resize(len);
	len = maFileListNext(mList, dst.pointer(), len+1);
	MAASSERT(len > 0);
	return len;
}
예제 #14
0
int vasprintf(char **ptr, const char *fmt, va_list ap) {
  size_t str_m;
  int str_l;

  *ptr = NULL;
  {	va_list ap2;
    va_copy(ap2, ap);  /* don't consume the original ap, we'll need it again */
    str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/
    va_end(ap2);
  }
  MAASSERT(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */
  *ptr = (char *) malloc(str_m = (size_t)str_l + 1);
  if (*ptr == NULL) {  str_l = -1; }
  else {
    int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
    MAASSERT(str_l2 == str_l);
  }
  return str_l;
}
예제 #15
0
static bool tryToMake(const char* dir) {
	MAHandle file = maFileOpen(dir, MA_ACCESS_READ_WRITE);
	MAT(file);
	int res = maFileExists(file);
	MAASSERT(res >= 0);
	if(res) {
		printf("Dir exists.\n");
		// delete everything inside.
		return cleanOut(dir);
	} else {
		printf("Creating dir...\n");
		MAT(maFileCreate(file));
	}
	printf("Closing...\n");
	res = maFileClose(file);
	MAASSERT(res == 0);
	printf("Done: %s\n", dir);
	return true;
}
예제 #16
0
int asprintf(char **ptr, const char *fmt, /*args*/ ...) {
  va_list ap;
  size_t str_m;
  int str_l;

  *ptr = NULL;
  va_start(ap, fmt);                            /* measure the required size */
  str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap);
  va_end(ap);
  MAASSERT(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */
  *ptr = (char *) malloc(str_m = (size_t)str_l + 1);
  if (*ptr == NULL) { str_l = -1; }
  else {
    int str_l2;
    va_start(ap, fmt);
    str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
    va_end(ap);
    MAASSERT(str_l2 == str_l);
  }
  return str_l;
}
예제 #17
0
파일: main.c 프로젝트: Felard/MoSync
int testfwrite()
{
  FILE * pFile;
  char c;

  pFile=fopen("alphabet.txt","wt");
	MAASSERT(pFile);
  for (c = 'A' ; c <= 'Z' ; c++) {
    putc (c , pFile);
  }
  fclose (pFile);
  return 0;
}
예제 #18
0
int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap) {
  int str_l;

  *ptr = NULL;
  { va_list ap2;
    va_copy(ap2, ap);  /* don't consume the original ap, we'll need it again */
    str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/
    va_end(ap2);
  }
  MAASSERT(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */
  if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1;      /* truncate */
  /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */
  if (str_m == 0) {  /* not interested in resulting string, just return size */
  } else {
    *ptr = (char *) malloc(str_m);
    if (*ptr == NULL) { str_l = -1; }
    else {
      int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);
      MAASSERT(str_l2 == str_l);
    }
  }
  return str_l;
}
예제 #19
0
파일: main.c 프로젝트: Felard/MoSync
int testfopen() {
	FILE *f;
	int i;
	setCurrentFileSystem(RES_BUNDLE, 0);
	f = fopen("mafs.data", "rb");
	MAASSERT(f);

	for(i = 0; i < 10; i++) {
		int j;
		/*int ret =*/ fread(&j, sizeof(int), 1, f);
		if(i == j) {
			;//int a = 2;
		}
	}

	return 0;
}
예제 #20
0
void SoapRequest::connRecvFinished(Connection* conn, int result) {
	LOG("connRecvFinished %i\n", result);
	MAASSERT(conn == &mHttp);
	if(result < 0) {
		mListener->soapError(result);
		return;
	}

	mResponsePtr[result] = 0;
	mResponsePtr = mResponseBuffer;

	//can use feed() here instead of feedProcess()
	//for better performance if you know that the server speaks Latin-1
	mContext.feedProcess(mResponseBuffer);

	if(mState == eReading)
		mHttp.recv(mResponsePtr, BUFLEN - 1 - (mResponsePtr - mResponseBuffer));
}
MAUtil::String SettingsScreen::getLocalPath() {
    // Do this here to work around a MoRE bug.
    FileLister fl;
    fl.start("/");

    MAUtil::String path;
    // Try getting the local path.
    int result = getSystemProperty("mosync.path.local", path);
    // If it works, fine.
    if(result > 0) {
        printf("Got local path: %i\n", result);
        return path + "/";
    }
    printf("local path output %i", result);
    // Otherwise, get the first root directory.
    fl.start("");
    result = fl.next(path);
    MAASSERT(result > 0);
    return path;
}
예제 #22
0
파일: main.cpp 프로젝트: AliSayed/MoSync
static bool deleteIfExist(const MAUtil::String& path) {
	MAHandle file = maFileOpen(path.c_str(), MA_ACCESS_READ_WRITE);
	if(file < 0) {
		printf("Error %i\n", file);
		return false;
	}
	int res = maFileExists(file);
	MAASSERT(res >= 0);
	if(res) {
		printf("File exists.\n");
		res = maFileDelete(file);
		if(res < 0) {
			printf("Error %i\n", res);
			return false;
		}
		printf("Deleted.\n");
	} else {
		printf("File doesn't exist.\n");
	}
	return true;
}
예제 #23
0
파일: helpers.c 프로젝트: Felard/MoSync
unsigned sleep(unsigned s) {
	lprintfln("sleep(%i)", s);
	const int start = maGetMilliSecondCount();
	const int end = start + s * 1000;
	do {
		int left = end - maGetMilliSecondCount();
		MAEvent e;
		if(left <= 0)
			break;
		while(maGetEvent(&e)) {
			if(e.type == EVENT_TYPE_CLOSE) {
				lprintfln("EVENT_TYPE_CLOSE");
				exit(42);
			}
		}
		maWait(left);
	} while(1);
	int passed = maGetMilliSecondCount() - start;
	MAASSERT(passed >= (int)s*1000);
	return 0;
}
예제 #24
0
int SoapRequest::start(const char* url, const void* data, int dataLen, SoapListener* listener) {
	MAASSERT(mState == eIdle);
	int res = mHttp.create(url, HTTP_POST);
	if(res < 0) {
		return res;
	}

	char buf[32];
	sprintf(buf, "%i", sSoapHeaderLength + dataLen + sSoapFooterLength);
	mHttp.setRequestHeader("Content-Length", buf);

	mHttp.setRequestHeader("Content-Type", SOAP_CONTENT_TYPE);

	mHttp.write(sSoapHeader, sSoapHeaderLength);

	mState = eWritingHeader;
	mListener = listener;
	mData = data;
	mDataLen = dataLen;
	return 0;
}
예제 #25
0
void SoapRequest::connWriteFinished(Connection* conn, int result) {
	MAASSERT(conn == &mHttp);
	if(result < 0) {
		mListener->soapError(result);
		return;
	}
	switch(mState) {
	case eWritingHeader:
		mHttp.write(mData, mDataLen);
		mState = eWritingData;
		break;
	case eWritingData:
		mHttp.write(sSoapFooter, sSoapFooterLength);
		mState = eWritingFooter;
		break;
	case eWritingFooter:
		mHttp.finish();
		mState = eFinishing;
		break;
	default:
		BIG_PHAT_ERROR;
	}
}
void SettingsScreen::loadSettings() {
	MAUtil::String filename = getLocalPath() + SETTINGS_FILE_NAME;

	MAHandle file = maFileOpen(filename.c_str(), MA_ACCESS_READ);
	if(file < 0) {
		printf("Error opening file %i\n", file);
		return;
	}

	// Check if the file exists.
	int res = maFileExists(file);
	MAASSERT(res >= 0);
	if(!res) {
		printf("File does not exist.\n");
		maFileClose(file);
		return;
	}

	// Get the file size.
	int size = maFileSize(file);
	printf("Size: %i\n", size);
	MAASSERT(size >= 0);

	// Read the file data.
	static char data[200];
	MAASSERT(size < (int)sizeof(data));
	res = maFileRead(file, data, size);
	MAASSERT(res == 0);

	// Close the file.
	printf("Closing...\n");
	res = maFileClose(file);
	MAASSERT(res == 0);

	printf("Done.\n");

	MAUtil::String contents = data;

	printf("Loaded settings string %s", contents.c_str());

	if (contents.findFirstOf(',', 0) <= 0)
		return;

	int commaPosition = contents.findFirstOf(',', 0);
	MAUtil::String appCode = contents.substr(0, commaPosition);
	mAppCodeBox->setText(appCode);
	printf("app code: %s", appCode.c_str());

	int prevCommaPosition = commaPosition + 1;
	commaPosition = contents.findFirstOf(',', prevCommaPosition);
	MAUtil::String appUniq = contents.substr(prevCommaPosition, commaPosition-prevCommaPosition);
	mAppUniqBox->setText(appUniq);
	printf("app uniq: %s", appUniq.c_str());

	prevCommaPosition = commaPosition + 1;
	commaPosition = contents.findFirstOf(',', prevCommaPosition);
	MAUtil::String appPwd = contents.substr(prevCommaPosition, contents.length() - prevCommaPosition);
	//mAppPwdBox->setText(appPwd);
	printf("app pwd: %s", appPwd.c_str());

	//helper = CBHelper(appCode, appUniq);
	//helper.setPassword(appPwd);
	this->mScreen->initalizeHelper(appCode, appUniq, appPwd);
}
예제 #27
0
파일: main.cpp 프로젝트: AliSayed/MoSync
void scan() {
	int nserv=0;
	MAEvent event;
#ifdef SCAN_DEVICES
scan_devices:
	int ndev=0;
	MABtDevice d;
	char namebuf[256];
	int res;

	printf("DevDisc...\n");
	int startTime = maGetMilliSecondCount();
	maBtStartDeviceDiscovery(1);
	//printf("Started\n");

	while(true) {
		d.name = namebuf;
		d.nameBufSize = sizeof(namebuf);

		do {
			strcpy(namebuf, "Hello Debugger!");
			res = maBtGetNewDevice(&d);
			if(res) {
				printf("d%i: %i %s\n", ndev++, res, d.name);
				if(res < 0) {
					break;
				}
				printf("%s\n", btaddr2string(d.address));
			} else {
				printf("res %i\n", res);
			}
		} while(res > 0);

		maWait(0);
		maGetEvent(&event);	//this oughta work, cause maWait(0) guarantees that there's at least one event.
		if(event.type == EVENT_TYPE_BT && event.state != 0)
			break;
		if(event.type == EVENT_TYPE_CLOSE ||
			(event.type == EVENT_TYPE_KEY_PRESSED && (event.key == MAK_0 || event.key == MAK_KP0)))
		{
			maExit(0);
		}
	}
	printf("Done %i, %i ms\n", event.state, maGetMilliSecondCount() - startTime);

	printf("Press 1 or 3\n");
	while(true) {
		maWait(0);
		maGetEvent(&event);
		if(event.type == EVENT_TYPE_CLOSE ||
			(event.type == EVENT_TYPE_KEY_PRESSED && (event.key == MAK_0 || event.key == MAK_KP0)))
		{
			maExit(0);
		}
		if(event.type == EVENT_TYPE_KEY_PRESSED && (event.key == MAK_1 || event.key == MAK_KP1)) {
			goto scan_devices;
		}
		if(event.type == EVENT_TYPE_KEY_PRESSED && (event.key == MAK_3 || event.key == MAK_KP3)) {
			break;
		}
	}


	const MABtAddr& address = d.address;
#else
	//const MABtAddr address = { { 0x00, 0x0f, 0xde, 0xa1, 0x4b, 0x70 } };	//K700i Jacob
	//const MABtAddr address = { { 0x00, 0x0b, 0x0d, 0x14, 0x99, 0x0f } };	//Holux
	//const MABtAddr address = { { 0x00, 0x11, 0x9f, 0xcb, 0x74, 0x10 } };	//6630 v1.0
	//const MABtAddr address = { { 0x00, 0x18, 0xc5, 0x3f, 0x74, 0x7e } };	//N73
	//const MABtAddr address = { { 0x00, 0x80, 0x98, 0x44, 0x74, 0xc8 } };	//MS-FREDRIK
	//const MABtAddr address = { { 0x00, 0x11, 0x67, 0x9c, 0xd9, 0x3c } };	//MS-FREDRIK, new dongle
	const MABtAddr address = { { 0x00, 0x23, 0x3a, 0xb3, 0xc7, 0x82 } };	//Samsung SGH-i900
#endif	//SCAN_DEVICES

	printf("ServDisc %s\n", btaddr2string(address));
	int servStartTime = maGetMilliSecondCount();
	maBtStartServiceDiscovery(&address, &L2CAP_PROTOCOL_MAUUID);

	while(true) {
		MABtService s;
		char sNameBuf[256];
		static const int MAX_UUIDS = 32;
		MAUUID uuidBuf[MAX_UUIDS];
		int res;
		s.name = sNameBuf;
		s.nameBufSize = sizeof(sNameBuf);
		s.uuids = uuidBuf;

		//printfln("state: %i\n", maBtDiscoveryState2());
		do {
			strcpy(sNameBuf, "Hello Sebugger!");
			MABtServiceSize ss;
			res = maBtGetNextServiceSize(&ss);
			if(res) {
				MAASSERT(ss.nUuids <= MAX_UUIDS);
				if(ss.nameBufSize < 0) {
					printf("%i\n", ss.nameBufSize);
				}
				res = maBtGetNewService(&s);
				if(res) {
					if(ss.nameBufSize < 0) {
						printf("s%i: %i %i No name\n", nserv++, res, s.port);
					} else {
						printf("s%i: %i %i %i \"%s\"\n", nserv++, res, s.port, ss.nameBufSize, s.name);
					}
					/*for(int j=0; j<ss.nUuids; j++) {
						int* u = s.uuids[j].i;
						printf("%08X-%08X-%08X-%08X\n", u[0], u[1], u[2], u[3]);
					}*/
					if(res < 0) {
						//printf("res1 %i\n", res);
						break;
					}
				} else {
					//printf("res2 %i\n", res);
				}
			} else {
				//printf("res3 %i\n", res);
			}
		} while(res > 0);

		maWait(0);
		maGetEvent(&event);
		if(event.type == EVENT_TYPE_BT) {
			//printf("event %i\n", event.state);
			if(event.state != 0)
				break;
		}
		if(event.type == EVENT_TYPE_CLOSE ||
			(event.type == EVENT_TYPE_KEY_PRESSED && (event.key == MAK_0 || event.key == MAK_KP0)))
		{
			maExit(0);
		}
	}
	printf("Done %i, %i ms\n", event.state, maGetMilliSecondCount() - servStartTime);
#ifdef SCAN_DEVICES
	printf("Done, total %i ms\n", maGetMilliSecondCount() - startTime);
#endif	//SCAN_DEVICES
}