// Device constructor. Automatically call the YAPI functin to reindex device internal YDevice(YGenericHub hub, WPEntry wpRec, Dictionary <string, List <YPEntry> > ypRecs) { // private attributes _hub = hub; _wpRec = wpRec; _cache_expiration = 0; _cache_json = null; _moduleYPEntry = new YPEntry(wpRec.SerialNumber, "module", YPEntry.BaseClass.Function); _moduleYPEntry.LogicalName = wpRec.LogicalName; _ypRecs = new Dictionary <int?, YPEntry>(); List <string> keySet = ypRecs.Keys.ToList(); foreach (string categ in keySet) { foreach (YPEntry rec in ypRecs[categ]) { if (rec.Serial.Equals(wpRec.SerialNumber)) { int funydx = rec.Index; _ypRecs[funydx] = rec; } } } }
private async Task _processMore(int start) { if (start == 0) { return; } imm_reportprogress(0, "Firmware update started"); YFirmwareFile firmware; try { //1% -> 5% if (_firmwarepath.StartsWith("www.yoctopuce.com") || _firmwarepath.StartsWith("http://www.yoctopuce.com")) { this.imm_reportprogress(1, "Downloading firmware"); byte[] bytes = await YFirmwareUpdate._downloadfile(_firmwarepath); firmware = YFirmwareFile.imm_Parse(_firmwarepath, bytes); } else { imm_reportprogress(1, "Loading firmware"); firmware = YFirmwareUpdate._loadFirmwareFile(_firmwarepath); } //5% -> 10% imm_reportprogress(5, "check if module is already in bootloader"); YGenericHub hub = null; YModule module = YModule.FindModuleInContext(_yctx, _serial + ".module"); if (await module.isOnline()) { YDevice yDevice = await module.getYDevice(); hub = yDevice.Hub; } else { // test if already in bootloader foreach (YGenericHub h in _yctx._hubs) { List <string> bootloaders = await h.getBootloaders(); if (bootloaders.Contains(_serial)) { hub = h; break; } } } if (hub == null) { imm_reportprogress(-1, "Device " + _serial + " is not detected"); return; } await hub.firmwareUpdate(_serial, firmware, _settings, imm_firmware_progress); //80%-> 98% imm_reportprogress(80, "wait to the device restart"); ulong timeout = YAPI.GetTickCount() + 60000; await module.clearCache(); while (!await module.isOnline() && timeout > YAPI.GetTickCount()) { await Task.Delay(5000); try { await _yctx.UpdateDeviceList(); } catch (YAPI_Exception) { } } if (await module.isOnline()) { if (_settings != null) { await module.set_allSettingsAndFiles(_settings); await module.saveToFlash(); } imm_reportprogress(100, "Success"); } else { imm_reportprogress(-1, "Device did not reboot correctly"); } } catch (YAPI_Exception e) { imm_reportprogress(e.errorType, e.Message); Debug.WriteLine(e.ToString()); Debug.Write(e.StackTrace); } }
private void imm_handleNotifcation(YPktStreamHead ystream) { string functionId; int firstByte = ystream.imm_GetByte(0); bool isV2 = ystream.StreamType == YGenericHub.YSTREAM_NOTICE_V2; if (isV2 || firstByte <= NOTIFY_1STBYTE_MAXTINY || firstByte >= NOTIFY_1STBYTE_MINSMALL) { int funcvalType = (firstByte >> NOTIFY_V2_TYPE_OFS) & NOTIFY_V2_TYPE_MASK; int funydx = firstByte & NOTIFY_V2_FUNYDX_MASK; YPEntry ypEntry = imm_getYPEntryFromYdx(funydx); if (ypEntry != null) { if (ypEntry.Index == funydx) { if (funcvalType == YGenericHub.NOTIFY_V2_FLUSHGROUP) { // not yet used by devices } else { if ((firstByte & NOTIFY_V2_IS_SMALL_FLAG) != 0) { // added on 2015-02-25, remove code below when confirmed dead code throw new YAPI_Exception(YAPI.IO_ERROR, "Hub Should not fwd notification"); } int len = (int)ystream.Len; byte[] data = new byte[len]; ystream.imm_CopyData(data, 0); string funcval = YGenericHub.imm_decodePubVal(funcvalType, data, 1, len - 1); _hub.imm_handleValueNotification(SerialNumber, ypEntry.FuncId, funcval); } } } } else { string serial = ystream.imm_GetString(0, YAPI.YOCTO_SERIAL_LEN); if (SerialNumber == null) { SerialNumber = serial; } uint p = YAPI.YOCTO_SERIAL_LEN; int type = ystream.imm_GetByte(p++); switch (type) { case NOTIFY_PKT_NAME: _logicalname = ystream.imm_GetString(p, YAPI.YOCTO_LOGICAL_LEN); _beacon = ystream.imm_GetByte(p + YAPI.YOCTO_LOGICAL_LEN); break; case NOTIFY_PKT_PRODNAME: _product = ystream.imm_GetString(p, YAPI.YOCTO_PRODUCTNAME_LEN); break; case NOTIFY_PKT_CHILD: break; case NOTIFY_PKT_FIRMWARE: _firmware = ystream.imm_GetString(p, YAPI.YOCTO_FIRMWARE_LEN); p += YAPI.YOCTO_FIRMWARE_LEN; p += 2; _deviceid = (ushort)(ystream.imm_GetByte(p) + (ystream.imm_GetByte(p + 1) << 8)); break; case NOTIFY_PKT_FUNCNAME: functionId = ystream.imm_GetString(p, YAPI.YOCTO_FUNCTION_LEN); p += YAPI.YOCTO_FUNCTION_LEN; string funcname = ystream.imm_GetString(p, YAPI.YOCTO_LOGICAL_LEN); if (!_usbYP.ContainsKey(functionId)) { _usbYP[functionId] = new YPEntry(serial, functionId, YPEntry.BaseClass.Function); } _usbYP[functionId].LogicalName = funcname; break; case NOTIFY_PKT_FUNCVAL: functionId = ystream.imm_GetString(p, YAPI.YOCTO_FUNCTION_LEN); p += YAPI.YOCTO_FUNCTION_LEN; string funcval = ystream.imm_GetString(p, YAPI.YOCTO_PUBVAL_SIZE); _hub.imm_handleValueNotification(serial, functionId, funcval); break; case NOTIFY_PKT_STREAMREADY: _devState = DevState.StreamReadyReceived; _wp = new WPEntry(_logicalname, _product, _deviceid, "", _beacon, SerialNumber); _yctx._Log("Device " + SerialNumber + " ready.\n"); _currentTask.SetResult(true); break; case NOTIFY_PKT_LOG: //FIXME: handle log notification break; case NOTIFY_PKT_FUNCNAMEYDX: functionId = ystream.imm_GetString(p, YAPI.YOCTO_FUNCTION_LEN - 1); p += YAPI.YOCTO_FUNCTION_LEN - 1; byte funclass = ystream.imm_GetByte(p++); funcname = ystream.imm_GetString(p, YAPI.YOCTO_LOGICAL_LEN); p += YAPI.YOCTO_LOGICAL_LEN; byte funydx = ystream.imm_GetByte(p); if (!_usbYP.ContainsKey(functionId)) { _usbYP[functionId] = new YPEntry(serial, functionId, YPEntry.BaseClass.forByte(funclass)); } // update ydx _usbYP[functionId].Index = funydx; _usbYP[functionId].LogicalName = funcname; break; case NOTIFY_PKT_PRODINFO: break; default: //fixme: Find why this happening on my dev computer throw new YAPI_Exception(YAPI.IO_ERROR, "Invalid Notification"); } } }
protected internal virtual void handleNetNotification(string notification_line) { string ev = notification_line.Trim(); if (ev == "") { //empty (\n) ping notification drop it. return; } if (ev.Length >= 3 && ev[0] >= NOTIFY_NETPKT_CONFCHGYDX && ev[0] <= NOTIFY_NETPKT_TIMEAVGYDX) { // function value ydx (tiny notification) _hub._isNotifWorking = true; _notifRetryCount = 0; if (_notifyPos >= 0) { _notifyPos += ev.Length + 1; } int devydx = ev[1] - 65; // from 'A' int funydx = ev[2] - 48; // from '0' if ((funydx & 64) != 0) { // high bit of devydx is on second character funydx -= 64; devydx += 128; } string value = ev.Substring(3); if (_hub._serialByYdx.ContainsKey(devydx)) { string serial = _hub._serialByYdx[devydx]; string funcid; YDevice ydev = _hub._yctx._yHash.imm_getDevice(serial); if (ydev != null) { switch (ev[0]) { case NOTIFY_NETPKT_FUNCVALYDX: funcid = ydev.imm_getYPEntry(funydx).FuncId; if (!funcid.Equals("")) { // function value ydx (tiny notification) _hub.imm_handleValueNotification(serial, funcid, value); } break; case NOTIFY_NETPKT_DEVLOGYDX: Task dummyTask = ydev.triggerLogPull(); break; case NOTIFY_NETPKT_CONFCHGYDX: _hub.imm_handleConfigChangeNotification(serial); break; case NOTIFY_NETPKT_TIMEVALYDX: case NOTIFY_NETPKT_TIMEAVGYDX: case NOTIFY_NETPKT_TIMEV2YDX: if (funydx == 0xf) { int not_len = value.Length / 2; byte[] data = new byte[not_len]; for (int i = 0; i < not_len; i++) { string part = value.Substring(i * 2, 2); data[i] = Convert.ToByte(part, 16); } ydev.imm_setLastTimeRef(data); } else { funcid = ydev.imm_getYPEntry(funydx).FuncId; if (!funcid.Equals("")) { // timed value report List <int> report = new List <int>(1 + value.Length / 2); report.Add((ev[0] == NOTIFY_NETPKT_TIMEVALYDX ? 0 : (ev[0] == NOTIFY_NETPKT_TIMEAVGYDX ? 1 : 2))); for (int pos = 0; pos < value.Length; pos += 2) { int intval = Convert.ToInt32(value.Substring(pos, 2), 16); report.Add(intval); } _hub.imm_handleTimedNotification(serial, funcid, ydev.imm_getLastTimeRef(), ydev.imm_getLastDuration(), report); } } break; case NOTIFY_NETPKT_FUNCV2YDX: funcid = ydev.imm_getYPEntry(funydx).FuncId; if (!funcid.Equals("")) { byte[] rawval = decodeNetFuncValV2(YAPI.DefaultEncoding.GetBytes(value)); if (rawval != null) { string decodedval = YGenericHub.imm_decodePubVal(rawval[0], rawval, 1, 6); // function value ydx (tiny notification) _hub.imm_handleValueNotification(serial, funcid, decodedval); } } break; case NOTIFY_NETPKT_FLUSHV2YDX: // To be implemented later break; } } } } else if (ev.Length >= 5 && ev.StartsWith("YN01", StringComparison.Ordinal)) { _hub._isNotifWorking = true; _notifRetryCount = 0; if (_notifyPos >= 0) { _notifyPos += ev.Length + 1; } char notype = ev[4]; if (notype == NOTIFY_NETPKT_NOT_SYNC) { _notifyPos = Convert.ToInt32(ev.Substring(5)); } else { string[] parts; switch (notype) { case NOTIFY_NETPKT_NAME: // device name change, or arrival parts = ev.Substring(5).Split(','); _hub.imm_handleBeaconNotification(parts[0], Convert.ToInt32(parts[2])); _hub._devListExpires = 0; break; case NOTIFY_NETPKT_CHILD: // device plug/unplug case NOTIFY_NETPKT_FUNCNAME: // function name change case NOTIFY_NETPKT_FUNCNAMEYDX: // function name change (ydx) _hub._devListExpires = 0; break; case NOTIFY_NETPKT_FUNCVAL: // function value (long notification) parts = ev.Substring(5).Split(','); _hub.imm_handleValueNotification(parts[0], parts[1], parts[2]); break; } } } else { // oops, bad notification ? be safe until a good one comes _hub._isNotifWorking = false; _notifyPos = -1; } }