// 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 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"); } } }
internal override async Task updateDeviceListAsync(bool forceupdate) { ulong now = YAPI.GetTickCount(); if (forceupdate) { _devListExpires = 0; } if (_devListExpires > now) { return; } if (!_notificationHandler.Connected) { if (_reportConnnectionLost) { throw new YAPI_Exception(YAPI.TIMEOUT, "hub " + _http_params.Url + " is not reachable"); } else { return; } } string json_data; try { byte[] data = await _notificationHandler.hubRequestSync("GET /api.json", null, YIO_DEFAULT_TCP_TIMEOUT); json_data = YAPI.DefaultEncoding.GetString(data); } catch (YAPI_Exception) { if (_reportConnnectionLost) { throw; } return; } Dictionary <string, List <YPEntry> > yellowPages = new Dictionary <string, List <YPEntry> >(); List <WPEntry> whitePages = new List <WPEntry>(); YJSONObject loadval = new YJSONObject(json_data); loadval.parse(); if (!loadval.has("services") || !loadval.getYJSONObject("services").has("whitePages")) { throw new YAPI_Exception(YAPI.INVALID_ARGUMENT, "Device " + _http_params.Host + " is not a hub"); } _serial = loadval.getYJSONObject("module").getString("serialNumber"); YJSONArray whitePages_json = loadval.getYJSONObject("services").getYJSONArray("whitePages"); YJSONObject yellowPages_json = loadval.getYJSONObject("services").getYJSONObject("yellowPages"); if (loadval.has("network")) { string adminpass = loadval.getYJSONObject("network").getString("adminPassword"); _writeProtected = adminpass.Length > 0; } // Reindex all functions from yellow pages //HashMap<String, Boolean> refresh = new HashMap<String, Boolean>(); List <string> keys = yellowPages_json.keys(); foreach (string classname in keys) { YJSONArray yprecs_json = yellowPages_json.getYJSONArray(classname); List <YPEntry> yprecs_arr = new List <YPEntry>(yprecs_json.Length); for (int i = 0; i < yprecs_json.Length; i++) { YPEntry yprec = new YPEntry(yprecs_json.getYJSONObject(i)); yprecs_arr.Add(yprec); } yellowPages[classname] = yprecs_arr; } _serialByYdx.Clear(); // Reindex all devices from white pages for (int i = 0; i < whitePages_json.Length; i++) { YJSONObject jsonObject = whitePages_json.getYJSONObject(i); WPEntry devinfo = new WPEntry(jsonObject); int index = jsonObject.getInt("index"); _serialByYdx[index] = devinfo.SerialNumber; whitePages.Add(devinfo); } await updateFromWpAndYp(whitePages, yellowPages); // reset device list cache timeout for this hub now = YAPI.GetTickCount(); _devListExpires = now + _devListValidity; }