Sheet 1
TimeLine(OCT,2015)
  10.08
    DONE
      optimized func: fileDBUtil.c->get_mzdb_path @@get it from mpdconf
      add cjson to mpd
      ecapsulate func: glue_mzdb_init_and_load() to fileDBUtil.c
      optimize func: setchannelmod @@fix bug when playerstatus = play
      fix bug: add urlsong's correct title to mpd
      add sqliteUtil to mpd
    KEY
      warning: implicit declaration of function 'usleep'
        该文件未引入相应头文件，但在其他文件中有引入
      song tag property
        g_snprintf(tracknum, sizeof(tracknum), "%d", track->tracknumber);
g_snprintf(date, sizeof(date), "%d", track->year);
g_snprintf(comment, sizeof(comment),
track->file_bitrate / 1000, track->geo_restricted ? "" : "not ");
tag_add_item(tag, TAG_TITLE, track->title);
tag_add_item(tag, TAG_ARTIST, track->artist->name);
tag_add_item(tag, TAG_TRACK, tracknum);
tag_add_item(tag, TAG_ALBUM, track->album);
tag_add_item(tag, TAG_DATE, date);
tag_add_item(tag, TAG_COMMENT, comment);
tag->time = track->length / 1000;
      sqlite demo
        http://www.tutorialspoint.com/sqlite/sqlite_c_cpp.htm
        callback
          http://www.cnblogs.com/nbsofer/archive/2012/05/29/2523807.html
          http://www.cnblogs.com/likebeta/archive/2012/06/17/2552757.html
      adb pull /sdcard/data/sqlite.db ./
    PROBLEM
      settingActivity.java 338n
        A.异常关闭后，无法通过界面启动
        B.列表状态未保存
      handle拆分多个文件
  10.09
    DONE
      定位 r13 定时开关bug
        定时开关与远程开关wifi的逻辑冲突
      与占勇联调mpd
        广播新代码
        url song's correct titile
        出现mpd异常关闭，解除某段注释
      add clear groupId
      add log for mpd to check exception
      fix bug: can't play local song
        file: & title 傻傻分不清楚～
      与占勇联调/讨论
    KEY
      shell EOF
        “<<EOF“表示后续的输入作为子命令或子shell的输入，直到遇到”EOF“
    PROBLEM
      添加url song出现卡顿现象
      url过期问题
        优先级较低
        token
      mpd同步模式在断电后清除
        mpdstate:master / slave -> alone
  10.11
    DONE
      与占勇联调
        添加mac地址
        add song with artist & album & img_url
      研究mpd idle & status
        添加idle_group
      广播中加入ssid
      调试同步功能
    KEY
      get current ssid
        iwlist wlan0 scanning |grep -A5 'Cell 01'
        iwconfig wlan0
        cat /data/misc/wifi/wpa_supplicant.conf |grep -C0 'ssid' > /data/data/be.deadba.ampd/files/ssid.tmp
      adb connect 192.168.199.152:5555
      adb -s 192.168.199.152:5555 logcat MEIZUMsg:I *:S
      am start -n be.deadba.ampd/.SettingsActivity
      adb -s 192.168.199.152:5555 uninstall be.deadba.ampd
    PROBLEM
      error: problems decoding "http://m5.file.xiami.com/411/75411/535630361/1774453639_16848870_l.mp3?auth_key=4214655dc100f0b092e1d0025021a081-1444521600-0-null
      Can't load library: java.lang.UnsatisfiedLinkError: Couldn't load cpufeatures_jni from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/be.deadba.ampd-1.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]]: findLibrary returned null
      ssid不能动态更新
      要先cancelslave，再cancelmaster
  10.12
    DONE
      调试mpd同步
      尝试jni/mpd获取系统文件
      java动态更新ssid
      优化/封装java savessid代码
      mpd重新运行时，重置mpdstate（groupid & mpdstate）
    PROBLEM
      mpd同步过程中不能快进
      第二次同步卡住
        一边正常播放，一次没播放
        一边正常播放，另一边进度条正常，但没有声音
      第一次同步成功后，再做任何操作失败率百分之百
  10.13
    DONE
      实现ampd java代码调用jni中的c函数Demo
      在handle_status中加入speakername
      加入mpd handler util类
      配合占勇/建峰调试mpd
    TODO
      command.c中逻辑代码抽离略坑
      整合接口（single，repeat，list，cycle）
    PROBLEM
      优化同步问题后，出现无法操作进度条(快进/后退)的现象
  10.14
    DONE
      与占勇联调idle通知命令
      解决java调c代码，在service中可以调用，activity中不能调用的问题
      测试/log mpd同步
      抽离/新建mpd操作接口供r12按键使用
    KEY
      系统音量键是onkeydown触发
        不是onkeyup
    PROBLEM
      测出同步问题：两台音箱中的一台硬件有问题
      两套音量键接口，导致混乱
      error: problems decoding "http://m5.file.xiami.com/615/615/2686/379343_18911_l.mp3"
  10.15
    DONE
      groupid初始化值改为sn号
      add func: setplaymode
      add func: getplaymode
      调试mpd同步成功
    KEY
      adb -s 192.168.199.221:5555 logcat MPDMsg:I *:S|grep 'handle_sync 2217'
    PROBLEM
      单个mpd操作进度条卡顿
        甚至会使连接断开
  10.16
    DONE
      fix bug: the state of player thread keep locking when calling libmpd_next()
        死锁问题
      add volume long key listener
    KEY
      pthread_mutex_lock( &g_mtx );
      pthread_cond_wait( &g_cond , &g_mtx );
        条件等待
      pthread_cond_timedwait(cond, mutex,abstime)
        计时等待
      pthread_mutex_unlock( &g_mtx );
  10.19
    DONE
      与占勇联调playmode / status接口
      调试playthread.c
      log得出结论：idle_add通知只能特定线程调用有效
    TODO
      按键模拟客户端访问mpd
      Service监控mpd状态
  10.20
    adjust func args:handle_add
    add exception statistics tools :youmeng
    与建峰联调handle_add()
    测试g_cond_timewait稳定性
  10.21
    DONE
      配合建峰联调handle_add接口
      配合建峰联调handle_playmode & handle_setchannelmod
      配合艾工调试MPD同步功能
      测试mpd稳定性
      检测友盟代码是否生效
      mpd运行时默认将android媒体音量调制最高
      fix bug: 随机播放设置错误
    PROBLEM
      同步功能设置后，apk未更新同步状态，命令只给其中一条
      apk在列表上点击播放正常，但在播放界面上命令执行时有时只有一方收到
  10.22
    DONE
      add interface setVol for java layer
      coding: set wifibox init volume from 100% to 66% failed
      adjust new interface: notify idle msg to client
      log to find the init volume
    PROBLEM
      列表混乱
      请求稳定性问题与超时重传机制问题
  10.23
    DONE
      开会讨论r12技术架构问题
      fix bug: cann't set mpd init volume
      竞品分析：SONOS
        同步场景操作
          apk连上两台sonos音箱
          分别往两台音箱加入不同数量，不同歌名的歌曲
            列表不同
          点击播放其中一台音箱的歌曲
          将另一台音箱组到正在播歌的音箱，这台音箱立即同声播放
          解散情况
            将后来加入的音箱从分组中分离
              后加入音箱的歌单状态回到原先的状态
            将先加入的音箱从分组中分离
              两台音箱的歌单状态相同
        随机播放
          sonos随机播放仅是将列表顺序打乱
            播放仍是顺序播放
          如正在播放某首歌时，设置随机播放
            正在播放的歌默认为第一首
            列表中其他歌顺序打乱
          取消随机播放，列表顺序状态恢复原始状态
        网络不稳定情景
          迅雷全开情景
          进入apk时，直接提示找不到sonos
          如果还能进入主界面
            apk与音箱交互会出现卡顿延迟现象
            音箱依旧处于同步状态
              要么一起播，要么一起停止
        DLNA推送
          推送列表情况
            推送给未配对音箱
              列表中有多台音箱可供选择推送
            推送给已配对音箱
              列表中只有一台音箱可供选择推送
          推送的歌不会加到列表中
          qq音乐推送情景
            (1)添加歌单到qq音乐列表中
            (2)选择播放列表第一首歌
            (3)将正在播放的歌推送到已配对音箱上
            (4)配对音箱开始同声播放
            (5)歌曲播完，继续推送并播qq音乐列表中的下一首歌
        手机音乐推送
          与DLNA不同，sonos列表中会有该歌曲信息
        配置立体声对
          左右声道
          SONOS会让用户按下靠左位置的音箱上的+键来辅助设置
          防止靠右位置的音箱被设置成左声道
          配置完立体声对后，分组里就只有一台音箱了
            无法通过取消分组，来拆散音箱
            要通过取消立体声对来解除
            取消立体声对，分组状态依然存在
        其他细节
          SONOS不能连接5g网络
          SONOS音量键各自加减，播放键则是同步控制的
          SONOS无单曲循环功能
      研究列表解决混乱思路
  10.24
    将ampd项目转成gradle项目
    熟悉在androidstudio上调试ampd
    试着在android studio上进行gdb
  10.26
    DONE
      android ndk gdb配置
      fix bug: cp: cannot stat './libs/armeabi/gdb.setup': No such file or directory
      fix bug:syntax error: bad substitution
      fix error: 'asm' operand has impossible constraints
    KEY
      ndk配置命令
        ndk-build -j32 NDK_DEBUG=1
        ndk-gdb --launch=be.deadba.ampd.SettingsActivity --start --verbose
        ndk-gdb --launch-list
        ndk-gdb --start
      git
        git push origin master:master
        .gitignore提交后需
          git rm --cached app/src/main/jni/glib -rf
        submodule
          git submodule add git@10.2.67.25:r12/jni/curl app/src/main/jni/curl
        git stash apply stash@{1}
  10.27
    DONE
      成功将mpd整合到androidstudio下运行，并推到新分支as_master
      log mpd proxy相关代码
        curl_input_plugin.c
          input_curl_headerfunction()
          input_curl_writefunction()
          g_queue_push_tail
        ntp_client.c
          bug: strcpy is different from memcpy
        ntp_server.c
      更改ndk-gdb代码
      fix gdb error: load libso uncorrectly
  10.28
    DONE
      寻找android studio gdb方法
      log mpd proxy & sync代码
      fix gdb error: can't not load sharelibrary
  10.29
    DONE
      configure android gdb
        add-symbol-file /home/rh/my_code/ampd/app/src/main/obj/local/armeabi/libmpd.so 0x79a57000
        exist error: cannot load sharelibrary
      log mpd proxy & sync代码
        strcpy & memcpy bug
        slave receive stream后,如何处理
          新增mz_stream_input_plugin处理
          Decoder_thread控制
        libmpd.c相关变量
        cache file code
        ntp server /ntp client
        DelayTime & DiffTime
        log三次请求失败原因
  10.30
    log mpd sync code
      elapsed_time
      input_stream.c read buffer to ffmpeg decoding
      先slave,在master原因
        http://www.cnblogs.com/ziyunfei/archive/2012/11/18/2775499.html
      彻底cancelslave & cancelmaster
    gradle项目重新整理submodule
  10.31
    ampd整合libmpdclient
      修改配置android.mk/application.mk
      将libmpdclient的.h/.c引入libmpd
      fix error: iso8601_datetime_parse&ie=UTF-8
      fix error:Can't load library: java.lang.UnsatisfiedLinkError
        libmpdclient需要在载入libmpd之前加载
      fix bug: select return 0
        means timeout
        mainthread call by itself & block itself
    socket I/O复用
      select函数调用修改
        select(fd + 1, &rfds, &wfds, &efds, tv);
        FD_ZERO(&rfds);
        FD_ZERO(&wfds);
        FD_ZERO(&efds);
        FD_SET(fd, &rfds);
      使用poll函数调用替代select
        #define POLLIN 0x0001
        #define POLLPRI 0x0002
        #define POLLOUT 0x0004
        #define POLLERR 0x0008
        #define POLLHUP 0x0010
        #define POLLNVAL 0x0020
        #define POLLRDNORM 0x0040
        #define POLLRDBAND 0x0080
        #define POLLWRNORM 0x0100
        #define POLLWRBAND 0x0200
        #define POLLMSG 0x0400
        #define POLLREMOVE 0x1000
        #define POLLRDHUP 0x2000
        Summary
          POLLIN|POLLPRI类似于select的读事件
          POLLOUT|POLLWRBAND类似于select的写事件
          POLLIN|POLLOUT监控是否可读或可写
      poll demo
        #include <stropts.h>
#include <poll.h>
...
struct pollfd fds[2];
int timeout_msecs = 500;
int ret;
int i;
/* Open STREAMS device. */
fds[0].fd = open("/dev/dev0", ...);
fds[1].fd = open("/dev/dev1", ...);
fds[0].events = POLLOUT | POLLWRBAND;
fds[1].events = POLLOUT | POLLWRBAND;
ret = poll(fds, 2, timeout_msecs);
if (ret > 0) {
/* An event on one of the fds has occurred. */
for (i=0; i<2; i++) {
if (fds[i].revents & POLLWRBAND) {
/* Priority data may be written on device number i. */
...
}
if (fds[i].revents & POLLOUT) {
/* Data may be written on device number i. */
...
}
if (fds[i].revents & POLLHUP) {
/* A hangup has occurred on device number i. */
...
}
}
}
1、复制的内容不同。strcpy只能复制字符串，而memcpy可以复制任意内容，例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度，它遇到被复制字符的串结束符"\0"才结束，所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy，而需要复制其他类型数据时则一般用memcpy