bool emIsLocalLongInterfaceId(const uint8_t* interfaceId) { uint8_t unmodified[8]; emUnmodifyInterfaceId(interfaceId, unmodified); return (MEMCOMPARE(unmodified, emMeshLocalIdentifier, 8) == 0 || MEMCOMPARE(unmodified, emLinkLocalIdentifier, 8) == 0); }
bool emIsAllNodesMulticastAddress(const uint8_t *address) { return ((MEMCOMPARE(address, emFf02AllNodesMulticastAddress.contents, 16) == 0) || (MEMCOMPARE(address, emFf03AllNodesMulticastAddress.contents, 16) == 0)); }
uint16_t emberAfPluginMeterMirrorRemoveMirror(EmberEUI64 requestingDeviceIeeeAddress) { uint8_t index; uint8_t endpoint; if (0 == MEMCOMPARE(nullEui64, requestingDeviceIeeeAddress, EUI64_SIZE)) { emberAfSimpleMeteringClusterPrintln("Rejecting mirror removal using NULL EUI64"); return INVALID_MIRROR_ENDPOINT; } index = findMirrorIndex(requestingDeviceIeeeAddress); if (index == INVALID_INDEX) { emberAfSimpleMeteringClusterPrint("Unknown mirror for remove: "); emberAfPrintBigEndianEui64(requestingDeviceIeeeAddress); emberAfSimpleMeteringClusterPrintln(" "); return MIRROR_NOT_FOUND_ZCL_RETURN_CODE; } clearMirrorByIndex(index, true); // print? endpoint = index + EMBER_AF_PLUGIN_METER_MIRROR_ENDPOINT_START; emberAfPluginMeterMirrorMirrorRemovedCallback(requestingDeviceIeeeAddress, endpoint); return endpoint; }
static EmberAfDeviceInfo* findDeviceByEui64(const EmberEUI64 eui64) { uint16_t i; for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_DATABASE_MAX_DEVICES; i++) { if (0 == MEMCOMPARE(eui64, deviceDatabase[i].eui64, EUI64_SIZE)) { return &(deviceDatabase[i]); } } return NULL; }
bool emberAfPluginMeterMirrorIsMirrorUsed(uint8_t endpoint) { uint8_t index = getIndexFromEndpoint(endpoint); if (INVALID_INDEX == index) { emberAfSimpleMeteringClusterPrintln("Error: Endpoint %d is not a valid mirror endpoint.", endpoint); return false; } return (0 != MEMCOMPARE(mirrorList[index].eui64, nullEui64, EUI64_SIZE)); }
static uint8_t findMirrorIndex(EmberEUI64 requestingDeviceIeeeAddress) { uint8_t i; for (i = 0; i < EMBER_AF_PLUGIN_METER_MIRROR_MAX_MIRRORS; i++) { if (0 == MEMCOMPARE(requestingDeviceIeeeAddress, mirrorList[i].eui64, EUI64_SIZE)) { return i; } } return INVALID_INDEX; }
uint8_t emAfPluginMeterMirrorGetMirrorsAllocated(void) { uint8_t mirrors = 0; uint8_t i; for (i = 0; i < EMBER_AF_PLUGIN_METER_MIRROR_MAX_MIRRORS; i++) { if (0 != MEMCOMPARE(mirrorList[i].eui64, nullEui64, EUI64_SIZE)) { mirrors++; } } return mirrors; }
static bool isSameNetwork(const EmberZllNetwork *network) { EmberNodeType nodeType; EmberNetworkParameters parameters; EmberStatus status = emberAfGetNetworkParameters(&nodeType, ¶meters); return (status == EMBER_SUCCESS && (MEMCOMPARE(parameters.extendedPanId, network->zigbeeNetwork.extendedPanId, EXTENDED_PAN_ID_SIZE) == 0) && parameters.panId == network->zigbeeNetwork.panId && parameters.nwkUpdateId == network->zigbeeNetwork.nwkUpdateId); }
void halInternalGetMfgTokenData(void *data, int16u token, int8u index, int8u len) { int8u *ram = (int8u*)data; //0x7F is a non-indexed token. Remap to 0 for the address calculation index = (index==0x7F) ? 0 : index; if(token == MFG_EUI_64_LOCATION) { //There are two EUI64's stored in the Info Blocks, St and Custom. //0x0A00 is the address used by the generic EUI64 token, and it is //token.c's responbility to pick the returned EUI64 from either St //or Custom. Return the Custom EUI64 if it is not all FF's, otherwise //return the St EUI64. tokTypeMfgEui64 eui64; halCommonGetMfgToken(&eui64, TOKEN_MFG_CUSTOM_EUI_64); if(MEMCOMPARE(eui64,nullEui, 8 /*EUI64_SIZE*/) == 0) { halCommonGetMfgToken(&eui64, TOKEN_MFG_ST_EUI_64); } MEMCOPY(ram, eui64, 8 /*EUI64_SIZE*/); } else { //read from the Information Blocks. The token ID is only the //bottom 16bits of the token's actual address. Since the info blocks //exist in the range DATA_BIG_INFO_BASE-DATA_BIG_INFO_END, we need //to OR the ID with DATA_BIG_INFO_BASE to get the real address. int32u realAddress = (DATA_BIG_INFO_BASE|token) + (len*index); int8u *flash = (int8u *)realAddress; MEMCOPY(ram, flash, len); } }
// Find an active tunnel to the given device. static uint8_t findTunnelByDeviceId(EmberEUI64 remoteDeviceId) { uint8_t tunnelIndex; // emberAfDebugPrint("CHF: findTunnelByDeviceId "); // emberAfDebugDebugExec(emberAfPrintBigEndianEui64(remoteDeviceId)); // emberAfDebugPrintln(""); for (tunnelIndex = 0; tunnelIndex < EMBER_AF_PLUGIN_COMMS_HUB_FUNCTION_TUNNEL_LIMIT; tunnelIndex++) { // emberAfDebugPrint("CHF: findTunnelByDeviceId compare to 0x%x ", // tunnels[tunnelIndex].state); // emberAfDebugDebugExec(emberAfPrintBigEndianEui64(tunnels[tunnelIndex].remoteDeviceId)); // emberAfDebugPrintln(""); if (tunnels[tunnelIndex].state != UNUSED_TUNNEL && (MEMCOMPARE(tunnels[tunnelIndex].remoteDeviceId, remoteDeviceId, EUI64_SIZE) == 0)) { return tunnelIndex; } } return EM_AF_PLUGIN_COMMS_HUB_FUNCTION_NULL_TUNNEL_INDEX; }
static void MarkDuplicateMatches(const MatchDescriptorReq_t *const in_dev) { // Check if we already have any from requested clusters from a remote EmberBindingTableEntry entry = {0}; // run through the incoming device's clusters list and check if // we already have any binding entries for (size_t i = 0; i < in_dev->source_cl_arr_len; ++i) { for (size_t j = 0; j < emberBindingTableSize; ++j) { if (emberGetBinding(j, &entry) != EMBER_SUCCESS) { break; } // if a binding entry not marked as unused and // current info are the same as in a request if (entry.type != EMBER_UNUSED_BINDING && entry.local == dev_comm_session.ep && entry.clusterId == in_dev->source_cl_arr[i] && entry.remote == in_dev->source_ep && MEMCOMPARE(entry.identifier, in_dev->source_eui64, EUI64_SIZE) == 0) { SkipRemoteCluster(i); break; } } } }
void securityAddToAddressCache(EmberNodeId nodeId, EmberEUI64 nodeEui64) { uint8_t index = nextIndex; uint8_t i; if (addressCacheSize == 0) { return; } if (nodeId >= EMBER_BROADCAST_ADDRESS) { assert(0); } // Search through our cache for an existing IEEE with the same info. // If it exists update that. for (i = 0; i < addressCacheSize; i++) { EmberEUI64 eui64; emberGetAddressTableRemoteEui64(addressCacheStartIndex + i, eui64); if (MEMCOMPARE(eui64, nodeEui64, EUI64_SIZE) == 0) { index = i; break; } } if (index == nextIndex) { nextIndex += 1; if (nextIndex == addressCacheSize) nextIndex = 0; } index += addressCacheStartIndex; if (emberSetAddressTableRemoteEui64(index, nodeEui64) == EMBER_SUCCESS) { emberSetAddressTableRemoteNodeId(index, nodeId); } }
static bool isShortInterfaceId(const uint8_t *interfaceId) { return MEMCOMPARE(emShortInterfaceIdPrefix, interfaceId, 6) == 0; }
static void noteFailedDiscovery(const EmberAfDeviceInfo* device) { emberAfPluginDeviceDatabaseSetStatus(device->eui64, EMBER_AF_DEVICE_DISCOVERY_STATUS_FAILED); EMBER_TEST_ASSERT(0 == MEMCOMPARE(device->eui64, currentEui64, EUI64_SIZE)); clearCurrentDevice(); }
/** @brief Disconnect Request * * * @param managerIEEEAddress Ver.: always */ bool emberAf11073ProtocolTunnelClusterDisconnectRequestCallback(uint8_t* managerIEEEAddress) { bool connected = false; EmberEUI64 currentManager; bool preemptible; EmberAfStatus status; // check to see if already connected status = emberAfReadServerAttribute(HC_11073_TUNNEL_ENDPOINT, CLUSTER_ID_11073_TUNNEL, ATTRIBUTE_11073_TUNNEL_CONNECTED, &connected, 1); // if not currently connected, generate connection status DISCONNECTED if (!connected) { emberAfFillCommand11073ProtocolTunnelClusterConnectStatusNotification( EMBER_ZCL_11073_TUNNEL_CONNECTION_STATUS_DISCONNECTED); emberAfSendResponse(); return true; } // if is connected, is ieee address same or is pre-emptible set to true? status = emberAfReadServerAttribute(HC_11073_TUNNEL_ENDPOINT, CLUSTER_ID_11073_TUNNEL, ATTRIBUTE_11073_TUNNEL_PREEMPTIBLE, &preemptible, 1); if(!preemptible) { status = emberAfReadServerAttribute(HC_11073_TUNNEL_ENDPOINT, CLUSTER_ID_11073_TUNNEL, ATTRIBUTE_11073_TUNNEL_MANAGER_TARGET, (uint8_t*)¤tManager, EUI64_SIZE); if (MEMCOMPARE(¤tManager, managerIEEEAddress, EUI64_SIZE) != 0) { emberAfFillCommand11073ProtocolTunnelClusterConnectStatusNotification( EMBER_ZCL_11073_TUNNEL_CONNECTION_STATUS_NOT_AUTHORIZED); emberAfSendResponse(); return true; } } // Set attribute to disconnected connected = false; status = emberAfWriteServerAttribute(HC_11073_TUNNEL_ENDPOINT, CLUSTER_ID_11073_TUNNEL, ATTRIBUTE_11073_TUNNEL_CONNECTED, &connected, ZCL_BOOLEAN_ATTRIBUTE_TYPE); // If it is authorized, then we can disconnect.Within 12 seconds device must send // DISCONNECTED notification to the manager device. Connected attribute set to // false to manager. emberAfFillCommand11073ProtocolTunnelClusterConnectStatusNotification( EMBER_ZCL_11073_TUNNEL_CONNECTION_STATUS_DISCONNECTED); emberAfSendResponse(); return true; // Send another DISCONNECTED connection event to sender of message. (may be same // as manager, may be some other device). return false; }
bool emberIsMeshLocalIdentifier(const uint8_t *identifier) { return (MEMCOMPARE(identifier, emMeshLocalIdentifier, 8) == 0); }
static void deviceInformationResponseHandler(const EmberEUI64 source, uint32_t transaction, uint8_t numberOfSubDevices, uint8_t startIndex, uint8_t deviceInformationRecordCount, uint8_t *deviceInformationRecordList) { uint16_t deviceInformationRecordListLen = (deviceInformationRecordCount * ZLL_DEVICE_INFORMATION_RECORD_SIZE); uint16_t deviceInformationRecordListIndex = 0; uint8_t i; bool validResponse = (emberEventControlGetActive(emberAfPluginZllCommissioningTouchLinkEventControl) && (network.securityAlgorithm.transactionId == transaction) && MEMCOMPARE(network.eui64, source, EUI64_SIZE) == 0); emberAfZllCommissioningClusterFlush(); emberAfZllCommissioningClusterPrint("RX: DeviceInformationResponse 0x%4x, 0x%x, 0x%x, 0x%x,", transaction, numberOfSubDevices, startIndex, deviceInformationRecordCount); emberAfZllCommissioningClusterFlush(); for (i = 0; i < deviceInformationRecordCount; i++) { uint8_t *ieeeAddress; uint8_t endpointId; uint16_t profileId; uint16_t deviceId; uint8_t version; uint8_t groupIdCount; uint8_t sort; ieeeAddress = &deviceInformationRecordList[deviceInformationRecordListIndex]; deviceInformationRecordListIndex += EUI64_SIZE; endpointId = emberAfGetInt8u(deviceInformationRecordList, deviceInformationRecordListIndex, deviceInformationRecordListLen); deviceInformationRecordListIndex++; profileId = emberAfGetInt16u(deviceInformationRecordList, deviceInformationRecordListIndex, deviceInformationRecordListLen); deviceInformationRecordListIndex += 2; deviceId = emberAfGetInt16u(deviceInformationRecordList, deviceInformationRecordListIndex, deviceInformationRecordListLen); deviceInformationRecordListIndex += 2; version = emberAfGetInt8u(deviceInformationRecordList, deviceInformationRecordListIndex, deviceInformationRecordListLen); deviceInformationRecordListIndex++; groupIdCount = emberAfGetInt8u(deviceInformationRecordList, deviceInformationRecordListIndex, deviceInformationRecordListLen); deviceInformationRecordListIndex++; sort = emberAfGetInt8u(deviceInformationRecordList, deviceInformationRecordListIndex, deviceInformationRecordListLen); deviceInformationRecordListIndex++; emberAfZllCommissioningClusterPrint(" ["); emberAfZllCommissioningClusterDebugExec(emberAfPrintBigEndianEui64(ieeeAddress)); emberAfZllCommissioningClusterPrint(" 0x%x 0x%2x 0x%2x 0x%x 0x%x 0x%x", endpointId, profileId, deviceId, version, groupIdCount, sort); emberAfZllCommissioningClusterFlush(); if (validResponse && (subDeviceCount < EMBER_AF_PLUGIN_ZLL_COMMISSIONING_SUB_DEVICE_TABLE_SIZE)) { MEMMOVE(subDevices[subDeviceCount].ieeeAddress, ieeeAddress, EUI64_SIZE); subDevices[subDeviceCount].endpointId = endpointId; subDevices[subDeviceCount].profileId = profileId; subDevices[subDeviceCount].deviceId = deviceId; subDevices[subDeviceCount].version = version; subDevices[subDeviceCount].groupIdCount = groupIdCount; subDeviceCount++; } else { emberAfZllCommissioningClusterPrint(" (ignored)"); } emberAfZllCommissioningClusterPrint("]"); emberAfZllCommissioningClusterFlush(); } emberAfZllCommissioningClusterPrintln(""); if (validResponse && (subDeviceCount < EMBER_AF_PLUGIN_ZLL_COMMISSIONING_SUB_DEVICE_TABLE_SIZE) && subDeviceCount < numberOfSubDevices) { sendDeviceInformationRequest(startIndex + deviceInformationRecordCount); } }
// // emChooseInterface -- choose an interface for subsequent calls to // emberUdpListen() or emTcpListen(). // // When interfaceChoice is 0xFF or prefixChoice is NULL, // they are ignored. If neither interfaceChoice nor prefixChoice // are given, an interface menu is printed so the user can decide which // interface to choose. // bool emChooseInterface(uint8_t interfaceChoice, const uint8_t *prefixChoice, bool produceOutput) { struct ifaddrs *addresses[10] = {0}; struct in6_addr prefix = {0}; struct in6_addr *ipv6Addresses[10] = {0}; struct ifaddrs *fullIfAddrs = NULL; if (prefixChoice != NULL) { if (inet_pton(AF_INET6, prefixChoice, (void*)&prefix) != 1) { emberSerialPrintfLine(APP_SERIAL, "Invalid IP address: %s " "(can't change it to network format)", prefixChoice); return false; } } int foundCount = emGetIpv6Addresses(addresses, 10, &fullIfAddrs); int i; if (foundCount == 0) { fprintf(stderr, "No global IPv6 interfaces found!\n"); exit(1); } if (interfaceChoice == 0xFF) { emberSerialPrintfLine(APP_SERIAL, "Choose an interface from below:"); } const char *loopbackAddress = "::1"; // // print out the interfaces // for (i = 0; i < foundCount; i++) { uint8_t addressString[INET6_ADDRSTRLEN] = {0}; ipv6Addresses[i] = &((struct sockaddr_in6*)addresses[i]->ifa_addr)->sin6_addr; if (inet_ntop(AF_INET6, ipv6Addresses[i], addressString, sizeof(addressString)) == NULL) { perror("inet_ntop"); exit(1); } bool prefixMatch = false; if (MEMCOMPARE(&prefix, ipv6Addresses[i], 8) == 0 || MEMCOMPARE(&prefix, ipv6Addresses[i], 16) == 0) { interfaceChoice = i; } if ((interfaceChoice == 0xFF || interfaceChoice == i) && produceOutput) { emberSerialPrintfLine(APP_SERIAL, "[%u]: %s on interface %s", i, addressString, addresses[i]->ifa_name); } } if (! produceOutput) { assert(interfaceChoice != 0xFF); } else { while (interfaceChoice >= foundCount) { emberSerialPrintf(APP_SERIAL, "Choice: "); char *line = malloc(1000); size_t lineSize = sizeof(line); ssize_t bytesRead = getline(&line, &lineSize, stdin); interfaceChoice = (bytesRead > 0 ? atoi(line) : 0xFF); free(line); } } // free later? emUnixInterface = strdup(addresses[interfaceChoice]->ifa_name); MEMCOPY(emMyIpAddress.bytes, ipv6Addresses[interfaceChoice], 16); freeifaddrs(fullIfAddrs); return true; }
bool emIsFe8Address(const uint8_t *address) { return (MEMCOMPARE(address, emFe8Prefix.contents, 8) == 0); }