This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088

Dependents:   MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more

libMiMic(MiMic library for mbed)は、WebService機能を提供するSDKです。 mbedでWebAPIに対応したネットワークデバイスを簡単に作ることが出来ます。

libMiMicはMiMic projectで開発しています。MiMic projectについてはこちらをご覧ください。 http://nyatla.jp/mimic/wp/

構成

libMiMicはmbedRTOS上で動作し、ユーザアプリケーションにAPIを提供します。コアAPIはC言語で記述されていますが、使用頻度の高いものについてはmbed向けのC++APIが準備されています。

/media/uploads/nyatla/libmimic-sdk.png

※libMiMicはmbedの標準イーサネットドライバをしようしていません。

標準イーサネットドライバと同時に使用することはできません。

  • MiMicIP - IPv4スタックです。レテンシとメモリ消費量を抑えたuipベースのライブラリです。
  • ARP/ICMP/UDP/TCP - 基礎的なソケットAPIを提供します。APIは独自です。
  • HTTP/1.1 Server - HTTP/1.1に対応したサーバです。マルチセッション・Chunked・持続性接続に対応しています。
  • HTTP Modules - HTTP/1.1の機能モジュールです。以下のモジュールがあります。
    • ROM file provider - ROMに格納したファイルイメージを公開します。
    • File system provider - mbedファイルシステムを公開します。
    • Onchip configuration - プログラムフラッシュを利用して設定を保存します。
    • MiMicVM processor - RPCリクエスト(MiMicVM)を処理します。
    • FileUpload - ファイルアップロードを受け取ります。
    • URL decoder - HTTPリクエストを解析します。
    • UPnP handler -UPnPメッセージを処理します。
    • WebSocket - Websocketサーバです。
  • mDNS - マルチキャストDNSサービスです。
  • UPnP - UPnP/1.0の機能を提供します。UPnP handlerと協調して動作します。(現在はデバイス探索(SSDP)・デスクリプション(Description)のみ実装してあります。)
  • DHCP/APIPA - ゼロコンフィギュレーション用のモジュールです。
  • HTTP/1.1 Client
  • mbed C++ class library - mbed向けのC++CPIです。C言語のものより簡単です。

対応機種

  • mbed(mbed LPC1768)
  • LPCXpresso1769

プログラム

Import programMiMicRemoteMCU-for-Mbed

MiMic RemoteMCU for mbed. This program provides MCU control API over REST API. It can control MCU from Javascript,PHP or any HTTP rest client directly. And, The application has self development environment.

Import programMbedFileServer

The program publishes files at local directory and SD filesystem. It is a full-fledged webServer somewhat.

サンプル

Import programMiMicSimpleHttpd

This is a simplest HTTP server made ​​of libMiMic. It will echo back a request path.

Import programUPnPBasicDevice

Simplest UPnP basic device example. This program to run UPnP basic device on the mbed.

Import programWebSocketSample

MiMicSDK Websocket module sample program.

Import programHttpClientSamlpe

A http client sample program.

Import programTcpSocketClientSamlpe

MiMicSDK Tcp client socket sample program.

Import programUdpSocketSamlpe

Udp socket sample program. This program will send back the received packet.

チュートリアル

English

libMiMic(MiMic library for mbed) is SDK which provides Webservice functions. It can be created networking device easily using mbed.

See more MiMic information, See MiMic project website. http://nyatla.jp/mimic/wp/

Structure

libMiMic run on mbed RTOS and provides networking API to user application. This library has C++ class API for the mbed, and low-level C language API.

/media/uploads/nyatla/libmimic-sdk.png

For WebService general, it can be written in a simple C + + API.

libMiMic does not have the standard Ethernet driver of mbed. It is not possible that will be used with the standard Ethernet driver.

  • MiMicIP - IPv4 protocol stack. This is based uip which is reduced memory and latency.
  • ARP / ICMP / UDP / TCP - Those are provide basic IP protocols.
  • HTTP/1.1 Server - The Http server compatible HTTP/1.1. It supports multi-session, chunked transport, persistent connection.
  • HTTP Modules - There are addon-module for HTTP server. The following modules.
    • ROM file module - Publish the file images in ROM.
    • File system module - Publish thefiles in mbed file system.
    • Onchip configuration module - To save the network settings to the program flash via REST.
    • MiMicVM module - To handle the (MiMicVM) RPC request.
    • FileUpload module - Accept a file via HTTP POST.
    • URL dedoce module - A versatility URL decoder.
    • UPnP handle module - To handle UPnP messages.
    • UPnP - This provides UPnP/1.0 device functions. It works together with UPnP handler.
    • Websocket - websocket (version13) server
  • mDNS Service - DNS-SD protocol server.
  • UPnP - This provides UPnP/1.0 device functions which works with UPnP handler. (You have been implemented (SSDP) ? description only (Description) device search now.) It is a module zero configuration for - DHCP / APIPA. mbed C + + class library - C of mbed for + + is the CPI. It is simple than that of the C language.
  • DHCP/APIPA - It support zero-cpnfigulation.
  • mbed C++ class library. Almost APIs for Web applications are available.
  • HTTP/1.1 Client

Supported target

  • mbed(mbed LPC1768)
  • LPCXpresso1769

Application

Import programMiMicRemoteMCU-for-Mbed

MiMic RemoteMCU for mbed. This program provides MCU control API over REST API. It can control MCU from Javascript,PHP or any HTTP rest client directly. And, The application has self development environment.

Import programMbedFileServer

The program publishes files at local directory and SD filesystem. It is a full-fledged webServer somewhat.

Sample

Import programMiMicSimpleHttpd

This is a simplest HTTP server made ​​of libMiMic. It will echo back a request path.

Import programUPnPBasicDevice

Simplest UPnP basic device example. This program to run UPnP basic device on the mbed.

Import programWebSocketSample

MiMicSDK Websocket module sample program.

Import programHttpClientSamlpe

A http client sample program.

Import programTcpSocketClientSamlpe

MiMicSDK Tcp client socket sample program.

Import programUdpSocketSamlpe

Udp socket sample program. This program will send back the received packet.

Tutorial

Committer:
nyatla
Date:
Thu Aug 08 15:21:43 2013 +0000
Revision:
50:35e765380772
Parent:
49:d4334acc3ec3
Child:
53:9fdba33969fe
bugfix; ????????????????; UPnP??????????????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nyatla 48:00d211aac2ec 1 /*********************************************************************************
nyatla 48:00d211aac2ec 2 * PROJECT: MiMic
nyatla 48:00d211aac2ec 3 * --------------------------------------------------------------------------------
nyatla 48:00d211aac2ec 4 *
nyatla 48:00d211aac2ec 5 * This file is part of MiMic
nyatla 48:00d211aac2ec 6 * Copyright (C)2011 Ryo Iizuka
nyatla 48:00d211aac2ec 7 *
nyatla 48:00d211aac2ec 8 * MiMic is free software: you can redistribute it and/or modify
nyatla 48:00d211aac2ec 9 * it under the terms of the GNU Lesser General Public License as published
nyatla 48:00d211aac2ec 10 * by the Free Software Foundation, either version 3 of the License, or
nyatla 48:00d211aac2ec 11 * (at your option) any later version.
nyatla 48:00d211aac2ec 12 *
nyatla 48:00d211aac2ec 13 * This program is distributed in the hope that it will be useful,
nyatla 48:00d211aac2ec 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nyatla 48:00d211aac2ec 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nyatla 48:00d211aac2ec 16 * GNU General Public License for more details.
nyatla 48:00d211aac2ec 17 *
nyatla 48:00d211aac2ec 18 * You should have received a copy of the GNU Lesser General Public License
nyatla 48:00d211aac2ec 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
nyatla 48:00d211aac2ec 20 *
nyatla 48:00d211aac2ec 21 * For further information please contact.
nyatla 48:00d211aac2ec 22 * http://nyatla.jp/
nyatla 48:00d211aac2ec 23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
nyatla 48:00d211aac2ec 24 *
nyatla 48:00d211aac2ec 25 *********************************************************************************/
nyatla 48:00d211aac2ec 26 #include "NyLPC_cSsdpSocket.h"
nyatla 48:00d211aac2ec 27 #include "NyLPC_http.h"
nyatla 48:00d211aac2ec 28 #include "NyLPC_uipService.h"
nyatla 48:00d211aac2ec 29 #include "../uip/NyLPC_cUipService_protected.h"
nyatla 48:00d211aac2ec 30
nyatla 48:00d211aac2ec 31 #include <stdio.h>
nyatla 48:00d211aac2ec 32 #include <string.h>
nyatla 48:00d211aac2ec 33
nyatla 48:00d211aac2ec 34
nyatla 48:00d211aac2ec 35
nyatla 48:00d211aac2ec 36
nyatla 48:00d211aac2ec 37
nyatla 48:00d211aac2ec 38 #define HTTP_SP 0x20
nyatla 48:00d211aac2ec 39
nyatla 48:00d211aac2ec 40 #define PARSE_NULL 0
nyatla 48:00d211aac2ec 41 #define PARSE_ST 0x01
nyatla 48:00d211aac2ec 42 #define PARSE_MAN 0x11
nyatla 48:00d211aac2ec 43 #define PARSE_UNKNOWN 0xff
nyatla 48:00d211aac2ec 44
nyatla 48:00d211aac2ec 45 static const struct NyLPC_TIPv4Addr SSDP_MCAST_IPADDR=NyLPC_TIPv4Addr_pack(239,255,255,250);
nyatla 48:00d211aac2ec 46 static const char* STR_UPNP_ROOT_DEVICE="upnp:rootdevice";
nyatla 48:00d211aac2ec 47
nyatla 48:00d211aac2ec 48 struct TMSearchHeader
nyatla 48:00d211aac2ec 49 {
nyatla 48:00d211aac2ec 50 struct NyLPC_THttpBasicHeader super;
nyatla 48:00d211aac2ec 51
nyatla 48:00d211aac2ec 52 const struct NyLPC_TUPnPDeviceRecord* _ref_devices;
nyatla 48:00d211aac2ec 53 /**
nyatla 48:00d211aac2ec 54 * パーサのステータス
nyatla 48:00d211aac2ec 55 */
nyatla 48:00d211aac2ec 56 NyLPC_TUInt8 st;
nyatla 48:00d211aac2ec 57 /**
nyatla 48:00d211aac2ec 58 * メモリ位置
nyatla 48:00d211aac2ec 59 */
nyatla 48:00d211aac2ec 60 const NyLPC_TChar* _rpos;
nyatla 48:00d211aac2ec 61 struct{
nyatla 48:00d211aac2ec 62 const NyLPC_TChar* st_str;
nyatla 48:00d211aac2ec 63 const NyLPC_TChar* man_str;
nyatla 48:00d211aac2ec 64 NyLPC_TUInt16 st_len;
nyatla 48:00d211aac2ec 65 NyLPC_TUInt16 man_len;
nyatla 48:00d211aac2ec 66 }result;
nyatla 48:00d211aac2ec 67 };
nyatla 48:00d211aac2ec 68
nyatla 48:00d211aac2ec 69 //とりあえずprivate
nyatla 48:00d211aac2ec 70 void NyLPC_cSsdpSocket_notify(NyLPC_TcSsdpSocket_t* i_inst);
nyatla 48:00d211aac2ec 71
nyatla 48:00d211aac2ec 72
nyatla 48:00d211aac2ec 73 static NyLPC_TBool urlHandler(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out)
nyatla 48:00d211aac2ec 74 {
nyatla 48:00d211aac2ec 75 // *であるかを確認 未実装
nyatla 48:00d211aac2ec 76 return NyLPC_TBool_TRUE;
nyatla 48:00d211aac2ec 77 }
nyatla 48:00d211aac2ec 78 static NyLPC_TInt16 printIpAddr(const struct NyLPC_TIPv4Addr* i_ip,NyLPC_TChar* i_buf)
nyatla 48:00d211aac2ec 79 {
nyatla 48:00d211aac2ec 80 NyLPC_TUInt32 ip;
nyatla 48:00d211aac2ec 81 NyLPC_TUInt8 v;
nyatla 48:00d211aac2ec 82 NyLPC_TInt8 l;
nyatla 48:00d211aac2ec 83 NyLPC_TChar* p=i_buf;
nyatla 48:00d211aac2ec 84 //IPをホストオーダーにする。
nyatla 48:00d211aac2ec 85 ip=NyLPC_NTOHL(i_ip->v);
nyatla 48:00d211aac2ec 86 for(l=3;l>=0;l--){
nyatla 48:00d211aac2ec 87 v=(ip>>(8*l))&0xff;
nyatla 48:00d211aac2ec 88 if(v<10){
nyatla 48:00d211aac2ec 89 //1桁
nyatla 48:00d211aac2ec 90 *(p+0)=v+'0';
nyatla 48:00d211aac2ec 91 *(p+1)='.';
nyatla 48:00d211aac2ec 92 p+=2;
nyatla 48:00d211aac2ec 93 }else if(v<100){
nyatla 48:00d211aac2ec 94 //2桁
nyatla 48:00d211aac2ec 95 *(p+0)=(v/10)+'0';
nyatla 48:00d211aac2ec 96 *(p+1)=(v%10)+'0';
nyatla 48:00d211aac2ec 97 *(p+2)='.';
nyatla 48:00d211aac2ec 98 p+=3;
nyatla 48:00d211aac2ec 99 }else{
nyatla 48:00d211aac2ec 100 //3桁
nyatla 48:00d211aac2ec 101 *(p+0)=(v/100)+'0';
nyatla 48:00d211aac2ec 102 *(p+1)=((v/10)%10)+'0';
nyatla 48:00d211aac2ec 103 *(p+2)=(v%10)+'0';
nyatla 48:00d211aac2ec 104 *(p+3)='.';
nyatla 48:00d211aac2ec 105 p+=4;
nyatla 48:00d211aac2ec 106 }
nyatla 48:00d211aac2ec 107 }
nyatla 48:00d211aac2ec 108 return p-i_buf-1;
nyatla 48:00d211aac2ec 109 }
nyatla 48:00d211aac2ec 110 #define TIMEOUT_IN_MS 100
nyatla 48:00d211aac2ec 111
nyatla 48:00d211aac2ec 112 /**
nyatla 48:00d211aac2ec 113 * SERVER MessageHeaderの値
nyatla 48:00d211aac2ec 114 * 40文字以内であること。
nyatla 48:00d211aac2ec 115 */
nyatla 48:00d211aac2ec 116 #define SERVER_MESSAGE_HEADER "MiMic/1.4;UPnP/1.0;MiMicUPnP/0.1"
nyatla 48:00d211aac2ec 117
nyatla 48:00d211aac2ec 118
nyatla 48:00d211aac2ec 119 /**
nyatla 48:00d211aac2ec 120 * MsearchResponseを格納したTxパケットをAllocする。
nyatla 48:00d211aac2ec 121 * @param i_st
nyatla 48:00d211aac2ec 122 * ST値
nyatla 48:00d211aac2ec 123 * @param i_udn
nyatla 48:00d211aac2ec 124 * DDESCのUDNの値
nyatla 48:00d211aac2ec 125 * @param i_usn
nyatla 48:00d211aac2ec 126 * USNのサフィックスパラメータ
nyatla 48:00d211aac2ec 127 * @return
nyatla 48:00d211aac2ec 128 * MsearchResponseを格納したTXメモリ
nyatla 48:00d211aac2ec 129 */
nyatla 48:00d211aac2ec 130 static void* allocMsearchResponeTx(
nyatla 48:00d211aac2ec 131 NyLPC_TcSsdpSocket_t* i_inst,
nyatla 48:00d211aac2ec 132 const NyLPC_TChar* i_st,
nyatla 48:00d211aac2ec 133 const NyLPC_TChar* i_udn,
nyatla 48:00d211aac2ec 134 const NyLPC_TChar* i_usn,
nyatla 48:00d211aac2ec 135 NyLPC_TUInt16 i_st_len,
nyatla 48:00d211aac2ec 136 NyLPC_TInt16* o_len)
nyatla 48:00d211aac2ec 137 {
nyatla 48:00d211aac2ec 138 NyLPC_TChar* obuf;
nyatla 48:00d211aac2ec 139 NyLPC_TUInt16 l;
nyatla 48:00d211aac2ec 140 NyLPC_TUInt16 len_usn=(NyLPC_TUInt16)(i_usn!=NULL?strlen(i_usn):0);
nyatla 48:00d211aac2ec 141 NyLPC_TUInt16 len_udn=(NyLPC_TUInt16)strlen(i_udn);
nyatla 48:00d211aac2ec 142 NyLPC_TUInt16 len_location=(NyLPC_TUInt16)strlen(i_inst->location_path);
nyatla 48:00d211aac2ec 143
nyatla 48:00d211aac2ec 144 // //161Byte
nyatla 48:00d211aac2ec 145 // "HTTP/1.1 200 OK\r\n" //15+2=17
nyatla 48:00d211aac2ec 146 // "CACHE-CONTROL: max-age = nnnn\r\n" //29+2=31
nyatla 48:00d211aac2ec 147 // "SERVER: [:40byte:]\r\n" //8+40+2=50
nyatla 48:00d211aac2ec 148 // "EXT: \r\n" //5+2 = 7
nyatla 48:00d211aac2ec 149 // "LOCATION: http://xxx.xxx.xxx.xxx:nnnnn/%s/d.xml\r\n" //34+2=46
nyatla 48:00d211aac2ec 150 // "USN: %s%s\r\n" //5+2=7
nyatla 48:00d211aac2ec 151 // "ST: %s\r\n\r\n" //4+4=8
nyatla 48:00d211aac2ec 152 l=166+len_location+len_usn+len_udn+i_st_len;
nyatla 48:00d211aac2ec 153 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->super),l,&l,TIMEOUT_IN_MS);
nyatla 48:00d211aac2ec 154
nyatla 48:00d211aac2ec 155 if(obuf==NULL){
nyatla 48:00d211aac2ec 156 return NULL;
nyatla 48:00d211aac2ec 157 }
nyatla 48:00d211aac2ec 158 //必要なメモリサイズを確保できた?
nyatla 48:00d211aac2ec 159 if(l<161+len_location+len_usn+len_udn+i_st_len)
nyatla 48:00d211aac2ec 160 {
nyatla 48:00d211aac2ec 161 NyLPC_cUdpSocket_releaseSendBuf(&i_inst->super,obuf);
nyatla 48:00d211aac2ec 162 return NULL;
nyatla 48:00d211aac2ec 163 }
nyatla 48:00d211aac2ec 164 //ワーク変数lの再初期化
nyatla 48:00d211aac2ec 165 l=0;
nyatla 48:00d211aac2ec 166 strcpy(obuf,
nyatla 48:00d211aac2ec 167 "HTTP/1.1 200 OK\r\n"
nyatla 48:00d211aac2ec 168 "CACHE-CONTROL: max-age = 300\r\n"
nyatla 48:00d211aac2ec 169 "SERVER: "SERVER_MESSAGE_HEADER"\r\n"
nyatla 48:00d211aac2ec 170 "EXT: \r\n"
nyatla 48:00d211aac2ec 171 "LOCATION: http://");
nyatla 48:00d211aac2ec 172 l+=strlen(obuf);
nyatla 48:00d211aac2ec 173 //IP addr:port\r\n
nyatla 48:00d211aac2ec 174 l+=printIpAddr(NyLPC_cUdpSocket_getSockIP(&i_inst->super),obuf+l);
nyatla 48:00d211aac2ec 175 *(obuf+l)=':';
nyatla 48:00d211aac2ec 176 l+=1+NyLPC_itoa(i_inst->location_port,obuf+l+1,10);
nyatla 48:00d211aac2ec 177 *(obuf+l)='/';l++;
nyatla 48:00d211aac2ec 178 memcpy(obuf+l,i_inst->location_path,len_location);l+=len_location;
nyatla 48:00d211aac2ec 179 memcpy(obuf+l,"/d.xml",6);l+=6;
nyatla 48:00d211aac2ec 180 *(obuf+l+0)='\r';
nyatla 48:00d211aac2ec 181 *(obuf+l+1)='\n';
nyatla 48:00d211aac2ec 182 l+=2;
nyatla 48:00d211aac2ec 183 //USN: uuid:xxx
nyatla 48:00d211aac2ec 184 memcpy(obuf+l,"USN: ",5); l+=5;
nyatla 48:00d211aac2ec 185 memcpy(obuf+l,i_udn,len_udn); l+=len_udn; //uuid:xxx
nyatla 48:00d211aac2ec 186 if(i_usn!=NULL){
nyatla 48:00d211aac2ec 187 *(obuf+l+0)=':';
nyatla 48:00d211aac2ec 188 *(obuf+l+1)=':';
nyatla 48:00d211aac2ec 189 l+=2;
nyatla 48:00d211aac2ec 190 memcpy(obuf+l,i_usn,len_usn);l+=len_usn; //usn:xxx
nyatla 48:00d211aac2ec 191 }
nyatla 48:00d211aac2ec 192 *(obuf+l+0)='\r';
nyatla 48:00d211aac2ec 193 *(obuf+l+1)='\n';
nyatla 48:00d211aac2ec 194 l+=2;
nyatla 48:00d211aac2ec 195 //ST
nyatla 48:00d211aac2ec 196 memcpy(obuf+l,"ST: ",4); l+=4;
nyatla 48:00d211aac2ec 197 memcpy(obuf+l,i_st,i_st_len);l+=i_st_len;
nyatla 48:00d211aac2ec 198 memcpy(obuf+l,"\r\n\r\n",4); l+=4;
nyatla 48:00d211aac2ec 199 *o_len=l;
nyatla 48:00d211aac2ec 200 return obuf;
nyatla 48:00d211aac2ec 201 }
nyatla 48:00d211aac2ec 202
nyatla 48:00d211aac2ec 203
nyatla 48:00d211aac2ec 204 /**
nyatla 48:00d211aac2ec 205 * MsearchResponseを格納したTxパケットをAllocする。
nyatla 48:00d211aac2ec 206 * @param i_udn
nyatla 48:00d211aac2ec 207 * udn
nyatla 48:00d211aac2ec 208 * @param i_udn
nyatla 48:00d211aac2ec 209 * DDESCのUDNの値
nyatla 48:00d211aac2ec 210 * @param i_usn
nyatla 48:00d211aac2ec 211 * USNのサフィックスパラメータ
nyatla 48:00d211aac2ec 212 * @return
nyatla 48:00d211aac2ec 213 * MsearchResponseを格納したTXメモリ
nyatla 48:00d211aac2ec 214 */
nyatla 48:00d211aac2ec 215 static void* allocNotifyTx(
nyatla 48:00d211aac2ec 216 NyLPC_TcSsdpSocket_t* i_inst,
nyatla 48:00d211aac2ec 217 const NyLPC_TChar* i_udn,
nyatla 48:00d211aac2ec 218 const NyLPC_TChar* i_usn,
nyatla 48:00d211aac2ec 219 NyLPC_TInt16* o_len)
nyatla 48:00d211aac2ec 220 {
nyatla 48:00d211aac2ec 221 NyLPC_TChar* obuf;
nyatla 48:00d211aac2ec 222 NyLPC_TUInt16 l,l2;
nyatla 48:00d211aac2ec 223 NyLPC_TUInt16 len_usn=(NyLPC_TUInt16)(i_usn!=NULL?strlen(i_usn):0);
nyatla 48:00d211aac2ec 224 NyLPC_TUInt16 len_udn=(NyLPC_TUInt16)strlen(i_udn);
nyatla 48:00d211aac2ec 225 NyLPC_TUInt16 len_location=(NyLPC_TUInt16)strlen(i_inst->location_path);
nyatla 50:35e765380772 226
nyatla 48:00d211aac2ec 227 // //193Byte
nyatla 48:00d211aac2ec 228 // "NOTIFY * HTTP/1.1\r\n" //15+2=17
nyatla 48:00d211aac2ec 229 // "HOST: 239.255.255.250:1900\r\n" //26+2=28
nyatla 48:00d211aac2ec 230 // "CACHE-CONTROL: max-age = 1800\r\n" //29+2=31
nyatla 48:00d211aac2ec 231 // "SERVER: [:40byte:]\r\n" //8+40+2=50
nyatla 48:00d211aac2ec 232 // "NTS: ssdp:alive\r\n" //14+2 =17
nyatla 48:00d211aac2ec 233 // "LOCATION: http://xxx.xxx.xxx.xxx:nnnnn/%s/d.xml\r\n"//44+2=46
nyatla 48:00d211aac2ec 234 // "USN: %s%s\r\n" //5+2=7
nyatla 48:00d211aac2ec 235 // "NT: %s\r\n\r\n" //4+4=8
nyatla 48:00d211aac2ec 236 l2=204+len_location+len_usn+len_udn+(len_usn>0?len_usn:len_udn);
nyatla 48:00d211aac2ec 237 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->super),l2,&l,TIMEOUT_IN_MS);
nyatla 48:00d211aac2ec 238 if(obuf==NULL){
nyatla 48:00d211aac2ec 239 return NULL;
nyatla 48:00d211aac2ec 240 }
nyatla 48:00d211aac2ec 241 //必要なメモリサイズを確保できた?
nyatla 48:00d211aac2ec 242 if(l<l2)
nyatla 48:00d211aac2ec 243 {
nyatla 48:00d211aac2ec 244 NyLPC_cUdpSocket_releaseSendBuf(&i_inst->super,obuf);
nyatla 48:00d211aac2ec 245 return NULL;
nyatla 48:00d211aac2ec 246 }
nyatla 48:00d211aac2ec 247 //ワーク変数lの再初期化
nyatla 48:00d211aac2ec 248 l=0;
nyatla 48:00d211aac2ec 249 strcpy(obuf,
nyatla 48:00d211aac2ec 250 "NOTIFY * HTTP/1.1\r\n"
nyatla 48:00d211aac2ec 251 "HOST: 239.255.255.250:1900\r\n"
nyatla 48:00d211aac2ec 252 "CACHE-CONTROL: max-age = 300\r\n"
nyatla 48:00d211aac2ec 253 "SERVER: "SERVER_MESSAGE_HEADER"\r\n"
nyatla 48:00d211aac2ec 254 "NTS: ssdp:alive\r\n"
nyatla 48:00d211aac2ec 255 "LOCATION: http://");
nyatla 48:00d211aac2ec 256 l+=strlen(obuf);
nyatla 48:00d211aac2ec 257 //IP addr:port\r\n
nyatla 48:00d211aac2ec 258 l+=printIpAddr(NyLPC_cUdpSocket_getSockIP(&i_inst->super),obuf+l);
nyatla 48:00d211aac2ec 259 *(obuf+l)=':';
nyatla 48:00d211aac2ec 260 l+=1+NyLPC_itoa(i_inst->location_port,obuf+l+1,10);
nyatla 48:00d211aac2ec 261 *(obuf+l)='/';l++;
nyatla 48:00d211aac2ec 262 memcpy(obuf+l,i_inst->location_path,len_location);l+=len_location;
nyatla 48:00d211aac2ec 263 memcpy(obuf+l,"/d.xml",6);l+=6;
nyatla 48:00d211aac2ec 264 *(obuf+l+0)='\r';
nyatla 48:00d211aac2ec 265 *(obuf+l+1)='\n';
nyatla 48:00d211aac2ec 266 l+=2;
nyatla 48:00d211aac2ec 267 //USN: uuid:xxx
nyatla 48:00d211aac2ec 268 memcpy(obuf+l,"USN: ",5); l+=5;
nyatla 48:00d211aac2ec 269 memcpy(obuf+l,i_udn,len_udn); l+=len_udn; //uuid:xxx
nyatla 48:00d211aac2ec 270 if(i_usn!=NULL){
nyatla 48:00d211aac2ec 271 *(obuf+l+0)=':';
nyatla 48:00d211aac2ec 272 *(obuf+l+1)=':';
nyatla 48:00d211aac2ec 273 l+=2;
nyatla 48:00d211aac2ec 274 memcpy(obuf+l,i_usn,len_usn);l+=len_usn; //usn:xxx
nyatla 48:00d211aac2ec 275 }
nyatla 48:00d211aac2ec 276 *(obuf+l+0)='\r';
nyatla 48:00d211aac2ec 277 *(obuf+l+1)='\n';
nyatla 48:00d211aac2ec 278 l+=2;
nyatla 48:00d211aac2ec 279 //NT
nyatla 48:00d211aac2ec 280 memcpy(obuf+l,"NT: ",4); l+=4;
nyatla 48:00d211aac2ec 281 if(len_usn>0){
nyatla 48:00d211aac2ec 282 memcpy(obuf+l,i_usn,len_usn);l+=len_usn;
nyatla 48:00d211aac2ec 283 }else{
nyatla 48:00d211aac2ec 284 memcpy(obuf+l,i_udn,len_udn);l+=len_udn;
nyatla 48:00d211aac2ec 285 }
nyatla 48:00d211aac2ec 286 memcpy(obuf+l,"\r\n\r\n",4); l+=4;
nyatla 48:00d211aac2ec 287 *o_len=l;
nyatla 48:00d211aac2ec 288 return obuf;
nyatla 48:00d211aac2ec 289 }
nyatla 48:00d211aac2ec 290
nyatla 48:00d211aac2ec 291
nyatla 48:00d211aac2ec 292 static NyLPC_TBool messageHandler(NyLPC_TcHttpBasicHeaderParser_t* i_inst,const NyLPC_TChar* i_name,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out)
nyatla 48:00d211aac2ec 293 {
nyatla 48:00d211aac2ec 294 struct TMSearchHeader* header=(struct TMSearchHeader*)o_out;
nyatla 48:00d211aac2ec 295 switch(header->st)
nyatla 48:00d211aac2ec 296 {
nyatla 48:00d211aac2ec 297 case PARSE_NULL:
nyatla 48:00d211aac2ec 298 if(NyLPC_stricmp(i_name,"ST")==0){
nyatla 48:00d211aac2ec 299 //mode==ST
nyatla 48:00d211aac2ec 300 header->st=PARSE_ST;
nyatla 48:00d211aac2ec 301 header->result.st_str=NULL;
nyatla 48:00d211aac2ec 302 }else if(NyLPC_stricmp(i_name,"MAN")==0){
nyatla 48:00d211aac2ec 303 //mode=MAN
nyatla 48:00d211aac2ec 304 header->st=PARSE_MAN;
nyatla 48:00d211aac2ec 305 header->result.man_str=NULL;
nyatla 48:00d211aac2ec 306 }else{
nyatla 48:00d211aac2ec 307 header->st=PARSE_UNKNOWN;
nyatla 48:00d211aac2ec 308 //無視
nyatla 48:00d211aac2ec 309 }
nyatla 48:00d211aac2ec 310 break;
nyatla 48:00d211aac2ec 311 case PARSE_ST:
nyatla 48:00d211aac2ec 312 if((header->result.st_str==NULL) && (i_c!=HTTP_SP)){
nyatla 48:00d211aac2ec 313 header->result.st_str=header->_rpos;
nyatla 48:00d211aac2ec 314 }
nyatla 48:00d211aac2ec 315 if(i_c=='\0')
nyatla 48:00d211aac2ec 316 {
nyatla 48:00d211aac2ec 317 header->result.st_len=header->_rpos-header->result.st_str-1;
nyatla 48:00d211aac2ec 318 header->st=PARSE_NULL;
nyatla 48:00d211aac2ec 319 }
nyatla 48:00d211aac2ec 320 break;
nyatla 48:00d211aac2ec 321 case PARSE_MAN:
nyatla 48:00d211aac2ec 322 if((header->result.man_str==NULL) && (i_c!=HTTP_SP)){
nyatla 48:00d211aac2ec 323 header->result.man_str=header->_rpos;
nyatla 48:00d211aac2ec 324 }
nyatla 48:00d211aac2ec 325 if(i_c=='\0'){
nyatla 48:00d211aac2ec 326 header->result.man_len=header->_rpos-header->result.man_str-1;
nyatla 48:00d211aac2ec 327 header->st=PARSE_NULL;
nyatla 48:00d211aac2ec 328 }
nyatla 48:00d211aac2ec 329 break;
nyatla 48:00d211aac2ec 330 case PARSE_UNKNOWN:
nyatla 48:00d211aac2ec 331 default:
nyatla 48:00d211aac2ec 332 if(i_c=='\0'){
nyatla 48:00d211aac2ec 333 header->st=PARSE_NULL;
nyatla 48:00d211aac2ec 334 }
nyatla 48:00d211aac2ec 335 break;
nyatla 48:00d211aac2ec 336 }
nyatla 48:00d211aac2ec 337 return NyLPC_TBool_TRUE;
nyatla 48:00d211aac2ec 338 }
nyatla 48:00d211aac2ec 339
nyatla 48:00d211aac2ec 340 /**
nyatla 48:00d211aac2ec 341 * デフォルトハンドラ
nyatla 48:00d211aac2ec 342 */
nyatla 48:00d211aac2ec 343 static const struct NyLPC_TcHttpBasicHeaderParser_Handler handler=
nyatla 48:00d211aac2ec 344 {
nyatla 48:00d211aac2ec 345 messageHandler,
nyatla 48:00d211aac2ec 346 urlHandler
nyatla 48:00d211aac2ec 347 };
nyatla 48:00d211aac2ec 348
nyatla 48:00d211aac2ec 349 static NyLPC_TBool parseHeader(struct TMSearchHeader* i_out,const void* i_rx,NyLPC_TInt16 i_rx_size)
nyatla 48:00d211aac2ec 350 {
nyatla 48:00d211aac2ec 351 NyLPC_TInt16 i;
nyatla 48:00d211aac2ec 352 NyLPC_TcHttpBasicHeaderParser_t parser;
nyatla 48:00d211aac2ec 353 //headerの初期化
nyatla 48:00d211aac2ec 354 i_out->st=PARSE_NULL;
nyatla 48:00d211aac2ec 355 i_out->result.st_str=NULL;
nyatla 48:00d211aac2ec 356 i_out->result.man_str=NULL;
nyatla 48:00d211aac2ec 357 NyLPC_cHttpBasicHeaderParser_initialize(&parser,&handler);
nyatla 48:00d211aac2ec 358 NyLPC_cHttpBasicHeaderParser_parseInit(&parser,&(i_out->super));
nyatla 48:00d211aac2ec 359 for(i=0;i<i_rx_size;i++){
nyatla 48:00d211aac2ec 360 i_out->_rpos=((const char*)(i_rx))+i;
nyatla 48:00d211aac2ec 361 if(NyLPC_cHttpBasicHeaderParser_parseChar(&parser,i_out->_rpos,1,&(i_out->super))<0){
nyatla 48:00d211aac2ec 362 NyLPC_cHttpBasicHeaderParser_finalize(&parser);
nyatla 48:00d211aac2ec 363 return NyLPC_TBool_FALSE;//ERROR
nyatla 48:00d211aac2ec 364 }
nyatla 48:00d211aac2ec 365 }
nyatla 48:00d211aac2ec 366 NyLPC_cHttpBasicHeaderParser_parseFinish(&parser,&(i_out->super));
nyatla 48:00d211aac2ec 367 NyLPC_cHttpBasicHeaderParser_finalize(&parser);
nyatla 48:00d211aac2ec 368 return NyLPC_TBool_TRUE;//OK
nyatla 48:00d211aac2ec 369 }
nyatla 48:00d211aac2ec 370
nyatla 48:00d211aac2ec 371 static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info)
nyatla 48:00d211aac2ec 372 {
nyatla 48:00d211aac2ec 373 //パケット解析
nyatla 48:00d211aac2ec 374 void* tx;
nyatla 48:00d211aac2ec 375 struct TMSearchHeader header;
nyatla 48:00d211aac2ec 376 NyLPC_TInt16 tx_len;
nyatla 48:00d211aac2ec 377 NyLPC_TInt8 i,i2;
nyatla 48:00d211aac2ec 378 NyLPC_TcSsdpSocket_t* sock=(NyLPC_TcSsdpSocket_t*)i_inst;
nyatla 48:00d211aac2ec 379 if(!parseHeader(&header,i_buf,i_info->size)){
nyatla 48:00d211aac2ec 380 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 381 }
nyatla 48:00d211aac2ec 382 //resultチェック
nyatla 48:00d211aac2ec 383 if(header.result.man_str==NULL || header.result.st_str==NULL){
nyatla 48:00d211aac2ec 384 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 385 }
nyatla 48:00d211aac2ec 386 //Methodチェック
nyatla 48:00d211aac2ec 387 if(header.super.startline.req.method!=NyLPC_THttpMethodType_M_SEARCH){
nyatla 48:00d211aac2ec 388 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 389 }
nyatla 48:00d211aac2ec 390
nyatla 48:00d211aac2ec 391 //MANチェック
nyatla 48:00d211aac2ec 392 if(strncmp("\"ssdp:discover\"",header.result.man_str,15)!=0){
nyatla 48:00d211aac2ec 393 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 394 }
nyatla 48:00d211aac2ec 395 //STによる処理分岐
nyatla 48:00d211aac2ec 396 if(strncmp("ssdp:all",header.result.st_str,8)==0){
nyatla 48:00d211aac2ec 397 tx=allocMsearchResponeTx(
nyatla 48:00d211aac2ec 398 sock,header.result.st_str,
nyatla 48:00d211aac2ec 399 sock->ref_device_record[0]->udn,STR_UPNP_ROOT_DEVICE,
nyatla 48:00d211aac2ec 400 header.result.st_len,
nyatla 48:00d211aac2ec 401 &tx_len);
nyatla 48:00d211aac2ec 402 if(tx==NULL){
nyatla 48:00d211aac2ec 403 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 404 }
nyatla 48:00d211aac2ec 405 if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 406 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 407 }
nyatla 48:00d211aac2ec 408 //全デバイスの送信
nyatla 48:00d211aac2ec 409 for(i=0;i<sock->number_of_device;i++){
nyatla 48:00d211aac2ec 410 tx=allocMsearchResponeTx(
nyatla 48:00d211aac2ec 411 sock,header.result.st_str,
nyatla 48:00d211aac2ec 412 sock->ref_device_record[i]->udn,sock->ref_device_record[i]->device_type,
nyatla 48:00d211aac2ec 413 header.result.st_len,
nyatla 48:00d211aac2ec 414 &tx_len);
nyatla 48:00d211aac2ec 415 if(tx==NULL){
nyatla 48:00d211aac2ec 416 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 417 }
nyatla 48:00d211aac2ec 418 if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 419 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 420 }
nyatla 48:00d211aac2ec 421 for(i2=0;i2<sock->ref_device_record[i]->number_of_service;i2++){
nyatla 48:00d211aac2ec 422 //serviceに一致
nyatla 48:00d211aac2ec 423 tx=allocMsearchResponeTx(
nyatla 48:00d211aac2ec 424 sock,header.result.st_str,
nyatla 48:00d211aac2ec 425 sock->ref_device_record[i]->udn,sock->ref_device_record[i]->services[i2].service_type,
nyatla 48:00d211aac2ec 426 header.result.st_len,
nyatla 48:00d211aac2ec 427 &tx_len);
nyatla 48:00d211aac2ec 428 if(tx==NULL){
nyatla 48:00d211aac2ec 429 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 430 }
nyatla 48:00d211aac2ec 431 if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 432 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 433 }
nyatla 48:00d211aac2ec 434 }
nyatla 48:00d211aac2ec 435 }
nyatla 48:00d211aac2ec 436 }else if(strncmp("uuid:",header.result.st_str,5)==0){
nyatla 48:00d211aac2ec 437 //UDNの一致するデバイスの送信
nyatla 48:00d211aac2ec 438 NyLPC_TInt16 i;
nyatla 48:00d211aac2ec 439 for(i=sock->number_of_device-1;i>=0;i--){
nyatla 48:00d211aac2ec 440 if(strncmp(header.result.st_str,sock->ref_device_record[i]->udn,header.result.st_len)==0){
nyatla 48:00d211aac2ec 441 //UDN一致
nyatla 48:00d211aac2ec 442 tx=allocMsearchResponeTx(
nyatla 48:00d211aac2ec 443 sock,header.result.st_str,
nyatla 48:00d211aac2ec 444 sock->ref_device_record[i]->udn,NULL,
nyatla 48:00d211aac2ec 445 header.result.st_len,
nyatla 48:00d211aac2ec 446 &tx_len);
nyatla 48:00d211aac2ec 447 if(tx==NULL){
nyatla 48:00d211aac2ec 448 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 449 }
nyatla 48:00d211aac2ec 450 if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 451 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 452 }
nyatla 48:00d211aac2ec 453 break;//送信処理終了
nyatla 48:00d211aac2ec 454 }
nyatla 48:00d211aac2ec 455 }
nyatla 48:00d211aac2ec 456 }else if(strncmp(STR_UPNP_ROOT_DEVICE,header.result.st_str,15)==0){
nyatla 48:00d211aac2ec 457 //rootDeviceはdevice0
nyatla 48:00d211aac2ec 458 tx=allocMsearchResponeTx(
nyatla 48:00d211aac2ec 459 sock,header.result.st_str,
nyatla 48:00d211aac2ec 460 sock->ref_device_record[0]->udn,sock->ref_device_record[0]->device_type,
nyatla 48:00d211aac2ec 461 header.result.st_len,
nyatla 48:00d211aac2ec 462 &tx_len);
nyatla 48:00d211aac2ec 463 if(tx==NULL){
nyatla 48:00d211aac2ec 464 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 465 }
nyatla 48:00d211aac2ec 466 if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 467 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 468 }
nyatla 48:00d211aac2ec 469 }else if(strncmp("urn:",header.result.st_str,4)==0){
nyatla 48:00d211aac2ec 470 for(i=0;i<sock->number_of_device;i++){
nyatla 48:00d211aac2ec 471 //urn一致チェック
nyatla 48:00d211aac2ec 472 if(strncmp(sock->ref_device_record[i]->device_type,header.result.st_str,header.result.st_len)==0){
nyatla 48:00d211aac2ec 473 //deviceに一致
nyatla 48:00d211aac2ec 474 tx=allocMsearchResponeTx(
nyatla 48:00d211aac2ec 475 sock,header.result.st_str,
nyatla 48:00d211aac2ec 476 sock->ref_device_record[i]->udn,sock->ref_device_record[i]->device_type,
nyatla 48:00d211aac2ec 477 header.result.st_len,
nyatla 48:00d211aac2ec 478 &tx_len);
nyatla 48:00d211aac2ec 479 if(tx==NULL){
nyatla 48:00d211aac2ec 480 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 481 }
nyatla 48:00d211aac2ec 482 if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 483 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 484 }
nyatla 48:00d211aac2ec 485 continue;
nyatla 48:00d211aac2ec 486 }
nyatla 48:00d211aac2ec 487 for(i2=0;i2<sock->ref_device_record[i]->number_of_service;i2++){
nyatla 48:00d211aac2ec 488 if(strncmp(sock->ref_device_record[i]->services[i2].service_type,header.result.st_str,header.result.st_len)==0){
nyatla 48:00d211aac2ec 489 //serviceに一致
nyatla 48:00d211aac2ec 490 tx=allocMsearchResponeTx(
nyatla 48:00d211aac2ec 491 sock,header.result.st_str,
nyatla 48:00d211aac2ec 492 sock->ref_device_record[i]->udn,sock->ref_device_record[i]->services[i2].service_type,
nyatla 48:00d211aac2ec 493 header.result.st_len,
nyatla 48:00d211aac2ec 494 &tx_len);
nyatla 48:00d211aac2ec 495 if(tx==NULL){
nyatla 48:00d211aac2ec 496 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 497 }
nyatla 48:00d211aac2ec 498 if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 499 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 500 }
nyatla 48:00d211aac2ec 501 }
nyatla 48:00d211aac2ec 502 }
nyatla 48:00d211aac2ec 503 }
nyatla 48:00d211aac2ec 504 }
nyatla 48:00d211aac2ec 505 //正常終了
nyatla 48:00d211aac2ec 506 return NyLPC_TBool_FALSE;
nyatla 48:00d211aac2ec 507 ERROR2:
nyatla 48:00d211aac2ec 508 NyLPC_cUdpSocket_releaseSendBuf(i_inst,tx);
nyatla 48:00d211aac2ec 509 ERROR1:
nyatla 48:00d211aac2ec 510 return NyLPC_TBool_FALSE;
nyatla 48:00d211aac2ec 511 }
nyatla 48:00d211aac2ec 512
nyatla 48:00d211aac2ec 513 #define SSDP_NOTIFY_INTERVAL 240*1000 //300*0.8*1000
nyatla 48:00d211aac2ec 514 #define FLAG_ORDER_START_SERVICE 0
nyatla 48:00d211aac2ec 515 #define FLAG_ORDER_STOP_SERVICE 1
nyatla 48:00d211aac2ec 516 #define FLAG_IS_SERVICE_RUNNING 2
nyatla 48:00d211aac2ec 517
nyatla 48:00d211aac2ec 518 static void onPeriodic(NyLPC_TcUdpSocket_t* i_inst)
nyatla 48:00d211aac2ec 519 {
nyatla 48:00d211aac2ec 520 NyLPC_TcSsdpSocket_t* sock=(NyLPC_TcSsdpSocket_t*)i_inst;
nyatla 48:00d211aac2ec 521 if(NyLPC_TUInt8_isBitOn(sock->_flags,FLAG_IS_SERVICE_RUNNING)){
nyatla 48:00d211aac2ec 522 //実行中
nyatla 48:00d211aac2ec 523 //停止要求着てる?
nyatla 48:00d211aac2ec 524 if(NyLPC_TUInt8_isBitOn(sock->_flags,FLAG_ORDER_STOP_SERVICE))
nyatla 48:00d211aac2ec 525 {
nyatla 48:00d211aac2ec 526 //状態変更
nyatla 48:00d211aac2ec 527 NyLPC_TUInt8_unsetBit(sock->_flags,FLAG_IS_SERVICE_RUNNING);
nyatla 48:00d211aac2ec 528 //要求フラグクリア
nyatla 48:00d211aac2ec 529 NyLPC_TUInt8_unsetBit(sock->_flags,FLAG_ORDER_STOP_SERVICE);
nyatla 48:00d211aac2ec 530 //@bug ByeBye送信しろ
nyatla 48:00d211aac2ec 531 }else if(NyLPC_cStopwatch_isExpired(&sock->_periodic_sw)){
nyatla 48:00d211aac2ec 532 //Notify送信
nyatla 48:00d211aac2ec 533 NyLPC_cSsdpSocket_notify(sock);
nyatla 48:00d211aac2ec 534 //タイマ再始動
nyatla 48:00d211aac2ec 535 NyLPC_cStopwatch_startExpire(&sock->_periodic_sw,SSDP_NOTIFY_INTERVAL);
nyatla 48:00d211aac2ec 536 }
nyatla 48:00d211aac2ec 537 }else{
nyatla 48:00d211aac2ec 538 //停止中
nyatla 48:00d211aac2ec 539 //開始要求着てる?
nyatla 48:00d211aac2ec 540 if(NyLPC_TUInt8_isBitOn(sock->_flags,FLAG_ORDER_START_SERVICE))
nyatla 48:00d211aac2ec 541 {
nyatla 48:00d211aac2ec 542 //状態変更
nyatla 48:00d211aac2ec 543 NyLPC_TUInt8_setBit(sock->_flags,FLAG_IS_SERVICE_RUNNING);
nyatla 48:00d211aac2ec 544 //要求フラグクリア
nyatla 48:00d211aac2ec 545 NyLPC_TUInt8_unsetBit(sock->_flags,FLAG_ORDER_START_SERVICE);
nyatla 48:00d211aac2ec 546 //次回expireするように
nyatla 48:00d211aac2ec 547 NyLPC_cStopwatch_startExpire(&sock->_periodic_sw,SSDP_NOTIFY_INTERVAL);
nyatla 48:00d211aac2ec 548 }
nyatla 48:00d211aac2ec 549 }
nyatla 48:00d211aac2ec 550 }
nyatla 48:00d211aac2ec 551
nyatla 48:00d211aac2ec 552 /**
nyatla 48:00d211aac2ec 553 * デバイスツリーを展開する。
nyatla 48:00d211aac2ec 554 */
nyatla 48:00d211aac2ec 555 static void expandDeviceTree(NyLPC_TcSsdpSocket_t* i_inst,const struct NyLPC_TUPnPDevDescDevice* i_dev)
nyatla 48:00d211aac2ec 556 {
nyatla 48:00d211aac2ec 557 NyLPC_TUInt16 i;
nyatla 48:00d211aac2ec 558 if(i_inst->number_of_device>=NyLPC_TcSsdpSocket_MAX_DEVICES){
nyatla 48:00d211aac2ec 559 NyLPC_Warning();//
nyatla 48:00d211aac2ec 560 }
nyatla 48:00d211aac2ec 561 i_inst->ref_device_record[i_inst->number_of_device]=i_dev;
nyatla 48:00d211aac2ec 562 i_inst->number_of_device++;
nyatla 48:00d211aac2ec 563 for(i=0;i<i_dev->number_of_devices;i++){
nyatla 48:00d211aac2ec 564 expandDeviceTree(i_inst,i_dev->devices[i]);
nyatla 48:00d211aac2ec 565 }
nyatla 48:00d211aac2ec 566 return;
nyatla 48:00d211aac2ec 567 }
nyatla 48:00d211aac2ec 568
nyatla 48:00d211aac2ec 569 void NyLPC_cSsdpSocket_initialize(
nyatla 48:00d211aac2ec 570 NyLPC_TcSsdpSocket_t* i_inst,
nyatla 48:00d211aac2ec 571 const struct NyLPC_TUPnPDevDescDevice* i_ref_dev_record,
nyatla 48:00d211aac2ec 572 NyLPC_TUInt16 i_server_port,const NyLPC_TChar* i_ref_location_path)
nyatla 48:00d211aac2ec 573 {
nyatla 48:00d211aac2ec 574 NyLPC_cUdpSocket_initialize(&(i_inst->super),1900,NULL,0);
nyatla 48:00d211aac2ec 575 NyLPC_cUdpSocket_setOnRxHandler(&(i_inst->super),onPacket);
nyatla 48:00d211aac2ec 576 NyLPC_cUdpSocket_setOnPeriodicHandler(&(i_inst->super),onPeriodic);
nyatla 48:00d211aac2ec 577
nyatla 48:00d211aac2ec 578 NyLPC_cUdpSocket_joinMulticast(&(i_inst->super),&SSDP_MCAST_IPADDR);
nyatla 48:00d211aac2ec 579 i_inst->_flags=0;
nyatla 48:00d211aac2ec 580 NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw));
nyatla 50:35e765380772 581 i_inst->number_of_device=0;
nyatla 48:00d211aac2ec 582 expandDeviceTree(i_inst,i_ref_dev_record);
nyatla 48:00d211aac2ec 583 i_inst->location_port=i_server_port;
nyatla 48:00d211aac2ec 584 i_inst->location_path=i_ref_location_path;
nyatla 48:00d211aac2ec 585 }
nyatla 48:00d211aac2ec 586 void NyLPC_cSsdpSocket_finalize(NyLPC_TcSsdpSocket_t* i_inst)
nyatla 48:00d211aac2ec 587 {
nyatla 48:00d211aac2ec 588 NyLPC_cStopwatch_finalize(&(i_inst->_periodic_sw));
nyatla 48:00d211aac2ec 589 NyLPC_cUdpSocket_finalize(&(i_inst->super));
nyatla 48:00d211aac2ec 590 }
nyatla 48:00d211aac2ec 591
nyatla 48:00d211aac2ec 592 void NyLPC_cSsdpSocket_start(NyLPC_TcSsdpSocket_t* i_inst)
nyatla 48:00d211aac2ec 593 {
nyatla 48:00d211aac2ec 594 //Notifyを3回送信
nyatla 48:00d211aac2ec 595 NyLPC_TInt16 i;
nyatla 48:00d211aac2ec 596 for(i=0;i<3;i++){
nyatla 48:00d211aac2ec 597 NyLPC_cSsdpSocket_notify(i_inst);
nyatla 48:00d211aac2ec 598 NyLPC_cThread_sleep(1000);
nyatla 48:00d211aac2ec 599 }
nyatla 48:00d211aac2ec 600
nyatla 48:00d211aac2ec 601 //ストップウォッチの開始要求
nyatla 48:00d211aac2ec 602 NyLPC_TUInt8_setBit(i_inst->_flags,FLAG_ORDER_START_SERVICE);
nyatla 48:00d211aac2ec 603 do{
nyatla 48:00d211aac2ec 604 NyLPC_cThread_sleep(10);
nyatla 48:00d211aac2ec 605 //開始フラグがクリアされるまでループ
nyatla 48:00d211aac2ec 606 }while(NyLPC_TUInt8_isBitOn(i_inst->_flags,FLAG_ORDER_START_SERVICE));
nyatla 48:00d211aac2ec 607 }
nyatla 48:00d211aac2ec 608 void NyLPC_cSsdpSocket_stop(NyLPC_TcSsdpSocket_t* i_inst)
nyatla 48:00d211aac2ec 609 {
nyatla 48:00d211aac2ec 610 //今は使えない。
nyatla 48:00d211aac2ec 611 NyLPC_Abort();
nyatla 48:00d211aac2ec 612 NyLPC_TUInt8_setBit(i_inst->_flags,FLAG_ORDER_STOP_SERVICE);
nyatla 48:00d211aac2ec 613 do{
nyatla 48:00d211aac2ec 614 NyLPC_cThread_sleep(10);
nyatla 48:00d211aac2ec 615 //開始フラグがクリアされるまでループ
nyatla 48:00d211aac2ec 616 }while(NyLPC_TUInt8_isBitOn(i_inst->_flags,FLAG_ORDER_STOP_SERVICE));
nyatla 48:00d211aac2ec 617 }
nyatla 48:00d211aac2ec 618 void NyLPC_cSsdpSocket_notify(NyLPC_TcSsdpSocket_t* i_inst)
nyatla 48:00d211aac2ec 619 {
nyatla 48:00d211aac2ec 620 void* tx;
nyatla 48:00d211aac2ec 621 NyLPC_TInt16 tx_len;
nyatla 48:00d211aac2ec 622 NyLPC_TUInt8 i,i2;
nyatla 48:00d211aac2ec 623 //rootdevice
nyatla 48:00d211aac2ec 624 tx=allocNotifyTx(
nyatla 48:00d211aac2ec 625 i_inst,
nyatla 48:00d211aac2ec 626 i_inst->ref_device_record[0]->udn,STR_UPNP_ROOT_DEVICE,
nyatla 48:00d211aac2ec 627 &tx_len);
nyatla 48:00d211aac2ec 628 if(tx==NULL){
nyatla 48:00d211aac2ec 629 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 630 }
nyatla 48:00d211aac2ec 631 if(!NyLPC_cUdpSocket_psend(&i_inst->super,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){
nyatla 48:00d211aac2ec 632 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 633 }
nyatla 48:00d211aac2ec 634 //all device
nyatla 48:00d211aac2ec 635 for(i=0;i<i_inst->number_of_device;i++){
nyatla 48:00d211aac2ec 636 //uuid
nyatla 48:00d211aac2ec 637 tx=allocNotifyTx(
nyatla 48:00d211aac2ec 638 i_inst,
nyatla 48:00d211aac2ec 639 i_inst->ref_device_record[i]->udn,NULL,
nyatla 48:00d211aac2ec 640 &tx_len);
nyatla 48:00d211aac2ec 641 if(tx==NULL){
nyatla 48:00d211aac2ec 642 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 643 }
nyatla 48:00d211aac2ec 644 if(!NyLPC_cUdpSocket_psend(&i_inst->super,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){
nyatla 48:00d211aac2ec 645 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 646 }
nyatla 48:00d211aac2ec 647 //devicatype
nyatla 48:00d211aac2ec 648 tx=allocNotifyTx(
nyatla 48:00d211aac2ec 649 i_inst,
nyatla 48:00d211aac2ec 650 i_inst->ref_device_record[i]->udn,i_inst->ref_device_record[i]->device_type,
nyatla 48:00d211aac2ec 651 &tx_len);
nyatla 48:00d211aac2ec 652 if(tx==NULL){
nyatla 48:00d211aac2ec 653 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 654 }
nyatla 48:00d211aac2ec 655 if(!NyLPC_cUdpSocket_psend(&i_inst->super,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){
nyatla 48:00d211aac2ec 656 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 657 }
nyatla 48:00d211aac2ec 658 for(i2=0;i2<i_inst->ref_device_record[i]->number_of_service;i2++){
nyatla 48:00d211aac2ec 659 tx=allocNotifyTx(
nyatla 48:00d211aac2ec 660 i_inst,
nyatla 48:00d211aac2ec 661 i_inst->ref_device_record[i]->udn,i_inst->ref_device_record[i]->services[i2].service_type,
nyatla 48:00d211aac2ec 662 &tx_len);
nyatla 48:00d211aac2ec 663 if(tx==NULL){
nyatla 48:00d211aac2ec 664 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 665 }
nyatla 48:00d211aac2ec 666 if(!NyLPC_cUdpSocket_psend(&i_inst->super,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){
nyatla 48:00d211aac2ec 667 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 668 }
nyatla 48:00d211aac2ec 669 }
nyatla 48:00d211aac2ec 670 }
nyatla 48:00d211aac2ec 671 return;
nyatla 48:00d211aac2ec 672 ERROR2:
nyatla 48:00d211aac2ec 673 NyLPC_cUdpSocket_releaseSendBuf(&i_inst->super,tx);
nyatla 48:00d211aac2ec 674 ERROR1:
nyatla 48:00d211aac2ec 675 return;
nyatla 48:00d211aac2ec 676 }
nyatla 48:00d211aac2ec 677