{"id":32474895,"url":"https://github.com/lukaslerche/bookwaves-feig","last_synced_at":"2025-10-26T20:15:04.867Z","repository":{"id":320565627,"uuid":"1071449073","full_name":"lukaslerche/bookwaves-feig","owner":"lukaslerche","description":"A Java-based RFID reader service using the Feig SDK, providing REST API endpoints for tag operations and multi-reader management.","archived":false,"fork":false,"pushed_at":"2025-10-24T13:06:23.000Z","size":47,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-24T15:07:17.059Z","etag":null,"topics":["bookwaves","feig","library-automation","rfid","uhf","uhf-rfid"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lukaslerche.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-07T11:13:20.000Z","updated_at":"2025-10-24T13:06:26.000Z","dependencies_parsed_at":"2025-10-24T15:20:58.375Z","dependency_job_id":null,"html_url":"https://github.com/lukaslerche/bookwaves-feig","commit_stats":null,"previous_names":["lukaslerche/bookwaves-feig"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/lukaslerche/bookwaves-feig","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukaslerche%2Fbookwaves-feig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukaslerche%2Fbookwaves-feig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukaslerche%2Fbookwaves-feig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukaslerche%2Fbookwaves-feig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lukaslerche","download_url":"https://codeload.github.com/lukaslerche/bookwaves-feig/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukaslerche%2Fbookwaves-feig/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281163807,"owners_count":26454256,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-26T02:00:06.575Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bookwaves","feig","library-automation","rfid","uhf","uhf-rfid"],"created_at":"2025-10-26T20:15:02.049Z","updated_at":"2025-10-26T20:15:04.861Z","avatar_url":"https://github.com/lukaslerche.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Feig RFID Reader Service\n\nA Java-based RFID reader service using the Feig SDK, providing REST API endpoints for tag operations and multi-reader management.\n\n## Features\n\n- **Multi-reader support** - Manage multiple RFID readers simultaneously\n- **Auto-detection** - Supports DE290, DE290F, DE386, DE6, and BR tag formats\n- **Configurable passwords** - Per-tag-type password management\n- **Host \u0026 Notification modes** - Support for both polling and event-driven tag detection\n- **Tag initialization** - Write new tags with proper format and security\n- **Tag editing** - Update media IDs on existing tags\n- **Security operations** - Lock/unlock, secure/unsecure tags\n- **Tag analysis** - Deep inspection of tag memory and security status\n\n## Quick Start (Docker)\n\nThe easiest way to run the service is using the pre-built Docker image:\n\n### 1. Create Configuration File\n\n**IMPORTANT:** This application requires an external configuration file. No default configuration is embedded.\n\n```bash\n# Copy the example configuration\ncp config.yaml.example config.yaml\n\n# Edit config.yaml with your reader details and passwords\n```\n\n**Never commit `config.yaml` to version control** (it contains sensitive passwords)\n\n### 2. Run with Docker\n\n```bash\ndocker run -d \\\n  -p 7070:7070 \\\n  -v $(pwd)/config.yaml:/app/config/config.yaml:ro \\\n  ghcr.io/lukaslerche/bookwaves-feig:latest\n```\n\nOr use Docker Compose with the provided `docker-compose.yml`:\n\n```bash\ndocker compose up -d\n```\n\nThe service will be available at `http://localhost:7070`\n\n## Configuration\n\n### Configuration File Format\n\nSee `config.yaml.example` for the complete configuration template.\n\n**Tag passwords by type:**\n- `DE290Tag.access` / `DE290Tag.kill` - For DE290 tags\n- `DE6Tag.access` / `DE6Tag.kill` - For DE6 tags\n- `DE386Tag.access` / `DE386Tag.kill` - For DE386 tags\n- `BRTag.secret` - For BR (Smartfreq) tags\n\n**Default tag format** - Used for tag initialization (DE290, DE6, DE290F, or DE386)\n\n**Reader configurations:**\n- Name, IP address, port\n- Operating mode: `host` or `notification`\n- Antenna numbers (as array)\n\n### Example Configuration\n\n```yaml\n# Global tag password configuration\ntagPasswords:\n  DE290Tag.access: \"12345678\"\n  DE290Tag.kill: \"87654321\"\n  DE6Tag.access: \"AABBCCDD\"\n  DE6Tag.kill: \"EEFF0011\"\n  DE386Tag.access: \"11223344\"\n  DE386Tag.kill: \"55667788\"\n  BRTag.secret: \"secret-key\"\n\n# Default tag format for initialization\ndefaultTagFormat: DE290\n\nreaders:\n  - name: \"reader1\"\n    address: \"192.168.1.225\"\n    port: 10001\n    mode: host\n    antennas: [4]\n  - name: \"reader2\"\n    address: \"192.168.1.70\"\n    port: 10001\n    mode: notification\n    antennas: [1,2]\n```\n\n**Mode values:**\n- `host` - Polling mode for manual inventory scans\n- `notification` - Event-driven automatic tag detection\n\n**Important notes:**\n- Only configure passwords for tag formats you actually use\n- Replace placeholder passwords with your actual tag passwords\n\n## API Endpoints\n\nBase URL: `http://localhost:7070`\n\n### Health Check\n\n#### Get Service Status\n```http\nGET /\n```\nReturns \"Hello Feig!\" to verify service is running.\n\n#### Test Endpoint\n```http\nGET /test\n```\nReturns \"Test successful\" for connectivity testing.\n\n### Reader Management\n\n#### List Readers\n```http\nGET /readers\n```\n\nReturns all configured readers with their status and configuration.\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"readerCount\": 2,\n  \"readers\": [\n    {\n      \"name\": \"reader1\",\n      \"address\": \"192.168.1.225\",\n      \"port\": 10001,\n      \"mode\": \"host\",\n      \"antennas\": [1, 2, 3, 4],\n      \"antennaMask\": \"0x0F\",\n      \"isConnected\": true,\n      \"connectionStatus\": \"connected\",\n      \"notificationActive\": false\n    }\n  ]\n}\n```\n\n### Tag Operations\n\n#### Inventory Scan\n```http\nGET /inventory/{readerName}\n```\n\nPerforms a single inventory scan and returns all detected tags with their format-specific information.\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"message\": \"Inventory successful\",\n  \"count\": 2,\n  \"tags\": [\n    {\n      \"tagType\": \"DE290Tag\",\n      \"epc\": \"3034257BF468D4800000162E\",\n      \"pc\": \"3400\",\n      \"mediaId\": \"5678\",\n      \"secured\": true,\n      \"rssiValues\": [\n        {\n          \"antenna\": 1,\n          \"rssi\": -42\n        }\n      ]\n    }\n  ]\n}\n```\n\n#### Initialize Tag\n```http\nPOST /initialize/{readerName}?mediaId={mediaId}\u0026format={format}\u0026secured={secured}\n```\n\nInitialize a blank tag with specified format and media ID. Writes EPC, passwords, and locks memory.\n\n**Query Parameters:**\n- `mediaId` (required) - Media identifier (format depends on tag type)\n- `format` (optional) - Tag format: DE290, DE6, DE290F, or DE386 (defaults to configured defaultTagFormat)\n- `secured` (optional) - Security bit value: true or false (default: true)\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"message\": \"Tag initialized successfully\",\n  \"epc\": \"3034257BF468D4800000162E\",\n  \"pc\": \"3400\",\n  \"mediaId\": \"5678\",\n  \"secured\": true,\n  \"format\": \"DE290\",\n  \"tagType\": \"DE290Tag\"\n}\n```\n\n**Errors:**\n- `400` - Invalid mediaId format or unsupported tag format\n- `404` - Reader not found\n- `500` - Initialization failed (no tag in field, multiple tags, write error)\n\n#### Edit Tag\n```http\nPOST /edit/{readerName}?epc={epc}\u0026mediaId={newMediaId}\n```\n\nUpdate the media ID on an existing formatted tag. Automatically handles password changes and memory updates.\n\n**Query Parameters:**\n- `epc` (required) - Current EPC hex string of the tag\n- `mediaId` (required) - New media identifier\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"message\": \"Tag updated successfully\",\n  \"oldEpc\": \"3034257BF468D4800000162E\",\n  \"newEpc\": \"3034257BF468D480000019C8\",\n  \"mediaId\": \"6600\",\n  \"tagType\": \"DE290Tag\"\n}\n```\n\n**Errors:**\n- `400` - Invalid EPC, unrecognized format, or invalid mediaId\n- `404` - Reader not found\n- `500` - Update failed (tag not found, write error)\n\n#### Clear Tag\n```http\nPOST /clear/{readerName}?epc={epc}\n```\n\nReset a tag to factory state: zeros passwords, restores TID as EPC, and unlocks memory.\n\n**Query Parameters:**\n- `epc` (required) - EPC hex string of tag to clear\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"message\": \"Tag cleared successfully - passwords zeroed and EPC restored to TID\",\n  \"oldEpc\": \"3034257BF468D4800000162E\",\n  \"newEpc\": \"E280689400005003F76A18ED\",\n  \"newPc\": \"3000\",\n  \"tid\": \"E280689400005003F76A18ED\"\n}\n```\n\n#### Secure Tag\n```http\nPOST /secure/{readerName}?epc={epc}\n```\n\nSet the security bit on a tag (marks tag as secured/locked in circulation).\n\n**Query Parameters:**\n- `epc` (required) - EPC hex string of tag to secure\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"message\": \"Tag secured successfully\",\n  \"epc\": \"3034257BF468D4800000162E\",\n  \"tagType\": \"DE290Tag\",\n  \"secured\": true\n}\n```\n\n#### Unsecure Tag\n```http\nPOST /unsecure/{readerName}?epc={epc}\n```\n\nClear the security bit on a tag (marks tag as available for circulation).\n\n**Query Parameters:**\n- `epc` (required) - EPC hex string of tag to unsecure\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"message\": \"Tag unsecured successfully\",\n  \"epc\": \"3034257BF468D4800000162E\",\n  \"tagType\": \"DE290Tag\",\n  \"secured\": false\n}\n```\n\n#### Analyze Tag\n```http\nGET /analyze/{readerName}?epc={epc}\n```\n\nPerform deep analysis of a tag's memory banks, passwords, and security configuration. Useful for debugging and verification.\n\n**Query Parameters:**\n- `epc` (required) - EPC hex string of tag to analyze\n\n**Response:**\n```json\n{\n  \"success\": true,\n  \"epc\": \"3034257BF468D4800000162E\",\n  \"analysis\": {\n    \"tagType\": \"DE290Tag\",\n    \"mediaId\": \"5678\",\n    \"epcBank\": {\n      \"readSuccess\": true,\n      \"pcValue\": \"0x3400\",\n      \"epcLengthInWords\": 8,\n      \"epcLengthInBytes\": 16,\n      \"actual\": \"34003034257BF468D4800000162E\",\n      \"theoretical\": \"34003034257BF468D4800000162E\",\n      \"matches\": true\n    },\n    \"tidBank\": {\n      \"readSuccess\": true,\n      \"data\": \"E280689400005003F76A18ED\",\n      \"length\": 12\n    },\n    \"reservedBank\": {\n      \"readableWithoutAuth\": false,\n      \"readableWithAuth\": true,\n      \"theoretical\": \"162E5678162E5678\",\n      \"actual\": \"162E5678162E5678\",\n      \"matches\": true,\n      \"passwordsAreZero\": false\n    },\n    \"lockStatus\": {\n      \"reservedBank\": \"LOCKED\",\n      \"reservedBankStatus\": \"Read-protected with access password\"\n    },\n    \"securityAssessment\": {\n      \"properlySecured\": true,\n      \"passwordCorrect\": true,\n      \"issues\": [],\n      \"passwordProtectionConfigured\": true,\n      \"passwordProtectionRequired\": true\n    }\n  }\n}\n```\n\n**Analysis Fields:**\n- `epcBank` - PC and EPC memory verification\n- `tidBank` - Tag Identifier data\n- `reservedBank` - Password memory and authentication status\n- `lockStatus` - Lock configuration for each memory bank\n- `securityAssessment` - Overall security evaluation and detected issues\n\n## Supported Tag Types\n\n- **DE290Tag** - TU Dortmund university library standard\n- **DE290FTag** - TU Dortmund university library Fernleihe variant\n- **BRTag** - TU Dortmund university library legacy tags by Smartfreq\n- **DE386Tag** - RPTU Kaiserslautern university library standard\n- **DE6Tag** - ULB Münster library standard\n- **RawTag** - Fallback for unrecognized formats\n\nAll tag types support automatic password lookup from configuration.\n\n## Architecture\n\n- **ReaderManager** - Central registry for all readers\n- **ManagedReader** - Wraps ReaderModule with mode-specific operations\n- **TagFactory** - Auto-detects and creates appropriate Tag instances\n- **ConfigLoader** - YAML configuration parser\n\n## Security Notes\n\n- Configuration file contains sensitive passwords\n- Use volume mounts with `:ro` (read-only) flag in production\n- Passwords are validated on startup - warnings logged for placeholder values\n- Never commit `config.yaml` to version control\n\n## Requirements\n\n- Java 21 or newer (64-bit platforms only)\n- Feig RFID readers (TCP/IP network interface)\n- OpenSSL 3.2+ on Linux for TLS features\n- Native libraries in `LD_LIBRARY_PATH`\n\n## Troubleshooting\n\n### Native Library Issues\nEnsure `LD_LIBRARY_PATH` points to correct native libraries:\n- Linux: `native/linux.x64`\n- Check logs for \"java.library.path\" on startup\n\n### Connection Failures\n- Verify reader IP address and port in config\n- Check network connectivity to readers\n- Ensure readers are powered on and network-accessible\n\n### Tag Not Detected\n- Verify antenna numbers match physical configuration\n- Check RF field is enabled\n- Ensure tag is within read range\n- Ensure passwords in config.yaml match tag programming\n\n---\n\n## Development\n\nThe following sections are for developers who want to build, modify, or contribute to the project.\n\n### Running Locally\n\n**Prerequisites:**\n- Java 21 or newer\n- Maven\n- Feig SDK files (see Devcontainer Prerequisites below)\n\nSet the environment variables and run the application:\n\n```bash\nexport CONFIG_FILE_PATH=$(pwd)/config.yaml\nexport LD_LIBRARY_PATH=$(pwd)/native/linux.x64\njava -cp \"target/classes:target/dependency/*:libs/*\" de.bookwaves.Main\n```\n\nOr use the provided VS Code launch configuration (already configured).\n\n### Developing with Devcontainer\n\n#### Prerequisites\n\nBefore using the devcontainer, you must obtain the Feig SDK files:\n\n1. **Download the Feig SDK** from the official Feig Electronic website:\n   - Navigate to the SDK download section for Java\n   - Download the latest Java SDK package (64-bit Linux version required)\n\n2. **Extract required files** to the project directories:\n   \n   **JAR files** (`libs/` directory):\n   ```\n   libs/fedm-funit-java-api-1.1.0.jar\n   libs/fedm-java-api-6.10.jar\n   libs/fedm-service-java-api-11.0.2.jar\n   ```\n   \n   **Native libraries** (`native/linux.x64/` directory):\n   ```\n   native/linux.x64/install.sh\n   native/linux.x64/libfecom.so.5.1.0\n   native/linux.x64/libfedm-funti.so.1.1.0\n   native/linux.x64/libfedm-funti4.so\n   native/linux.x64/libfedm-funti4j.so.1.1.0\n   native/linux.x64/libfedm-service.so.11.0.2\n   native/linux.x64/libfedm-service4j.so.11.0.2\n   native/linux.x64/libfedm.so.6.11.0\n   native/linux.x64/libfedm4j.so.6.11.0\n   native/linux.x64/libfeisp.so.1.5.1\n   native/linux.x64/libfetls.so.0.9.0\n   native/linux.x64/libfeudp.so.1.0.0\n   native/linux.x64/libfeusb2.so.1.1.0\n   ```\n\n3. **Create symbolic links** by running the provided install script:\n   ```bash\n   cd native/linux.x64\n   chmod +x install.sh\n   ./install.sh\n   ```\n   \n   This will create the required `.so` and `.so.X` symbolic links pointing to the versioned files.\n\n4. **Verify directory structure** after running install.sh:\n   ```\n   .\n   ├── libs/\n   │   ├── fedm-funit-java-api-1.1.0.jar\n   │   ├── fedm-java-api-6.10.jar\n   │   └── fedm-service-java-api-11.0.2.jar\n   ├── native/\n   │   └── linux.x64/\n   │       ├── install.sh\n   │       ├── libfecom.so -\u003e libfecom.so.5\n   │       ├── libfecom.so.5 -\u003e libfecom.so.5.1.0\n   │       ├── libfecom.so.5.1.0\n   │       ├── libfedm.so -\u003e libfedm.so.6\n   │       ├── libfedm.so.6 -\u003e libfedm.so.6.11.0\n   │       ├── libfedm.so.6.11.0\n   │       └── (etc. - all libraries with symlinks)\n   └── ...\n   ```\n\n**Note:** These files are proprietary and cannot be included in the repository. You must obtain them directly from Feig Electronic.\n\n#### Starting the Devcontainer\n\n1. **Open in VS Code** with the Dev Containers extension installed\n\n2. **Reopen in Container** - VS Code will prompt to reopen in the devcontainer, or use:\n   - Command Palette (`Cmd+Shift+P` / `Ctrl+Shift+P`)\n   - Select: \"Dev Containers: Reopen in Container\"\n\n3. **Build the project** (done automatically, or manually):\n   ```bash\n   mvn clean compile dependency:copy-dependencies\n   ```\n\n4. **Create your configuration**:\n   ```bash\n   cp config.yaml.example config.yaml\n   # Edit config.yaml with your reader settings\n   ```\n\n5. **Run the application** using VS Code launch configuration or:\n   ```bash\n   export CONFIG_FILE_PATH=$(pwd)/config.yaml\n   export LD_LIBRARY_PATH=$(pwd)/native/linux.x64\n   java -cp \"target/classes:target/dependency/*:libs/*\" de.bookwaves.Main\n   ```\n\n### Building the Docker Image\n\n#### Prerequisites\n\nThe same SDK files are required for Docker builds:\n\n1. **Ensure SDK files are in place** as described in the Devcontainer Prerequisites section above\n   - `libs/` - JAR files\n   - `native/linux.x64/` - Native library files with symlinks\n\n2. **Install Docker** with buildx support (included in Docker Desktop)\n\n3. **Authenticate with GitHub Container Registry** (for pushing images):\n   ```bash\n   echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin\n   ```\n   \n   Or create a Personal Access Token (PAT) with `write:packages` scope.\n\n#### Build for Local Testing\n\n```bash\ndocker buildx build --platform linux/amd64 --tag ghcr.io/lukaslerche/bookwaves-feig:latest --load .\n```\n\n**Note:** The `--platform linux/amd64` flag is required because the native libraries are platform-specific. The `--load` flag imports the image into your local Docker daemon for testing.\n\n#### Push to GitHub Container Registry\n\n1. **Build and push** with version tags:\n   ```bash\n   docker buildx build --platform linux/amd64 \\\n     --tag ghcr.io/lukaslerche/bookwaves-feig:latest \\\n     --tag ghcr.io/lukaslerche/bookwaves-feig:1.0.0 \\\n     --push .\n   ```\n\n2. **Verify the push** by checking the GitHub Container Registry:\n   - Navigate to your GitHub profile → Packages\n   - Find `bookwaves-feig` package\n\n3. **Make the package public** (optional):\n   - Go to package settings\n   - Change visibility to public\n\n**Note:** Currently only `linux/amd64` is supported because the native libraries are x64-specific. Additional platforms would require corresponding native libraries from Feig.\n\n### Environment Variables\n\n- `CONFIG_FILE_PATH` - Path to configuration file (optional in Docker, defaults to `/app/config/config.yaml`)\n- `LD_LIBRARY_PATH` - Path to native libraries (set automatically in Dockerfile)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukaslerche%2Fbookwaves-feig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flukaslerche%2Fbookwaves-feig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukaslerche%2Fbookwaves-feig/lists"}