// Remove a device from YAPI after an unplug detected by device refresh internal virtual void imm_forgetDevice(string serial) { YDevice dev = _devs[serial]; if (dev == null) { return; } string lname = dev.imm_getLogicalName(); _devs.Remove(serial); if (_snByName.ContainsKey(lname) && _snByName[lname].Equals(serial)) { _snByName.Remove(lname); } YFunctionType module = _fnByType["Module"]; module.imm_forgetFunction(serial + ".module"); int count = dev.imm_functionCount(); for (int i = 0; i < count; i++) { YPEntry yp = dev.imm_getYPEntry(i); if (_fnByType.ContainsKey(yp.Classname)) { YFunctionType functionType = _fnByType[yp.Classname]; functionType.imm_forgetFunction(yp.HardwareId); } } }
// Reindex a device in YAPI after a name change detected by device refresh internal virtual void imm_reindexDevice(YDevice dev) { string serial = dev.imm_getSerialNumber(); string lname = dev.imm_getLogicalName(); _devs[serial] = dev; if (!lname.Equals("")) { _snByName[lname] = serial; } YFunctionType module = _fnByType["Module"]; YPEntry moduleYPEntry = dev.ModuleYPEntry; module.imm_reindexFunction(moduleYPEntry); int count = dev.imm_functionCount(); for (int i = 0; i < count; i++) { YPEntry yp = dev.imm_getYPEntry(i); string classname = yp.Classname; YFunctionType functionType; if (_fnByType.ContainsKey(classname)) { functionType = _fnByType[classname]; } else { functionType = new YFunctionType(classname, _yctx); _fnByType[classname] = functionType; } functionType.imm_reindexFunction(yp); } }
// Find the exact Hardware Id of the specified function, if currently connected // If device is not known as connected, return a clean error // This function will not cause any network access public virtual HWID imm_resolve(string func) { // Try to resolve str_func to a known Function instance, if possible, without any device access int dotpos = func.IndexOf('.'); if (dotpos < 0) { // First case: func is the logical name of a function if (_hwIdByName.ContainsKey(func)) { string hwid_str = _hwIdByName[func]; return(new HWID(hwid_str)); } // fallback to assuming that func is a logical name or serial number of a module // with an implicit function name (like serial.module for instance) func += string.Format(".{0}{1}", char.ToLower(_className[0]), _className.Substring(1)); } // Second case: func is in the form: device_id.function_id HWID hwid = new HWID(func); // quick lookup for a known pure hardware id if (_ypEntries.ContainsKey(hwid.ToString())) { return(hwid); } if (hwid.module.Length > 0) { // either the device id is a logical name, or the function is unknown YDevice dev = _yctx._yHash.imm_getDevice(hwid.module); if (dev == null) { throw new YAPI_Exception(YAPI.DEVICE_NOT_FOUND, "Device [" + hwid.module + "] not online"); } string serial = dev.imm_getSerialNumber(); hwid = new HWID(serial, hwid.Function); if (_ypEntries.ContainsKey(hwid.ToString())) { return(hwid); } // not found neither, may be funcid is a function logicalname int nfun = dev.imm_functionCount(); for (int i = 0; i < nfun; i++) { YPEntry yp = dev.imm_getYPEntry(i); if (yp.LogicalName.Equals(hwid.Function) && _ypEntries.ContainsValue(yp)) { return(new HWID(serial, yp.FuncId)); } } } else { // only functionId (ie ".temperature") foreach (string hwid_str in _connectedFns.Keys) { HWID tmpid = new HWID(hwid_str); if (tmpid.Function.Equals(hwid.Function)) { return(tmpid); } } } throw new YAPI_Exception(YAPI.DEVICE_NOT_FOUND, "No function [" + hwid.function + "] found on device [" + hwid.module + "]"); }
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; } }