// 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");
                }
            }
        }
Esempio n. 4
0
        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;
            }
        }