GithubHelp home page GithubHelp logo

bastibl / gnuradio-android Goto Github PK

View Code? Open in Web Editor NEW
185.0 20.0 38.0 355 KB

GNU Radio Android Toolchain

License: GNU General Public License v3.0

Shell 4.03% Dockerfile 0.52% C 40.39% C++ 55.05%
sdr gnuradio android

gnuradio-android's Introduction

GNU Radio Android Toolchain

GNU Radio Android

This is a development environment for GNU Radio on Android. It provides a real-time stream-data processing framework for Android, targeted towards (but not limited to) software defined radio systems. More detailed information is available in the accompanying paper.

Features

  • Supports the most recent GNU Radio version (v3.8).
  • Supports 32-bit and 64-bit ARM architectures (i.e., armeabi-v7a and arm64-v8a).
  • Supports popular hardware frontends (RTL-SDR, HackRF, Ettus B2XX).
  • Supports interfacing Android hardware (mic, speaker, accelerometer, ...) through gr-grand.
  • No need to root the device.
  • All signal processing happens in C++ domain.
  • Various means to interact with a flowgraph from Java-domain (e.g., Control Port, PMTs, ZeroMQ, TCP/UDP).
  • A custom GNU Radio double-mapped circular buffer implementation, using Android shared memory.
  • SIMD acceleration through VOLK, including a custom profiling app for android.
  • OpenCL support through gr-clenabled.
  • Android app to benchmark GNU Radio runtime, VOLK, and OpenCL.
  • Example applications for WLAN and FM.

WLAN Receiver

Requirements

  • Android phone or tablet that supports Android API level 29, introduced with Android 10 Q.
  • ~18Gb disk space for the Docker container.
  • USB-OTG adapter to connect an SDR. (Some USB-C multi-adapters work as well.)

Building the Toolchain

The easiest way to get started is to setup a development environment in Docker. The Dockerfile also serves as documentation on how to set up a native environment.

  • Install Docker. Some installations seem to restrict the maximum container size. This container requires ~18Gb.

  • Checkout the repository (mainly to get the Dockerfile)

git clone --depth=1 https://github.com/bastibl/gnuradio-android.git
cd gnuradio-android/docker
  • Build the container. Please note that the scripts accepts several Android licenses during the build process.
docker build -t gnuradio-android .
  • Run the Docker container. The privileged flag and the /dev/bus/usb mount seem to be required to access the phone from the container. The DISPLAY variable and the Xauthority mount allow to start GUI applications in the container.
docker run -it --privileged -v /dev/bus/usb:/dev/bus/usb --net=host --env="DISPLAY" --volume="$HOME/.Xauthority:/home/android/.Xauthority:rw" gnuradio-android
  • Start Android Studio.
~/src/android-studio/bin/studio.sh
  • Put your phone in developer mode (see instructions).

  • Now the phone should show up in Android Studio. If it does not work, check if the host auto-started adb and, in case, kill it, since the phone can only be connected to one adb server at a time.

  • The container comes with several example projects, e.g., an FM receiver in ~/src/android-fm. Open the project in Android Studio to test the toolchain.

  • The application is a proof-of-concept and doesn't come with a comprehensive lists of USB vendor and product IDs for SDRs. So, you'll likely have to make some manual adjustments.

  • Build the app and install it to your phone. When you connect the phone to Android Studio for the first time, the phone will ask for permissions.

  • Close the app, disconnect the phone from the PC, enable OTG mode on your phone, connect your SDR to the phone, and start the application.

If everything is working, it should like in this demo video:

FM Receiver

Using the Toolchain

While the Android applications should work out-of-the-box in the Docker container, native installations require to adapt some paths to link correctly against the toolchain.

Setting the Architecture

The 32-bit armeabi-v7a toolchain is built with the build.sh script. The 64-bit arm64-v8a toolchain is built with build_aarch64.sh script. These scripts have to know the location of the Android Native Development Kit (NDK), so you might have to adapt the TOOL_CHAIN_ROOT variable.

Libraries, headers, and other build artifacts are installed in the toolchain directory. It will create subdirectories for the different architectures, resulting, for example, in toolchain/armeabi-v7a/lib/libgnuradio-runtime.so.

Android Studio requires a different directory layout to link to external libraries (e.g. armeabi-v7a/libgnuradio-runtime.so). This structure is created through symlinks in the toolchain/jni directory.

Apps can be built for multiple architectures. For development purposes, you might want to limit to a particular one. This can be configured in app/build.gradle, which includes a section like:

ndk {
    abiFilters "armeabi-v7a", "arm64-v8a"
}

Linking to the Toolchain

The path to the toolchain needs to be adapted in two places. The TOOLCHAIN variable in the CMakeLists.txt file that builds the native library, which is usually at app/src/main/cpp. In the jniLibs.srcDirs variable in apps/build.gradle. It should point to the jni directory, described in the previous section.

SIMD Acceleration through Volk

The Docker container includes an Android application to profile the kernels of the Volk library. The project is at ~/src/android-volk in the container and also available on GitHub. Running the application generates a config file with the fastest implementation for the architecture and stores it on Android's External Storage (this can be a SD card or an internal partition). Running this benchmark can speed-up your GNU Radio flowgraphs.

GPU Acceleration

Android lacks native support for OpenCL. Yet, many smartphone processors have capable GPUs and come with the corresponding drivers. For example, the 2017 OnePlus 5T features a Snapdragon 835 processor with an Adreno 540 GPU that supports OpenCL 2.0.

To create Android applications that use OpenCL, the libraries have to be copied from the phone into the toolchain/<arch>/lib directory. libopenCL.so (and its dependencies) are in the /system/lib(64) and /vendor/lib(64) directories. In case of runtime errors due to missing libraries (i.e., dependencies of libopenCL.so), the missing libraries have to be added to the toolchain directory as well.

SDR Drivers

USB-based SDRs like the RTL-SDR, the HackRF, and the Ettus B2XX series are interesting options for smartphones and tablets. Their drivers are based on libusb. On Linux, these drivers traverse the usbfs device tree to find and initialize supported devices. Android does not support this kind of direct access to usbfs. Instead, the app has to interact with Android's UsbManager, which provides a file descriptor to talk to the device. All hardware drivers were, therefore, adapted to support initialization with a file descriptor.

Ettus B2XX SDRs

The B2XX series of devices uses a rather complicated initialization procedure: the device attaches to the host, the host uploads firmware, the device reattaches (as a different device), the host uploads the FPGA image. On Android, this is supported through a dedicated app. It registers a service that is called whenever a B2XX is attached and uploads the firmware. The actual GNU Radio application uses the reattached device directly and only uploads the FPGA image.

Related Applications

Credits

This toolchain is based on an earlier Android port by Tom Rondeau.

Publication

If you use this toolchain, we would appreciate a reference to:

  • Bastian Bloessl, Lars Baumgärtner and Matthias Hollick, “Hardware-Accelerated Real-Time Stream Data Processing on Android with GNU Radio,” Proceedings of 14th International Workshop on Wireless Network Testbeds, Experimental evaluation & Characterization (WiNTECH’20), London, UK, September 2020. [DOI, BibTeX, PDF and Details…]

gnuradio-android's People

Contributors

bastibl avatar marcospanghero avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gnuradio-android's Issues

Missing .so file on armeabi-v7a

Error when building apk for armeabi-v7a cpu architecture, missing libuhd.so and libgnuradio-uhd.so. On the other hand, building using arm64-v8a no error occurred.
error

fail in build docker img

after running docker build -t gnuradio-android .
it fails in the 5th step "apt-get update"
Screen Shot 2020-12-29 at 9 15 00 PM
wondering do you have similar issue

open-ssl

The open-ssl submodule cannot be cloned into in the repository.
Would you please update it ? Thanks a lot.

Building toolchain does not work - build-tools;30.0.0-rc2 not found

git clone --depth=1 https://github.com/bastibl/gnuradio-android.git
cd gnuradio-android/docker
docker build -t gnuradio-android .

Results in:

 ---> Using cache
 ---> 41e813121662
Step 36/47 : RUN yes | ./sdkmanager --sdk_root=${ANDROID_HOME} "build-tools;30.0.0-rc2"
 ---> Running in d5f40b0bacde
Warning: Failed to find package build-tools;30.0.0-rc2                          
The command '/bin/sh -c yes | ./sdkmanager --sdk_root=${ANDROID_HOME} "build-tools;30.0.0-rc2"' returned a non-zero code: 1

successfull build but runtime Error: missing .so

hi thanks for your grate work.

i am working on radio-FM project. i build it exactly based on the tutorial .. i installed it too. but i got this error:
image

when i comment this line:

image

its working and enters to app .. but obviously its not working ...
so why it cannot find *.so files to load library?

Current buildable version of this?

Building the docker doesn't work, and just getting the git clone doesn't work because of old commits as requirements.

Is anyone aware of a gnuradio on Andriod that is maintained and working?

Prebuild Dependency in build.gradle

Hi,

in the new Version from Android Studio there is a change in jniLibs.

https://developer.android.com/studio/releases/gradle-plugin#cmake-imported-targets

After performing the Upgrade the App will not compile anymore:

More than one file was found with OS independent path 'lib/arm64-v8a/libuhd.so'. If you are using jniLibs and CMake IMPORTED targets, see https://developer.android.com/studio/previev/features#automatic_packaging_of_prebuilt_dependencies_used_by_cmake

FM App Crashes - /sdcard/gnuradio is default Folder

Hi,

found that the App does not work for me - when i took a look at the Console it shows following:

2020-07-26 20:40:57.427 22515-22515/net.bastibl.fm E/net.bastibl.fm: Unknown bits set in runtime_flags: 0x8000 2020-07-26 20:40:57.523 22515-23522/net.bastibl.fm E/BehaviorCollectManager: Fail to acquire dataAnalyzerService... 2020-07-26 20:40:57.675 1876-2539/? E/DollieAdapterService: notifyActivityState pkg:net.bastibl.fm/net.bastibl.fmrx.MainActivity state:2 fg:true mUid:10191 2020-07-26 20:40:57.677 1876-2539/? E/ScgQuickAddManager: the compName is :net.bastibl.fm 2020-07-26 20:40:57.857 1417-1497/? E/WindowManager: win=Window{640a902 u0 Splash Screen net.bastibl.fm EXITING} destroySurfaces: appStopped=false win.mWindowRemovalAllowed=true win.mRemoveOnExit=true 2020-07-26 20:40:59.067 1876-2539/? E/DollieAdapterService: notifyActivityState pkg:net.bastibl.fm/net.bastibl.fmrx.MainActivity state:2 fg:true mUid:10191 2020-07-26 20:40:59.091 22515-22515/net.bastibl.fm E/libc++abi: terminating with uncaught exception of type std::runtime_error: Failed to create FFTW wisdom lockfile: /sdcard/gnuradio/gr_fftw_wisdom.lock 2020-07-26 20:40:59.092 22515-22515/net.bastibl.fm A/libc: Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 22515 (net.bastibl.fm), pid 22515 (net.bastibl.fm) 2020-07-26 20:40:59.139 23580-23580/? A/DEBUG: pid: 22515, tid: 22515, name: net.bastibl.fm >>> net.bastibl.fm <<< 2020-07-26 20:40:59.270 23580-23580/? A/DEBUG: #01 pc 00000000000bd600 /data/app/net.bastibl.fm-j6XnamKyj6XamqD0tR657Q==/base.apk!libnative-lib.so (offset 0x1bd000) (BuildId: d1b60079ba186423167998b133dbac4c361cf9a4) 2020-07-26 20:40:59.270 23580-23580/? A/DEBUG: #02 pc 00000000000bd758 /data/app/net.bastibl.fm-j6XnamKyj6XamqD0tR657Q==/base.apk!libnative-lib.so (offset 0x1bd000) (BuildId: d1b60079ba186423167998b133dbac4c361cf9a4) 2020-07-26 20:40:59.270 23580-23580/? A/DEBUG: #03 pc 00000000000ba794 /data/app/net.bastibl.fm-j6XnamKyj6XamqD0tR657Q==/base.apk!libnative-lib.so (offset 0x1bd000) (BuildId: d1b60079ba186423167998b133dbac4c361cf9a4) 2020-07-26 20:40:59.270 23580-23580/? A/DEBUG: #04 pc 00000000000b9e98 /data/app/net.bastibl.fm-j6XnamKyj6XamqD0tR657Q==/base.apk!libnative-lib.so (offset 0x1bd000) (BuildId: d1b60079ba186423167998b133dbac4c361cf9a4) 2020-07-26 20:40:59.270 23580-23580/? A/DEBUG: #05 pc 00000000000b9e18 /data/app/net.bastibl.fm-j6XnamKyj6XamqD0tR657Q==/base.apk!libnative-lib.so (offset 0x1bd000) (__cxa_throw+120) (BuildId: d1b60079ba186423167998b133dbac4c361cf9a4) 2020-07-26 20:40:59.270 23580-23580/? A/DEBUG: #06 pc 000000000002c4e8 /data/app/net.bastibl.fm-j6XnamKyj6XamqD0tR657Q==/base.apk!libgnuradio-fft.so (offset 0xe65000) (BuildId: 9cc636ccda6d13ba7f764905f79cd6e2796a32af) 2020-07-26 20:40:59.270 23580-23580/? A/DEBUG: #07 pc 000000000002c0f8 /data/app/net.bastibl.fm-j6XnamKyj6XamqD0tR657Q==/base.apk!libgnuradio-fft.so (offset 0xe65000) (gr::fft::fft_complex::fft_complex(int, bool, int)+208) (BuildId: 9cc636ccda6d13ba7f764905f79cd6e2796a32af) 2020-07-26 20:40:59.270 23580-23580/? A/DEBUG: #08 pc 0000000000038c14 /data/app/net.bastibl.fm-j6XnamKyj6XamqD0tR657Q==/base.apk!libgnuradio-fft.so (offset 0xe65000) (BuildId: 9cc636ccda6d13ba7f764905f79cd6e2796a32af) 2020-07-26 20:40:59.270 23580-23580/? A/DEBUG: #09 pc 00000000000387f4 /data/app/net.bastibl.fm-j6XnamKyj6XamqD0tR657Q==/base.apk!libgnuradio-fft.so (offset 0xe65000) (gr::fft::ctrlport_probe_psd::make(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char>> const&, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char>> const&, int)+76) (BuildId: 9cc636ccda6d13ba7f764905f79cd6e2796a32af) 2020-07-26 20:40:59.270 23580-23580/? A/DEBUG: #10 pc 000000000004fcfc /data/app/net.bastibl.fm-j6XnamKyj6XamqD0tR657Q==/base.apk!libnative-lib.so (offset 0x1bd000) (Java_net_bastibl_fmrx_MainActivity_fgInit+1696) (BuildId: d1b60079ba186423167998b133dbac4c361cf9a4) 2020-07-26 20:40:59.270 23580-23580/? A/DEBUG: #18 pc 0000000000015478 [anon:dalvik-classes2.dex extracted in memory from /data/app/net.bastibl.fm-j6XnamKyj6XamqD0tR657Q==/base.apk!classes2.dex] (net.bastibl.fmrx.MainActivity.setupUSB+336) 2020-07-26 20:40:59.270 23580-23580/? A/DEBUG: #21 pc 000000000001494a [anon:dalvik-classes2.dex extracted in memory from /data/app/net.bastibl.fm-j6XnamKyj6XamqD0tR657Q==/base.apk!classes2.dex] (net.bastibl.fmrx.MainActivity$usbReceiver$1.onReceive+94) 2020-07-26 20:40:59.423 1417-1627/? E/InputDispatcher: channel '2fd3dc3 net.bastibl.fm/net.bastibl.fmrx.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed! 2020-07-26 20:40:59.429 1417-8088/? E/InputDispatcher: Window handle Window{2fd3dc3 u0 net.bastibl.fm/net.bastibl.fmrx.MainActivity} has no registered input channel 2020-07-26 20:40:59.431 1417-6002/? E/WindowManager: win=Window{2fd3dc3 u0 net.bastibl.fm/net.bastibl.fmrx.MainActivity EXITING} destroySurfaces: appStopped=false win.mWindowRemovalAllowed=true win.mRemoveOnExit=true 2020-07-26 20:40:59.446 1876-2539/? E/DollieAdapterService: notifyActivityState pkg:net.bastibl.fm/net.bastibl.fmrx.MainActivity state:20 fg:false mUid:10191

lookes like the Folder specified in this file is the problem - but I can't get it to work

gnuradio-runtime/lib/CMakeFiles/gnuradio-runtime.dir/sys_paths.cc.o

Latest master dockerfile does not build

Hi,
The lastest and greatest master docker file seems to be not building. The andoid NDK version specified in the Dockerfile is 20.0.5594570 while the TOOLCHAIN_ROOT in build.sh and build_aarch64.sh point to 21.3.6528147

Am I doing something wrong?

changing the version of ndk in Dockerfile to 21.3.6528147 allows building continue after the exports in build.sh but still does not build correctly

App Crashes

i did every step in docs and installed first demo on my mobile .

then i get in the codes to change the vendorId and Pid based on this infos:

#################### NEW RUN ###################
2022-04-14 12:24:40.170 12727-12727/net.bastibl.fm D/gnuradio: Found fd: 73  usbfs_path: /dev/bus/usb/001/004
2022-04-14 12:24:40.170 12727-12727/net.bastibl.fm D/gnuradio: Found vid: 7504  pid: 24713
2022-04-14 12:24:40.170 12727-12727/net.bastibl.fm I/gnuradio: hackrf=0,fd=73,usbfs=/dev/bus/usb/001/004

so i chaned you'r mentioned line to this:

if(device.vendorId == 0x1D50 && device.productId == 0x6089) {

based on 7504=0x1D50 & 24713=0x6089

also Im using hackRf and this code:

ss << "hackrf=0,fd=" << fd << ",usbfs=" << env->GetStringUTFChars(usbfsPath, NULL)

Full checkHWPermission code:

    private fun checkHWPermission() {

        val manager = getSystemService(Context.USB_SERVICE) as UsbManager
        val deviceList: HashMap<String, UsbDevice> = manager.deviceList
        deviceList.values.forEach { device ->
            if(device.vendorId == 0x1D50 && device.productId == 0x6089) {
//            if(device.vendorId == 0x1d50) {
//            if(device.vendorId == 0x2500) {
                val permissionIntent = PendingIntent.getBroadcast(this, 0, Intent(ACTION_USB_PERMISSION), 0)
                val filter = IntentFilter(ACTION_USB_PERMISSION)
                registerReceiver(usbReceiver, filter)

                manager.requestPermission(device, permissionIntent)
            }
        }
    }

ERROR:

E/libc++abi: terminating with uncaught exception of type std::runtime_error: Failed to create FFTW wisdom lockfile: /sdcard/gnuradio/gr_fftw_wisdom.lock

A/libc: Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 12727 (net.bastibl.fm), pid 12727 (net.bastibl.fm)

Full Log:

2022-04-14 12:30:55.971 14546-14546/net.bastibl.fm D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2022-04-14 12:30:56.014 14546-14546/net.bastibl.fm D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2022-04-14 12:30:56.015 14546-14546/net.bastibl.fm D/ActivityThread: handleBindApplication() -- skipGraphicsSupport=false
2022-04-14 12:30:56.125 14546-14546/net.bastibl.fm V/uhd::b200_impl: Registering B200
2022-04-14 12:30:56.125 14546-14546/net.bastibl.fm V/uhd::b200_impl:     Registered
2022-04-14 12:30:56.205 14546-14546/net.bastibl.fm E/net.bastibl.fm: Invalid ID 0x00000000.
2022-04-14 12:30:56.216 14546-14546/net.bastibl.fm I/DecorView: [INFO] isPopOver=false, config=true
2022-04-14 12:30:56.216 14546-14546/net.bastibl.fm I/DecorView: updateCaptionType >> DecorView@310cca1[], isFloating=false, isApplication=true, hasWindowDecorCaption=false, hasWindowControllerCallback=true
2022-04-14 12:30:56.216 14546-14546/net.bastibl.fm D/DecorView: setCaptionType = 0, this = DecorView@310cca1[]
2022-04-14 12:30:56.295 14546-14546/net.bastibl.fm W/net.bastibl.fm: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist, reflection, allowed)
2022-04-14 12:30:56.297 14546-14546/net.bastibl.fm W/net.bastibl.fm: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist, reflection, allowed)
2022-04-14 12:30:56.469 14546-14546/net.bastibl.fm D/InputTransport: Input channel constructed: 'e730309', fd=74
2022-04-14 12:30:56.473 14546-14546/net.bastibl.fm I/ViewRootImpl@cb6a3ba[MainActivity]: setView = com.android.internal.policy.DecorView@310cca1 TM=true
2022-04-14 12:30:56.479 14546-14546/net.bastibl.fm D/gnuradio: #################### NEW RUN ###################
2022-04-14 12:30:56.480 14546-14546/net.bastibl.fm D/gnuradio: Found fd: 73  usbfs_path: /dev/bus/usb/001/004
2022-04-14 12:30:56.480 14546-14546/net.bastibl.fm D/gnuradio: Found vid: 7504  pid: 24713
2022-04-14 12:30:56.480 14546-14546/net.bastibl.fm I/gnuradio: hackrf=0,fd=73,usbfs=/dev/bus/usb/001/004
2022-04-14 12:31:06.323 14546-14546/net.bastibl.fm E/libc++abi: terminating with uncaught exception of type std::runtime_error: Failed to create FFTW wisdom lockfile: /sdcard/gnuradio/gr_fftw_wisdom.lock
2022-04-14 12:31:06.324 14546-14546/net.bastibl.fm A/libc: Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 14546 (net.bastibl.fm), pid 14546 (net.bastibl.fm)

I open the app .
it requests for the permissions
i grant it
it crashes

Could you please tell me what should i do more? and whats my wrong?

Adalm-pluto support?

Hello,
I have this board and would like to try with this environment. it's possible?.

Building example projects in docker

The docker image builds okay, but the three linked example projects:

  • gnuradio-fm
  • gnuradio-volk
  • gnuradio-benchmark

Don't actually build with android studio as configured by the docker container. There are so far a few issues identified:
1. build.gradle is pointing to a deprecated repository [all projects]
It looks like build.gradle in the root directory of all three are using jcenter() (which is deprecated?). Adding mavenCentral() to the allprojects and buildscript repositories resolved the dependencies not being pulled in.

2. fm and benchmark are referencing different ndk versions than this repo is.
Both gnuradio-fm and gnuradio-benchmark expect the ndk version 20.0....., but the docker container installs 21.3.6528147.

3. gnuradio-fm references a package with a dependency not currently found in mavenCentral(), which is com.androidplot-core:1.5.7 with figplot 1.0.7. The earliest available version I could find on mavenCentral is 1.5.9, but that appears to have deprecated a function used in MainActivity, as when we run it we see an address error (not totally sure about this one).

The first two issues I was able to resolve, the third issue I was not able to fix. Any chance I could get an assist with this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.