static void Main(string[] args) { Console.WriteLine("Loading app bundle:"); var bundle = new PebbleBundle("demo.pbw"); Console.WriteLine(bundle); Console.WriteLine("Loading fw bundle:"); bundle = new PebbleBundle("normal_ev2_4_v1.10.0.pbz"); Console.WriteLine(bundle); Console.ReadLine(); }
static void AddApp(Pebble pebble, string watch=null, bool removeFirst = false) { string watchdir=null; if (String.IsNullOrEmpty(watch)) { watchdir = ConfigurationManager.AppSettings["watch-dir"]; if (watchdir == null) { Console.WriteLine("Missing .config entry for 'watch-dir'"); return; } if (!Directory.Exists(watchdir)) { Console.WriteLine("watch-dir not found: {0}", watchdir); return; } } var appbank = pebble.GetAppbankContents().AppBank; var applist = appbank.Apps; if (applist.Count == appbank.Size) { Console.WriteLine("All {0} banks are full", appbank.Size); return; } try { if (String.IsNullOrEmpty(watch)) { Console.WriteLine("Choose an app to install"); var watches = Directory.GetFiles(watchdir, "*.pbw"); watch = SharpMenu<string>.WriteAndPrompt(watches); watch = Path.Combine(watchdir, watch); } if (removeFirst) { PebbleBundle pb = new PebbleBundle(watch); var app2remove = applist.Find(delegate(AppBank.App app) { return app.Name == pb.Application.AppName; }); if (app2remove.Name != null) { Console.WriteLine("Removing existing..."); pebble.RemoveApp(app2remove); Thread.Sleep(2000); // let things settle } } Console.WriteLine("Installing..."); pebble.InstallApp(watch, applist.Count); } catch(Exception ex) { Console.WriteLine(ex.Message); } }
public void InstallApp(string path, int firstFree /*TODO, bool installApp*/) { PebbleBundle bundle = new PebbleBundle(path); if (bundle.BundleType != PebbleBundle.BundleTypes.Application) { throw new Exception("not an app"); } PutBytesClient c = new PutBytesClient(this, (uint)firstFree, PutBytesType.Binary, bundle.Binary); c.init(); while (!c.IsDone && !c.HasError) { Thread.Sleep(1000); } if (c.HasError) { throw new Exception("couldn't send app"); } if (bundle.HasResources) { c = new PutBytesClient(this, (uint)firstFree, PutBytesType.Resources, bundle.ResourcesBinary); c.init(); while (!c.IsDone && !c.HasError) { Thread.Sleep(1000); } if (c.HasError) { throw new Exception("couldn't send resources"); } } var msg = Util.Pack("!bI", 3, firstFree); Thread.Sleep(2000); sendMessage(Endpoints.APP_MANAGER, msg); Thread.Sleep(2000); }
public async Task InstallAppAsync(PebbleBundle bundle, IProgress <ProgressValue> progress = null) { if (bundle == null) { throw new ArgumentNullException("bundle"); } if (bundle.BundleType != PebbleBundle.BundleTypes.Application) { throw new ArgumentException("Bundle must be an application"); } if (progress != null) { progress.Report(new ProgressValue("Removing previous install(s) of the app if they exist", 1)); } var metaData = bundle.AppMetadata; var uuid = metaData.UUID; AppbankInstallResponse appbankInstallResponse = await RemoveAppByUUID(uuid); if (appbankInstallResponse.Success == false) { return; } if (progress != null) { progress.Report(new ProgressValue("Getting current apps", 10)); } AppbankResponse appBankResult = await GetAppbankContentsAsync(); if (appBankResult.Success == false) { throw new PebbleException("Could not obtain app list; try again"); } var appBank = appBankResult.AppBank; byte firstFreeIndex = 1; foreach (var app in appBank.Apps) { if (app.Index == firstFreeIndex) { firstFreeIndex++; } } if (firstFreeIndex == appBank.Size) { throw new PebbleException("All app banks are full"); } if (progress != null) { progress.Report(new ProgressValue("Reading app data", 30)); } var zipFile = ZipFile.Read(bundle.FullPath); var appEntry = zipFile.Entries.FirstOrDefault(x => x.FileName == bundle.Manifest.Application.Filename); if (appEntry == null) { throw new PebbleException("Could find application file"); } byte[] appBinary = Util.GetBytes(appEntry); if (progress != null) { progress.Report(new ProgressValue("Transferring app to Pebble", 50)); } if (await PutBytes(appBinary, firstFreeIndex, TransferType.Binary) == false) { throw new PebbleException(string.Format("Failed to send application binary {0}/pebble-app.bin", bundle.FullPath)); } if (bundle.HasResources) { var resourcesEntry = zipFile.Entries.FirstOrDefault(x => x.FileName == bundle.Manifest.Resources.Filename); if (resourcesEntry == null) { throw new PebbleException("Could not find resource file"); } byte[] resourcesBinary = Util.GetBytes(resourcesEntry); if (progress != null) { progress.Report(new ProgressValue("Transferring app resources to Pebble", 70)); } if (await PutBytes(resourcesBinary, firstFreeIndex, TransferType.Resources) == false) { throw new PebbleException(string.Format("Failed to send application resources {0}/app_resources.pbpack", bundle.FullPath)); } } if (progress != null) { progress.Report(new ProgressValue("Adding app", 90)); } await AddApp(firstFreeIndex); if (progress != null) { progress.Report(new ProgressValue("Done", 100)); } }
public void InstallApp(string path, int firstFree/*TODO, bool installApp*/) { PebbleBundle bundle = new PebbleBundle(path); if (bundle.BundleType != PebbleBundle.BundleTypes.Application) { throw new Exception("not an app"); } PutBytesClient c = new PutBytesClient(this, (uint)firstFree, PutBytesType.Binary, bundle.Binary); c.init(); while (!c.IsDone && !c.HasError) Thread.Sleep(1000); if (c.HasError) throw new Exception("couldn't send app"); if (bundle.HasResources) { c = new PutBytesClient(this, (uint)firstFree, PutBytesType.Resources, bundle.ResourcesBinary); c.init(); while (!c.IsDone && !c.HasError) Thread.Sleep(1000); if (c.HasError) throw new Exception("couldn't send resources"); } var msg = Util.Pack("!bI", 3, firstFree); Thread.Sleep(2000); sendMessage(Endpoints.APP_MANAGER, msg); Thread.Sleep(2000); }
static void TestPack() { #if DEBUG if (ConfigurationManager.AppSettings["watch-dir"] != null) { PebbleBundle bundle = new PebbleBundle(Path.Combine(ConfigurationManager.AppSettings["watch-dir"],"brains.pbw")); } var items = new object[] { (sbyte)-11, -123, UInt32.MaxValue, (byte)244, (uint)0,short.MinValue,ushort.MaxValue,Int32.MinValue,UInt32.MaxValue,"12345","1234","123456","DOES_NOT_MATTER","a" }; var data = Util.Pack("!biIBIhHlL5s5s5s0ss",items); var ritems = Util.Unpack("!biIBIhHlL5s5s5s0ss", data); if (items.Length != ritems.Length) throw new Exception(); if ((sbyte)items[0] != (sbyte)ritems[0]) throw new Exception(); if ((int)items[1] != (int)ritems[1]) throw new Exception(); if ((uint)items[2] != (uint)ritems[2]) throw new Exception(); if ((byte)items[3] != (byte)ritems[3]) throw new Exception(); if ((uint)items[4] != (uint)ritems[4]) throw new Exception(); if ((short)items[5] != (short)ritems[5]) throw new Exception(); if ((ushort)items[6] != (ushort)ritems[6]) throw new Exception(); if ((int)items[7] != (int)ritems[7]) throw new Exception(); if ((uint)items[8] != (uint)ritems[8]) throw new Exception(); if ((string)items[9] != (string)ritems[9]) throw new Exception(); // normal string if ((string)items[10] != (string)ritems[10]) throw new Exception(); // shorter than expected if (((string)items[11]).Substring(0,5) != (string)ritems[11]) throw new Exception(); // longer than expected if ("" != (string)ritems[12]) throw new Exception(); // empty string if ((string)items[13] != (string)ritems[13]) throw new Exception(); // implied string length of 1 items = new object[] { Byte.MaxValue, (byte)100,ushort.MaxValue }; data = Util.Pack("!2BH", items); ritems = Util.Unpack("!2BH", data); if ((byte)items[0] != (byte)ritems[0]) throw new Exception(); if ((byte)items[1] != (byte)ritems[1]) throw new Exception(); if ((ushort)items[2] != (ushort)ritems[2]) throw new Exception(); ritems = Util.Unpack("!2SH",data); // interpret as byte[] if (!System.Linq.Enumerable.SequenceEqual(new byte[]{Byte.MaxValue,(byte)100}, (byte[]) ritems[0])) throw new Exception(); if ((ushort)items[2] != (ushort)ritems[1]) throw new Exception(); if (Util.GetPackedDataSize("!II32s32sIH") != 78) throw new Exception(); if (Util.GetPackedDataSize("!2i32s32si2B") != 78) throw new Exception(); #endif }
static void p(string[] args) { //https://github.com/Hexxeh/libpebble/blob/master/pebble/pebble.py Dictionary<string,string> argmap = new Dictionary<string,string>(); argmap["pebble_id"]=null; for (int i=0;i<args.Length;++i) { var arg = args[i]; if (arg == "--test") { argmap["test"] = "yes"; } else if (arg == "--pebble_id") { var addr = i+1<args.Length?args[++i]:null; if (addr.Length > 4) { // assume BT addr or shortcut addr = addr.Replace(":",""); addr = addr.Substring(addr.Length-4,4); } argmap["pebble_id"] = addr; } else if (arg == "--nolaunch") { argmap["no_launch"] = ""; } else if (arg == "list") { argmap["list"] = ""; } else if (arg == "load") { argmap["load"] = i + 1 < args.Length ? args[++i] : null; } else if (arg == "reinstall") { argmap["load"] = i + 1 < args.Length ? args[++i] : null; argmap["unload"] = argmap["load"]; } } if (argmap.ContainsKey("test")) { TestPack(); return; } var pebble = Pebble.GetPebble(argmap["pebble_id"]); try { pebble.Connect(); } catch (System.IO.IOException e) { Console.Write("Connection failed: "); Console.WriteLine(e.Message); Console.WriteLine("Press enter to exit."); Console.ReadLine(); return; } Console.WriteLine("Successfully connected!"); Console.WriteLine(pebble); if (argmap.ContainsKey("list")) { Console.WriteLine(pebble.GetAppbankContents().AppBank); } else if (argmap.ContainsKey("load")) { if (argmap.ContainsKey("unload")) { PebbleBundle pb = new PebbleBundle(argmap["load"]); var apps = pebble.GetAppbankContents().AppBank.Apps; var app = apps.Find(a => pb.Application.AppName == a.Name); if (app.Name != null) // in case it didn't find it pebble.RemoveApp(app); } AddApp(pebble, argmap["load"]); } }