Toemat Labs

Foscam C1 IP Camera Teardown and Review

The Foscam C1

The Foscam C1 is an inexpensive wireless IP camera that sells for about $70 USD. I'm looking to replace some aging security cameras and based off my experience so far it looks like the C1 is just the ticket.

I've been using Foscam cameras around the house for a number of years. Specifically the FI8918W model which has motorized pan and tilt. I installed the first one in Jan 2011 and have added a few here and there since then.

That first camera has been running 24/7 for 5 straight years, outside with just a minimal amount of protection from nature. Somehow it's survived and I haven't had a single issue with it or with any other to others I've installed since then. (Impressive since they have moving mechanical parts. Even still – no issues).

Going inside the Foscam C1

Foscam C1 disassembled

How are we going to know what we're working with without first tearing it all apart? Besides, it's a great way to learn!

Just by looking at the outside it's clear that Foscam is trying to compete with the Nest Dropcams (It looks a lot like this model).

The Nest/Dropcam cameras are great but they're expensive and rely on a monthly subscription.

Foscam C1 top removed

It was easy to get the front cover off. It just snaps in place. Under that were a couple screws that hold the front half of the frame in place.

Looks like they've done a nice job with the spacial design. Two boards with a couple interconnects.

Foscam C1 cover with antenna

Here's the front half of the frame. If you look closely you can see the wifi antenna traces embedded in the frame.

The C1 doesn't have an external antenna hookup so you'll have to do with the internal one. Although I suppose you could connect something like this to the internal uFL plug and mount your own external SMA antenna if necessary!

Top PCB

The lens had to come out to get this first PCB out because the front of the lens doesn't fit through the center hole.

The component at the top is the PIR motion sensor. This is something my older cameras lacked, so I'm looking forward to seeing how well this detects people and other things.

Besides that, we've got a nice ring of IR LEDs and an ambient light sensor at the bottom of the ring. There's also a hookup for the microphone, which is mounted in the front cover.

Back PCB with lens

Here's the main board. I've reattached the lens just for the photo.

That enclosure at the base of the lens is actually an electromechanical IR filter, which moves the IR filter off the sensor when it goes into night time mode.

That red bit is the wifi module. Looks like they're using a MediaTek MT7601UN chip for the wifi.

Back PCB, IR filter

Here's with the IR filter in place. The PCB is densely populated. I'd say they did a great job on the layout.

Back PCB bottom

The back of the main board reveals the microSD card slot, the main processor (which had a heatsink stuck to it), and a mysterious unlabeled 4-pin port.

The processor is a Hi3518, apparently pretty standard for devices of this type.

Serial port connection

I suspected the unlabeled port near the CPU was a serial port, a little prodding with the oscilloscope confirmed.

Serial connector pinout

The connector fits a PicoBlade 51021-0400 (see Mouser). It spits out the linux boot output at 115200bps (at 3.3v):

U-Boot 2010.06 (Dec 11 2014 - 15:55:58)

Check spi flash controller v350... Found
Spi(cs1) ID: 0xC2 0x20 0x18 0xC2 0x20 0x18
Spi(cs1): Block:64KB Chip:16MB Name:"MX25L128XX"
MMC:   MMC FLASH INIT: No card on slot!
In:    serial
Out:   serial
Err:   serial
Auto-update from SD Card: 
MMC Device 1 not found
MMC Device 2 not found
MMC Device 3 not found
Can't find sd card device!
Can't load upgrade file, aborting sd -update
Auto-update from TFTP: trying update file 'recover_image.bin'
Hisilicon ETH net controler
MAC:   *redacted*
Up/Down PHY not link.
Can't load update file, aborting auto-update
Hit any key to stop autoboot:  1 0 
16384 KiB hi_sfc at 0:0 is now current device

## Starting application at 0x82000000 ...
Uncompressing Linux... done, booting the kernel.
Linux version 3.0.8 (root@foscam-virtual-machine) (gcc version 4.4.1 (Hisilicon_v100(gcc4.4-290+uclibc_0.9.32.1+eabi+linuxpthread)) ) #5 Sat Sep 13 12:38:53 CST 2014
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
CPU: VIVT data cache, VIVT instruction cache
Machine: hi3518
Memory policy: ECC disabled, Data cache writeback
AXI bus clock 200000000.
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 10922
Kernel command line: mem=43M console=ttyAMA0,115200 mtdparts=hi_sfc:512K(boot),3M(kernel),6M(app),6M(app_ext),512K(para)
PID hash table entries: 256 (order: -2, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 43MB = 43MB total
Memory: 37244k/37244k available, 6788k reserved, 0K highmem
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    DMA     : 0xffc00000 - 0xffe00000   (   2 MB)
    vmalloc : 0xc3000000 - 0xfe000000   ( 944 MB)
    lowmem  : 0xc0000000 - 0xc2b00000   (  43 MB)
    modules : 0xbf000000 - 0xc0000000   (  16 MB)
      .init : 0xc0008000 - 0xc0273000   (2476 kB)
      .text : 0xc0273000 - 0xc060c000   (3684 kB)
      .data : 0xc060c000 - 0xc0622540   (  90 kB)
       .bss : 0xc0622564 - 0xc06328cc   (  65 kB)
SLUB: Genslabs=13, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS:32 nr_irqs:32 32
sched_clock: 32 bits at 100MHz, resolution 10ns, wraps every 42949ms
Calibrating delay loop... 218.72 BogoMIPS (lpj=1093632)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
NET: Registered protocol family 16
Serial: AMBA PL011 UART driver
uart:0: ttyAMA0 at MMIO 0x20080000 (irq = 5) is a PL011 rev2
console [ttyAMA0] enabled
uart:1: ttyAMA1 at MMIO 0x20090000 (irq = 5) is a PL011 rev2
bio: create slab <bio-0> at 0
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
cfg80211: Calling CRDA to update world regulatory domain
Switching to clocksource timer1
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 2048 (order: 2, 16384 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 2048 bind 2048)
TCP reno registered
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
fuse init (API version 7.16)
msgmni has been set to 72
io scheduler noop registered
io scheduler deadline registered (default)
io scheduler cfq registered
Spi id table Version 1.22
Spi(cs1) ID: 0xC2 0x20 0x18 0xC2 0x20 0x18
SPI FLASH start_up_mode is 3 Bytes
Spi(cs1): 
Block:64KB 
Chip:16MB 
Name:"MX25L128XX"
spi size: 16MB
chip num: 1
5 cmdlinepart partitions found on MTD device hi_sfc
Creating 5 MTD partitions on "hi_sfc":
0x000000000000-0x000000080000 : "boot"
0x000000080000-0x000000380000 : "kernel"
0x000000380000-0x000000980000 : "app"
0x000000980000-0x000000f80000 : "app_ext"
0x000000f80000-0x000001000000 : "para"
Fixed MDIO Bus: probed
himii: probed
Invalid HW-MAC Address: 00:00:00:00:00:00
Set Random MAC address: *redacted*
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
hiusb-ehci hiusb-ehci.0: HIUSB EHCI
hiusb-ehci hiusb-ehci.0: new USB bus registered, assigned bus number 1
hiusb-ehci hiusb-ehci.0: irq 15, io mem 0x100b0000
hiusb-ehci hiusb-ehci.0: USB 0.0 started, EHCI 1.00
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
hiusb-ohci hiusb-ohci.0: HIUSB OHCI
hiusb-ohci hiusb-ohci.0: new USB bus registered, assigned bus number 2
hiusb-ohci hiusb-ohci.0: irq 16, io mem 0x100a0000
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 1 port detected
TCP cubic registered
NET: Registered protocol family 17
lib80211: common routines for IEEE802.11 drivers
øFreeing init memory: 2476K

init started: BusyBox v1.21.1 (2015-01-07 16:46:55 CST)

starting pid 271, tty '': '/etc/init.d/rcS'
mount: mounting tmpfs on /dev failed: Invalid argument

            _ _ _ _ _ _ _ _ _ _ _ _
            \  _  _   _  _ _ ___
            / /__/ \ |_/
           / __   /  -  _ ___
          / /  / /  / /
  _ _ _ _/ /  /  \_/  \_ ______
___________\___\__________________

[RCS]: /etc/init.d/S00devs
mknod: /dev/console: File exists
mknod: /dev/ttyAMA0: File exists
mknod: /dev/ttyAMA1: File exists
mknod: /dev/ttyS000: File exists
[RCS]: /etc/init.d/S01udev
udevd (304): /proc/304/oom_adj is deprecated, please use /proc/304/oom_score_adj instead.
[RCS]: /etc/init.d/S80network
[RCS]: /etc/init.d/S90init
[ver_get_oldver.212]:1.9.1.12,2.52.2.5.
local mac: *redacted*
broadcast ioctl error![99-Cannot assign requested address]
Can not find broadcast client!
[exit_main.26]:exit app[99.Cannot assign requested address].
can't find /dev/mmcblk0p1
sd card vfat32 system don't need fix.
/mnt/para/etc/sm_cn_private.pem exist !
/mnt/para/etc/RT2870AP.dat exist !
/mnt/para/etc/udhcpd.conf exist !
/mnt/para/etc/logo.argb4444 exist !
/mnt/para/etc/logo_vga.argb4444 exist !
can't find /mnt/para/config/Rom.dat.
ln -sf /mnt/para/etc/Rom.dat /mnt/para/config/Rom.dat
---- Your model name is C1 SENSOR=7 WIFI=2 LANGUAGE=2 MODELVERSION=52----
---- Your input model name is C1 ----
mem=39720
Hisilicon Media Memory Zone Manager
hi3518_base: module license 'Proprietary' taints kernel.
Disabling lock debugging due to kernel taint
Hisilicon UMAP device driver interface: v3.00
pa:82b00000, va:c31c0000
load sys.ko for Hi3518...OK!
load viu.ko for Hi3518...OK!
ISP Mod init!
load vpss.ko ....OK!
load venc.ko for Hi3518...OK!
load group.ko for Hi3518...OK!
load chnl.ko for Hi3518...OK!
load h264e.ko for Hi3518...OK!
load jpege.ko for Hi3518...OK!
load rc.ko for Hi3518...OK!
load region.ko ....OK!
load vda.ko ....OK!
hi_i2c init is ok!
insmod: can't insert 'extdrv/gpioi2c_ex.ko': No such file or directory
initialized adc driver success
---- Your input Sensor type is 7 ----
*** Board tools : ver0.0.1_20120501  *** 
[debug]: {source/utils/cmdshell.c:166}cmdstr:himm
0x20030030: 0x00000000 --> 0x00000001 
[END]
Kernel: ssp initial ok!
acodec inited!
insert audio
---- Your input Wifi type is 2 ----
rtusb init rtusbSTA --->
usbcore: registered new interface driver rtusbSTA
ptz_init start ptz_state[1],HorPos[0],VerPos[0]
setup ptz gpio success
setup zoom gpio success
ptz_init end ptz_state[1],HorPos[-1],VerPos[-1],flag[0]
Hisilicon Watchdog Timer: 0.01 initialized. default_margin=5 sec (nowayout= 0, nodeamon= 0)
set rtc time to system time

starting pid 831, tty '': '/sbin/getty -L ttyS000 115200 vt100 -n root -I "Auto login as root ..."'
Auto login as root ...
(none) login: killall: devMng: no process killed
killall: codec: no process killed
killall: UDTMediaServer: no process killed
killall: webService: no process killed
killall: storage: no process killed
killall: FirmwareUpgrade: no process killed
killall: OnvifAgent: no process killed
set time
year:2015
month:9
date:1
hour:22
minute:16
second:11
time.nist.gov: Unknown host
mkdir: can't create directory '/usr/local/pureftpd': File exists
mkdir: can't create directory '/usr/local/pureftpd/etc': File exists
creatSystemUser
Changing password for ftpuser1
New password: 
Retype password: 
Password for ftpuser1 changed by root
creatVirtualUser
Password: 
Enter it again: 
usb 1-1: new high speed USB device number 2 using hiusb-ehci
killall: CGIProxy.fcgi: no process killed
killall: lighttpd: no process killed


--= pAd = c3691000, size = 860440 --=

<-- RTMPAllocTxRxRingMemory, Status=0
<-- RTMPAllocAdapterBlock, Status=0
RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x8
RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x4
RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x5
RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x6
RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x7
RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x9
NVM is EFUSE
Endpoint(8) is for In-band Command
Endpoint(4) is for WMM0 AC0
Endpoint(5) is for WMM0 AC1
Endpoint(6) is for WMM0 AC2
Endpoint(7) is for WMM0 AC3
Endpoint(9) is for WMM1 AC0
Endpoint(84) is for Data-In
Endpoint(85) is for Command Rsp


Lighttpd Server BUILD:May  5 2015 15:12:46

2015-09-01 22:16:12: (network.c.724) --1--srv->config_storage[ 0 ]= 0 
2015-09-01 22:16:12: (network.c.724) --1--srv->config_storage[ 1 ]= 1 
WARNING: can't open config file: /usr/local/openssl/ssl/openssl.cnf
2015-09-01 22:16:12: (network.c.985) --2--srv->config_storage[ 1 ]= 1 
2015-09-01 22:16:12: (network.c.456) --------=s->ssl_enabled= 0 
2015-09-01 22:16:12: (network.c.456) --------=s->ssl_enabled= 1 
2015-09-01 22:16:12: (log.c.164) server started 
killall: pure-ftpd: no process killed
SMT DEBUG : ERROR : Adapter is NULLdriver: ircut_switch.low:250,ircut_switch.high:580
netstat: /proc/net/tcp6: No such file or directory
driver: close IR_LED
MaxQp=34...........................
stVencRcPara.stParamH264VBR.s32DeltaQP=2
1. LDO_CTR0(6c) = a64799, PMU_OCLEVEL c
2. LDO_CTR0(6c) = a6478d, PMU_OCLEVEL 6
FW Version:0.1.00 Build:7640
Build Time:201308222153____
ILM Length = 47000(bytes)
DLM Length = 0(bytes)
Loading FW....
#
RTMP_TimerListAdd: add timer obj c371192c!
RTMP_TimerListAdd: add timer obj c3711944!
RTMP_TimerListAdd: add timer obj c371195c!
RTMP_TimerListAdd: add timer obj c3711914!
RTMP_TimerListAdd: add timer obj c37118cc!
RTMP_TimerListAdd: add timer obj c37118e4!
RTMP_TimerListAdd: add timer obj c36a6764!
RTMP_TimerListAdd: add timer obj c36931e0!
RTMP_TimerListAdd: add timer obj c36931fc!
RTMP_TimerListAdd: add timer obj c36a67bc!
RTMP_TimerListAdd: add timer obj c3695cf0!
RTMP_TimerListAdd: add timer obj c36953a0!
RTMP_TimerListAdd: add timer obj c3695cd4!
RTMP_TimerListAdd: add timer obj c3695f14!
RTMP_TimerListAdd: add timer obj c3695d0c!
RTMP_TimerListAdd: add timer obj c3695d28!
RTMP_TimerListAdd: add timer obj c3695d44!
RTMP_TimerListAdd: add timer obj c36a6734!
RTMP_TimerListAdd: add timer obj c36a67a4!
RTMP_TimerListAdd: add timer obj c3695f44!
RTMP_TimerListAdd: add timer obj c3695f5c!
RTMP_TimerListAdd: add timer obj c3695f74!
RTMP_TimerListAdd: add timer obj c3695f8c!
cfg_mode=5
wmode_band_equal(): Band Equal!
Key1Str is Invalid key length(0) or Type(0)
Key2Str is Invalid key length(0) or Type(0)
Key3Str is Invalid key length(0) or Type(0)
Key4Str is Invalid key length(0) or Type(0)
1. Phy Mode = 14
2. Phy Mode = 14
NVM is Efuse and its size =1d[1e0-1fc] 
3. Phy Mode = 14
AntCfgInit: primary/secondary ant 0/1
---> InitFrequencyCalibration
InitFrequencyCalibrationMode:Unknow mode = 3
InitFrequencyCalibration: frequency offset in the EEPROM = 108(0x6c)
<--- InitFrequencyCalibration
RTMPSetPhyMode: channel is out of range, use first channel=1 
MCS Set = ff 00 00 00 01
<---- rt28xx_init, Status=0
0x1300 = 00064300
RTMPDrvOpen(1):Check if PDMA is idle!
RTMPDrvOpen(2):Check if PDMA is idle!
RTMP_TimerListAdd: add timer obj bf362748!
smtcn_channel_switch_init
smtcn_channel_switch_start
SMT_DEBUG: _pfsm_rst:0,0
SMT DEBUG smtcn_flag: 1
smtcn_channel_switch_timeout
smtcn_channel_switch_start
...


Login timed out 
process '/sbin/getty -L ttyS000 115200 vt100 -n root -I "Auto login as root ..."' (pid 831) exited. Scheduling for restart.

starting pid 1092, tty '': '/sbin/getty -L ttyS000 115200 vt100 -n root -I "Auto login as root ..."'
Auto login as root ...
(none) login: smtcn_channel_switch_timeout
smtcn_channel_switch_start
smtcn_channel_switch_timeout
...

If anyone has any idea how to log into root on this thing please let me know, I'd love to get access to the software.

Speaking of software

Typically I loathe the software (i.e. web interface) that comes with these things but the web interface on this C1 is actually not so bad.

It streams the HD feed quickly with low latency, has an interface for viewing recorded videos from the microSD and, maybe most impressively, it can link up to other cameras on the network to provide a grid view without having a central server.

The only problem? You have to install a browser plugin. Between that and a couple of usability issues I think I'll be rolling my own viewer interface.

I'm still working on that part, but I've at least found how to request a static JPEG:

Get a single JPEG from the C1

http://ipaddr:88/CGIProxy.fcgi?cmd=snapPicture2&usr=xxx&pwd=xxx

Just note that the user has to be administrator level.

I was really hoping there would be a way to get an MJPEG stream from this camera but from what I've seen it seems not possible.

Is it any good?

Yes.

It's small, seems well designed, the price is right, and the interface isn't even that bad. I think I'll replace all of my IP cams with the C1.

Check Amazon for the latest Foscam C1 pricing. Thanks for stopping by and let me know if you have any questions! 📹🔥

Thomas Renck

I make things. Sometimes I un-make things. Most of the time I write code and teach on intentionality in design.