Re: [PATCH] TODO: ownership change of E911 support
Jarko Poutiainen wrote: Hi, I have agreed with Sjur that I would take ownership of this. ... - Owner: Sjur Brændeland sjur.brandel...@stericsson.com + Owner: Jarko Poutiainen jarko.poutiai...@tieto.com Acked-by: Sjur Brændeland sjur.brandel...@stericsson.com Regards /Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[RFCv3] doc: Proposal for LTE/IMS API
From: Sjur Brændeland sjur.brandel...@stericsson.com With latest changes the P-CSCF addresses from ISIM can be read from the IpMultimediaIdentity objects and the P-CSCF addresses returned as dynamic parameters for the PDN Connection are avilable in the ConnectionContext object. I have also added LocalAddress to the IMS QoS SIP PreCondiction check. The Local IP address identifies the APN, so that PreCondition check in effect can be done per IMS APN. Changes from RFC-v2: - Moved P-CSCF addresses to the IpMultimediaIdentity object - Fixed object path descriptions - IMS Registration types is now an array of strings - Fixed bad parameters to UnRegister - Added LocalAddress to PreConditionCheck - Added P-CSCF addresses to the ConnectionContext object --- doc/connman-api.txt | 18 ++ doc/ims-api.txt | 148 +++ 2 files changed, 166 insertions(+), 0 deletions(-) create mode 100644 doc/ims-api.txt diff --git a/doc/connman-api.txt b/doc/connman-api.txt index 22c59dc..314c018 100644 --- a/doc/connman-api.txt +++ b/doc/connman-api.txt @@ -249,3 +249,21 @@ Properties boolean Active [readwrite] string MessageCenter [readwrite, MMS only] Holds the MMSC setting. + + array{string} PcscfAddresses [readonly,optional] + + For ConnectionContext with Type = ims this + property holds the Domain Names or IP Addresses + of the SIP Proxy, called Proxy Call Session Control + Function (P-CSCF). + + The P-CSCF addresses are returned in EPS signaling as + part of the Default Bearer setup for the IMS APN. The + addresses may be of type IPv4 and/or IPv6. + + Related AT command: AT+CGCONTRDP + + NOTE: The P-CSCF addresses read from ISIM, is + available in the IpMultimediaIdentity + object. It is up to the IMS application to + choose the P-CSCF to use. diff --git a/doc/ims-api.txt b/doc/ims-api.txt new file mode 100644 index 000..9030457 --- /dev/null +++ b/doc/ims-api.txt @@ -0,0 +1,148 @@ +Ip Multimedia Subsystem hierarchy [experimental] += + +Serviceorg.ofono +Interface org.ofono.IpMultimediaSubsystem +Object path[variable prefix]/{modem0,modem1,...} + +Methodsdict GetProperties() + + Returns all IMS properties. See the + properties section for available properties. + + void Register(array{string} types) + + Registers an IMS Application. It must register + with at least one of the types: voice or messaging. + In future video (Conversational Video, Live + Streaming) should be added. This registration will + inform the modem's radio stack that the IMS application + has registered for Voice and/or Messaging over IMS. + This registration may impact UE Mode of operation + and the ISR feature in the radio stack. + + The registered application is tracked, if the + application exits the registration will be + automatically released. + + Possible Errors: [service].Error.InvalidArguments + + void UnRegister() + + Un-registers a previously registered IMS application. + + boolean PreConditionCheck(string Type, string PeerAddress, + uint16 PeerPort, string LocalAddress, + uint16 LocalPort) + + This method is used by the IMS application to check + if the QoS SIP precondition is fulfilled. + + The IMS application should call this method when + receiving a PreConditionChanged() signal. + The IMS Application is not allowed to start alerting + before it has confirmed that it has a voice-ready + Dedicated Bearer and QoS set up in the network. + + The legal parameter for Type currently is currently + voice only. In future video (Conversational Video, + Live Streaming) will be added. + + PeerAddress and LocalAddress can be IPv4 or IPv6 + address. PeerPort and LocalPort is the RTP port + used for the media stream. + + This method returns true if the Traffic Flow Template
Re: [RFCv2] doc: Proposal for LTE/IMS API
Hi Rémi, + boolean PreConditionCheck(string Type, string PeerAddress, + uint16 PeerPort, uint16 LocalPort) + That stuff is per context. Should it not be in the context object rather than in the IMS manager? oFono should only consider QoS information from the IMS Default and Dedicated bearers when checking the precondition. In theory there might be more than one IMS APN for a operator, but I really don't see this as a real life scenario for this. If anyone disagrees please speak out and explain... Well, I don't care if it is part of the normal context interface, or if it is an extra IMS-specific interface on the IMS context object path. But this is clearly a per-context thing so it should be in the context. I don't want to end up in a 'woops' situation down the line. And I don't trust operators not to actually implement those useless in real life scenarii... One option could be to keep it here in the IMS API but to include the Local IP Address as a argument to the PreConditionCheck. This fits quite nicely with the QoS SIP Precondition operation and can easily be used by oFono core to map to the right APN. There is still a theoretical problem here if you get the same Home Address from two IMS APN, If anyone think this is an issue I'll throw in the towel and move the PreConditionCheck to the ConnectionContext object ;-) Anyway, I think either solution would work just fine. In terms of the separation of concern i think keeping it here is the best solution, but putting it in the ConnectionContext is more flexible. I'm not going to keep arguing for this forever ;-) + array{string} PcscfAddresses [readonly] Should this be in the context object? The AT command is per CID. Would it make any sense for a network to have different P-CSCF based on the bearer? As mentioned above, I don't see why an operator would ever have more than one IMS APN. If we only have one IMS APN, then we might as well present this information here in the IMS API. How do you cope with two connections to the same APN? 3GPP TS 24.229, B.2.2.1 PDP context activation and P-CSCF discovery, describes that the P-CSCF can be provided as dynamic parameter with the PDN connection, stored on the ISIM, or by provisioning. As far as I understand this It is up to the IMS application to select which one of the P-CSCF addresses it should use. So I think the best would be to expose the P-CSCF address stored on ISIM in the IMS API, and move add the P-CSCF provided with the PDN Connection to the ConnectionContext API. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[RFCv2] doc: Proposal for LTE/IMS API
From: Sjur Brændeland sjur.brandel...@stericsson.com Thanks for lots of useful feedback from last RFC, here is my next revision on the LTE/IMS API. Comments are still very much welcome! Changes from RFC-V1: - Renamed IMS to IpMultimediaSubsystem (some places) - Changed registration of IMS application. - Moved IMS Identities to a separate interface - Dropped the entire TFT/QoS info. Instead oFono checks the QoS SIP Preconditions. IMS application is notified about changes in QoS, and asks oFono if the QoS SIP preconditions are satisfied. --- doc/ims-api.txt | 162 +++ 1 files changed, 162 insertions(+), 0 deletions(-) create mode 100644 doc/ims-api.txt diff --git a/doc/ims-api.txt b/doc/ims-api.txt new file mode 100644 index 000..5404e61 --- /dev/null +++ b/doc/ims-api.txt @@ -0,0 +1,162 @@ +Ip Multimedia Subsystem hierarchy [experimental] += + +Serviceorg.ofono +Interface org.ofono.IpMultimediaSubsystem +Object path[variable prefix] + +Methodsdict GetProperties() + + Returns all IMS properties. See the + properties section for available properties. + + void Register(string type) + + Register a IMS Application. It must register + with one of the types: + voice, messaging, voice_messaging. + + This registration will inform modem's radio + stack that the IMS application has registered + for Voice and/or Messaging over IMS. + This registration may impact UE Mode of operation + and the ISR feature in the radio stack. + + The registered application is tracked, if the + application exits the registration will be + automatically released. + + Related AT command: AT+EISR. + + Possible Errors: [service].Error.InvalidArguments + + void UnRegister(object path) + + Un-register a IpMultimediaSubsystemAgent. + + Possible Errors: [service].Error.InvalidArguments + + boolean PreConditionCheck(string Type, string PeerAddress, + uint16 PeerPort, uint16 LocalPort) + + This method is used by the IMS application to check + if the QoS SIP precondition is fulfilled. + + The IMS application should call this method when + receiving a PreConditionChanged() signal. + The IMS Application is not allowed to start alerting + before it has confirmed that it has a voice-ready + Dedicated Bearer and QoS set up in the network. + + The legal parameter for Type currently is currently + voice only. In future video (Conversational Video, + Live Streaming) will be added. + + PeerAddress can be IPv4 or IPv6 address. PeerPort and + LocalPort is the RTP port used for the media stream. + + This method returns true if the Traffic Flow Template + read from the modem matches the address information + provided, and the QCI and Bit Rates fulfills the + requirements for the specified type. + + Related AT commands: AT+CGEQOSRDP, AT+CGTFTRDP + + NOTE: Should the Type parameter be removed? + Maybe IMS-video still is a bit futuristic. + +SignalsPropertyChanged(string property, variant value) + + This signal indicates a changed value of the given + property. + + void PreConditionChanged() + + This signal is sent when the network has changed + the QoS or Packet Filters for a Bearer. + The IMS application can then check the QoS SIP + preconditions by calling PreConditionCheck(). + + Only QoS information relevant for IMS will be + signaled, i.e. QCI=1 for voice and QCI=2 for video. + + Related AT commands: AT+CGEREP, + +CGEV: NW ACT, +CGEV: NW MODIFY + +Properties + array{object} Identities [readonly] + + Array of IP Multimedia Identities objects and + properties. + NOTE: It is assumed that Identities will not change. + + boolean VoiceOverPs [readonly
Re: [RFCv2] doc: Proposal for LTE/IMS API
Hi Rémi, +Service org.ofono +Interface org.ofono.IpMultimediaSubsystem +Object path [variable prefix] I guess this is meant to be a modem object path, but it seems the oFono documentation is already a bit sloppy on this point. Yes, this should be the modem object path. I'll fix this in the next patch. + void Register(string type) + + Register a IMS Application. It must register + with one of the types: + voice, messaging, voice_messaging. I am not very familiar with the underlying protocol... If it really makes sense to register both services simultaneously, then I think we should have an array of strings. Or if there are no benefits, then why bother with 'voice_messaging' anyway. Yes, an array of strings might be a good idea here. + boolean PreConditionCheck(string Type, string PeerAddress, + uint16 PeerPort, uint16 LocalPort) + That stuff is per context. Should it not be in the context object rather than in the IMS manager? oFono should only consider QoS information from the IMS Default and Dedicated bearers when checking the precondition. In theory there might be more than one IMS APN for a operator, but I really don't see this as a real life scenario for this. If anyone disagrees please speak out and explain... + array{string} PcscfAddresses [readonly] Should this be in the context object? The AT command is per CID. Would it make any sense for a network to have different P-CSCF based on the bearer? As mentioned above, I don't see why an operator would ever have more than one IMS APN. If we only have one IMS APN, then we might as well present this information here in the IMS API. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [RFCv2] doc: Proposal for LTE/IMS API
Hi Redouane, + void UnRegister(object path) + + Un-register a IpMultimediaSubsystemAgent. Register and UnRegister functions are not really symmetric here ... How object path is used by UnRegister function ?? Maybe we should have : void UnRegister(string type) Thanks for spotting this, it's a bug. It should have been void UnRegister(). I'll fix this in the next patch. + boolean PreConditionCheck(string Type, string PeerAddress, + uint16 PeerPort, uint16 LocalPort) How to make the link between the primary context (or default bearer) activated by the IMS client , and the TFT and QOS. When Dedicated bearers are created +CGEV: NW ACT reports both the Default Bearer and the Dedicated bearer. We can imagine that we have a good QOS / TFT but it doesn't belong to the primary context (or default bearer) activated by the IMS client. As mentioned to Rémi, we should only consider the QoS/TFT for the IMS ConnectionContext and related Dedicated Bearers. So oFono core only needs to keep track of the QoS/TFTs for IMS. + void PreConditionChanged() + + This signal is sent when the network has changed + the QoS or Packet Filters for a Bearer. + The IMS application can then check the QoS SIP + preconditions by calling PreConditionCheck(). + + Only QoS information relevant for IMS will be + signaled, i.e. QCI=1 for voice and QCI=2 for video. + + Related AT commands: AT+CGEREP, + +CGEV: NW ACT, +CGEV: NW MODIFY + Same here , IMS client will be notified for all dedicated bearer ? I agree with Rémi, it 'll be better if we can put QOS/TFT somewhere under primary context. I believe we will have only one IMS APN for each operator, so we might as well keep it here in the IMS Interface. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [RFC] doc: Proposal for LTE/IMS API.
Hi Pekka. Do you think we will ever have more than one IMS ConnectionContext pr SIM? If not not we could probably keep the PcscfAddresses in this IMS API (see object-path proposal below). Unfortunately, yes. Could you please elaborate on this. Do you really foresee a scenario where an operator will provide more than one IMS network? Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCHv2] doc: Assisted Satellite Navigation API and Agent API
From: Simon Lethbridge simon.lethbri...@stericsson.com This patch introduces support for Global Satellite Navigation System (GNSS), using the AT commands AT+CPOS and +CPOSR as specified 3GPP 27.007. --- Changes from v1 (28 Jan): s/SendPositioningControl/SendPositioningElement/ Thanks Rémi, for spotting this one, Changes from RFCv2 (Nov 22): Hi Denis, 2010/11/30 Denis Kenzior denk...@gmail.com: +AssistedSatelliteNavigation hierarchy What do you think of naming this AssistedNavigation? I think the current name might be a bit too long. See mail previous mail on this topic, I think we'd like to keep it as is for now. +Methods void SendPositioningControl(string xml_element) What do you think of SendPositioningElement? Fixed, +Methods void PositioningRequest(string xml_element) I think that 'Request' will be sufficient. Positioning is already part of the agent name. Fixed, + void AssistanceDataReset() I suggest ResetAssistanceData here. Fixed, The only other change I'd make is to mark the entire interface 'experimental', but I can take care of that as well. Fixed, Otherwise the proposal looks good to me. Sorry for taking so long before responding on this. Let us know if you have any issues with this patch. Regards, Sjur and Simon. doc/assisted-sattelite-navigation.txt | 56 + 1 files changed, 56 insertions(+), 0 deletions(-) create mode 100644 doc/assisted-sattelite-navigation.txt diff --git a/doc/assisted-sattelite-navigation.txt b/doc/assisted-sattelite-navigation.txt new file mode 100644 index 000..c5a8c10 --- /dev/null +++ b/doc/assisted-sattelite-navigation.txt @@ -0,0 +1,56 @@ +Assisted Satellite Navigation hierarchy [experimental] +== + +Serviceorg.ofono +Interface org.ofono.AssistedSatelliteNavigation +Object path[variable prefix]/{modem0,modem1,...} + +Methodsvoid SendPositioningElement(string xml_element) + + Send an XML element conforming to the XML DTD for pos + as defined in 3GPP 27.007 Table 8.55-2. This xml is + used for transferring data associated with positioning + requests received via control plane from the network. + This includes assistance data requests and the results + of positioning procedures. This method maps directly to + the 3GPP 27.007 AT+CPOS command. + + void RegisterPositioningRequestAgent(object path) + + Registers an agent which will be called whenever a + CPOSR AT response is received. The Agent must respond + to requests using SendPositioningElement. + + void UnregisterPositioningRequestAgent(object path) + + Un-registers the agent. + +PositioningRequestAgent hierarchy +== + +Serviceunique name +Interface org.ofono.PositioningRequestAgent +Object pathfreely definable + +Methodsvoid Request(string xml_element) + + Receive an XML element conforming to the XML DTD for + pos in 3GPP 27.007. This xml is used for transferring + data associated with positioning requests received, via + control plane, from the network. This includes + measurement requests and assistance data. This method + maps directly to the 3GPP defined +CPOSR unsolicited + result code. + + void ResetAssistanceData() + + A request has been received from the network that all + assistance data should be reset. This is used for 3gpp + performance tests. + + void Release() + + Agent is being released, possibly because of oFono + terminating, AssistedSatelliteNavigation interface + is being torn down or modem off. + No UnregisterPositioningRequestAgent call is needed. -- 1.7.0.4 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] doc: Assisted Satellite Navigation API and Agent API
From: Simon Lethbridge simon.lethbri...@stericsson.com This patch introduces support for Global Satellite Navigation System (GNSS), using the AT commands AT+CPOS and +CPOSR as specified 3GPP 27.007. --- Hi Denis, 2010/11/30 Denis Kenzior denk...@gmail.com: +AssistedSatelliteNavigation hierarchy What do you think of naming this AssistedNavigation? I think the current name might be a bit too long. See mail previous mail on this topic, I think we'd like to keep it as is for now. +Methods void SendPositioningControl(string xml_element) What do you think of SendPositioningElement? Fixed, +Methods void PositioningRequest(string xml_element) I think that 'Request' will be sufficient. Positioning is already part of the agent name. Fixed, + void AssistanceDataReset() I suggest ResetAssistanceData here. Fixed, The only other change I'd make is to mark the entire interface 'experimental', but I can take care of that as well. Fixed, Otherwise the proposal looks good to me. Sorry for taking so long before responding on this. Let us know if you have any issues with this patch. Regards, Sjur and Simon. doc/assisted-sattelite-navigation.txt | 56 + 1 files changed, 56 insertions(+), 0 deletions(-) create mode 100644 doc/assisted-sattelite-navigation.txt diff --git a/doc/assisted-sattelite-navigation.txt b/doc/assisted-sattelite-navigation.txt new file mode 100644 index 000..abacf54 --- /dev/null +++ b/doc/assisted-sattelite-navigation.txt @@ -0,0 +1,56 @@ +Assisted Satellite Navigation hierarchy [experimental] +== + +Serviceorg.ofono +Interface org.ofono.AssistedSatelliteNavigation +Object path[variable prefix]/{modem0,modem1,...} + +Methodsvoid SendPositioningElement(string xml_element) + + Send an XML element conforming to the XML DTD for pos + as defined in 3GPP 27.007 Table 8.55-2. This xml is + used for transferring data associated with positioning + requests received via control plane from the network. + This includes assistance data requests and the results + of positioning procedures. This method maps directly to + the 3GPP 27.007 AT+CPOS command. + + void RegisterPositioningRequestAgent(object path) + + Registers an agent which will be called whenever a + CPOSR AT response is received. The Agent must respond + to requests using SendPositioningControl. + + void UnregisterPositioningRequestAgent(object path) + + Un-registers the agent. + +PositioningRequestAgent hierarchy +== + +Serviceunique name +Interface org.ofono.PositioningRequestAgent +Object pathfreely definable + +Methodsvoid Request(string xml_element) + + Receive an XML element conforming to the XML DTD for + pos in 3GPP 27.007. This xml is used for transferring + data associated with positioning requests received, via + control plane, from the network. This includes + measurement requests and assistance data. This method + maps directly to the 3GPP defined +CPOSR unsolicited + result code. + + void ResetAssistanceData() + + A request has been received from the network that all + assistance data should be reset. This is used for 3gpp + performance tests. + + void Release() + + Agent is being released, possibly because of oFono + terminating, AssistedSatelliteNavigation interface + is being torn down or modem off. + No UnregisterAgent call is needed. -- 1.7.0.4 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [RFC 1/5] gprs: Update documentation for IPv6
Hi, + dict IPv6Settings [readonly, optional] + + Holds all the IPv6 network settings. + + string Interface [readonly, optional] + + Holds the name of the IPv6 network interface + used by this context (e.g. ppp0 usb0). + + For combined IPv4v6 context (3GPP rel 8) the + same network interface may be used for both + IPv4 and IPv6. IPv4 and IPv6 may also be + offered via separate network interfaces. + I think it would be nice if we could keep only one interface here. It's a bit messy that the difference between R7 and R8 networks will be visible to the users like this. So when in a R7 network the uplink traffic should be filtered into the right ipv4 and ipv6 pdp-connection automagically. I know STE will support this in the modem firmware. If firmware doesn't support this perhaps this could also be handled in the kernel drivers. This should be doable for phonet (and Caif), maybe a little more tricky with ppp/pppd? Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [RFC] doc: Proposal for LTE/IMS API.
Hi Rémi, - The QoS information is presented as an array of QoS settings with an associated list IP Packet Filters. Only the QoS data for connection context of type IMS will be reported. The assumption is that QoS is only going to be used by IMS applications. Initially I was planning to put this in the connman-api.txt, but based on feedback from Denis in the Paris workshop I have moved this to the IMS API. If this assumption proves wrong QoS should be moved to ConnectionContext interface. What is this for? In my understanding, the LTE modem will do the classification on outgoing packets - not the application engine. Indeed, based on the proposed API, there is no way for the application engine to tag packet for the benefit of the modem... Yes, this is correct. The modem should take care of this. And we do not need to know anything about classification of incoming packets, other than which primary context they belong to. The point here is that the IMS application needs some information about the QoS it actually got from the network. Apparently IMS-app needs this for selecting appropriate codec-parameters to use. That's the only purpose of presenting this information. +Properties boolean ImsVoiceRegistered [readwrite, optional] + + Inform modem's radio stack that the IMS application + has registered for Voice over IMS. This impacts + UE Mode of operation and the ISR feature in the + radio stack. Related AT command: AT+EISR I suppose this should be similar to Modem.Lockdown: only one D-Bus client can set it (at a time), and it gets automatically cleared if said client dies. I assume you are right, but someone knowing more about the IMS application should answer on this Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [RFC] doc: Proposal for LTE/IMS API.
Hi Pekka, Features: - The QoS information is presented as an array of QoS settings with an associated list IP Packet Filters. Only the QoS data for connection context of type IMS will be reported. The assumption is that QoS is only going to be used by IMS applications. Initially I was planning to put this in the connman-api.txt, but based on feedback from Denis in the Paris workshop I have moved this to the IMS API. If this assumption proves wrong QoS should be moved to ConnectionContext interface. The UE initiates the Default Bearer. In R8, the Network may then initiate a number of Dedicated Bearers. Each Dedicated Bearer will have a defined QoS. In order to route the IP traffic into the different Dedicated Bearers, a set of Packet Filters can be defined for each Dedicated Bearer. I think we need these in ConnectionContext, or perhaps a separate DedicatedContext interface would be better. Yes, as I mentioned earlier I considered this as well. But do you see other scenarios than IMS where the NW will set up Dedicated Bearers? Also the PcscfAddresses should be part of the Settings or Settings6 in ConnectionContext. Do you think we will ever have more than one IMS ConnectionContext pr SIM? If not not we could probably keep the PcscfAddresses in this IMS API (see object-path proposal below). - The UE-Mode of operation, is primarily triggered by IMS application registering to the RadioStack that it has registered on Voice and/or SMS by setting the properties ImsVoiceRegistered or ImsSmsRegistered. - SIM identities used for IMS registration such as: PrivateImsIdentity, PublicImsIdentity, HomeDomainName. These should be available from separate interface/object, one for each ISIM. I guess if you have more than one SIM, you would in fact have two modem instances and two instance of this API. In the next patch I should probably use [{modem1},{modem2}...] as the object-path of this IMS object. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Bug tracking for oFono
Hi, I notice that there has been a couple of bug reports sent on this list lately, and usually the response is care to send a patch for it?. oFono homepage states: A bug tracking system is in the process of being set up. What is the status of this? It seems to be possible to submit bugs on oFono via MeeGo Bugzilla (http://bugs.meego.com/enter_bug.cgi), is this a possible way forward? Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[RFC] TODO: Move signal strength property to separate Agent API.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- I think we should consider changing the way we handle signal strength in oFono. In the past I have seen very frequent signal strength reports from the modem under certain network conditions. I think we can improve the power consumption by changing the design here. I know other Radio Interfaces are subscribing to changes in power modes and turns off the signal strength reporting when screen is turned off. An Agent API for for Signal Strength would allow oFono to subscribe to modem signal strength updates only when an Agent is registered, and applications should register on the Agent API only when the signal-strength information is really needed. Regards, Sjur TODO |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/TODO b/TODO index a36e9ed..50561a8 100644 --- a/TODO +++ b/TODO @@ -434,6 +434,14 @@ Miscellaneous Complexity: C1 Owner: Aki Niemi aki.ni...@nokia.com +- Move the Property Strength in NetworkRegistration into an Agent + API in order to avoid frequent wakeup due to signal strength updates + from the modem. With an Agent API the application can register for updates + if the strength bars are visible, and unregister when applicable (before + going into low-power mode). + Priority: Medium + Complexity: C1 + CDMA Voicecall == -- 1.7.0.4 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [RFC PATCH] gprs: add function to handle activated context
Hi, Pekka Pessi ppe...@gmail.com wrote: The 27.007 for release 9 (from version 9.3.0 onwards) says: NOTE 1: The cids for network-initiated PDP contexts will have values outside the ranges indicated for the cid in the test form of the commands +CGDCONT and +CGDSCONT. The change was proposed by STE last February. This has some ramifications on how we use the CIDs within driver/core. I'm not sure we have any problems with Network Initiated Connection in oFono, unless someone is planning to add support for Network Initiated Primary Contexts / PDN Connections. Because the Network Initiated Contexts we are dealing with will be Secondary PDP Contexts / Dedicated Bearers. If we need to expose information about the Network Initiated Dedicated Bearers, I don't think we should model this as separate Connection-Contexts (with CID), but rather as a dictionary within the primary context object containing the necessary information about the QoS available. I guess we need to hear from IMS-folks the minimum information they need about the QoS, and provide just that information. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [RFC PATCH] gprs: add function to handle activated context
Hi, So far we have been discussing CID races, but if we solve the CID issue, we still might end up with two identical Connections activated with the same connection properties (APN, Username, Password), one initiated by the modem in the LTE Combined Attach procedure and the other being a normal Context Activation, right? How do we protect against establishing two contexts with the same properties? Also: what is the likelihood of not having information the initial PDN defined in the provisioning database, would this be an exceptional case only? Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [RFC PATCH] gprs: add function to handle activated context
Hi Pekka. Pekka Pessi ppe...@gmail.com wrote: I'm not sure we have any problems with Network Initiated Connection in oFono, unless someone is planning to add support for Network Initiated Primary Contexts / PDN Connections. AFAIK the initial LTE default bearer context can be network-initiated, and the CID 0 falls outside the range from +CGDCONT. If I am not mistaken the initial LTE default bearer is initiated by the ME in a combined attach procedure, and not by the Network. (but the Dedicated bearers / Secondary PDPs are activated by the Network). Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCH] plugins-mbm: Combining mbm_disable and reopen_callback
Hi Tomasz, don't worry the tone on the list is quite rough. If you like marit or I can review tomorrow, but feel free to send patch as well if you like. :) Sjur 2011/1/12, Tomasz Gregorek tomasz.grego...@gmail.com: Hi Marcel I already had my solution in head and misunderstood you. I will correct and retest it. Br Tomasz 2011/1/12 Marcel Holtmann mar...@holtmann.org Hi Tomasz, Combining mbm_disable and reopen_callback into one and removing 1 second delay between them to avoid call to reopen_callback after modem being disconnected. have you actually tested this? This will not work since you can not reopen the TTY right away. You need that delay in between. From my previous email, I remember saying that the right fix would be to disarm the timer within disable. Why are we not doing that? Regards Marcel ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCHv5] plugin: Add ste modem initd integration
Hi Marcel. +static void get_modems() +{ so these are declared as get_modems(void) btw. The compiler should have warned you about this. I don't get a compiler warning for this one, not even with -Wall -Wextra -Wpedantic on GCC 4.4.3. But a new rule in the coding-style should perhaps be added, e.g: M15: Use void if function has no parameters A function with no parameters must use void in the parameter list. Example: 1) void foo(void) { } 2) void foo() // Wrong { } ... +static void mgr_disconnect(DBusConnection *connection, void *user_data) +{ + g_hash_table_remove_all(modem_list); + g_dbus_remove_watch(connection, property_changed_watch); +} + +static void stemgr_exit() +{ + g_hash_table_destroy(modem_list); + g_dbus_remove_watch(connection, modem_daemon_watch); + g_dbus_remove_watch(connection, property_changed_watch); This is not right. You need to remove the property_changed_watch in the disconnect callback. Otherwise if your daemon restarts twice you actually have two watches. It's already present in mgr_disconnect, did you miss that? In the previous review 2011/1/5 you said: +static void stemgr_exit() +{ The only thing you missed here is to remove the property changed watch in case it was registered (aka the init daemon started). Anyway, I think the watch handing in the latest patch is correct, we need to do remove_watch for property_changed_watch in both stemgr_exit and in stemgr_disconnect. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] coding-style: Use void if function has no parameters
From: Sjur Brændeland sjur.brandel...@stericsson.com --- Marcel, Denis, Here is the patch, please apply it if you agree. I'm easy :-) Regards, Sjur doc/coding-style.txt | 15 +++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/doc/coding-style.txt b/doc/coding-style.txt index 3bee240..40bb36b 100644 --- a/doc/coding-style.txt +++ b/doc/coding-style.txt @@ -279,6 +279,21 @@ memset(stuff, 0, sizeof(*stuff)); memset(stuff, 0, sizeof *stuff); // Wrong +M15: Use void if function has no parameters +=== +A function with no parameters must use void in the parameter list. + +Example: +1) +void foo(void) +{ +} + +2) +void foo() // Wrong +{ +} + O1: Shorten the name Better to use abbreviation, rather than full name, to name a variable, -- 1.7.0.4 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCHv6] plugin: Add ste modem initd integration
Hi Marcel. you are out of luck today ;) Darn, I forgot to pull. Hang on I'll be back shortly Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCHv7] plugin: Add ste modem initd integration
From: Sjur Brændeland sjur.brandel...@stericsson.com This patch introduces auto discovery of ST-Ericsson modems. ST-Ericsson modems (M57XX, M7XX, M74XX) are managed by a Modem Init Daemon responsible for start, power cycles, flashing etc. This STE plugin monitors the modem state exposed from the Modem Init Damon's Dbus API. When the modem is in state on the STE modem is created and registered. Muliple modem instances, and reset handling is supported. --- Hi Marcel, Am I still out of luck? $ git pull Already up-to-date. $ git am 0001-plugin-Add-ste-modem-initd-integration.patch Applying: plugin: Add ste modem initd integration Regards, Sjur Makefile.am |3 + plugins/stemgr.c | 390 ++ 2 files changed, 393 insertions(+), 0 deletions(-) create mode 100644 plugins/stemgr.c diff --git a/Makefile.am b/Makefile.am index cc30624..4dec90a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -298,6 +298,9 @@ builtin_sources += plugins/ifx.c builtin_modules += ste builtin_sources += plugins/ste.c +builtin_modules += stemgr +builtin_sources += plugins/stemgr.c + builtin_modules += caif builtin_sources += plugins/caif.c diff --git a/plugins/stemgr.c b/plugins/stemgr.c new file mode 100644 index 000..377e115 --- /dev/null +++ b/plugins/stemgr.c @@ -0,0 +1,390 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2011 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include errno.h +#include string.h +#include net/if.h + +#include glib.h +#include gdbus.h + +#define OFONO_API_SUBJECT_TO_CHANGE +#include ofono/plugin.h +#include ofono/log.h +#include ofono/modem.h +#include ofono/dbus.h + +/* + * ST-Ericsson's Modem Init Daemon is used for controling the modem power + * cycles and provides a dbus API for modem state and properties. + */ +#define MGR_SERVICEcom.stericsson.modeminit +#define MGR_INTERFACE MGR_SERVICE .Manager +#define MGR_GET_MODEMS GetModems +#define GET_MODEMS_TIMEOUT 5000 + +#define MGR_MODEM_INTERFACEMGR_SERVICE .Modem +#define PROPERTY_CHANGED PropertyChanged + +enum ste_state { + STE_STATE_OFF, + STE_STATE_READY, + STE_STATE_RESET +}; + +enum ste_operation { + STE_OP_STARTING, + STE_OP_READY, + STE_OP_RESTART, + STE_OP_OFF +}; + +struct ste_modem { + char *path; + struct ofono_modem *modem; + enum ste_state state; + char *serial; + char *interface; +}; + +static GHashTable *modem_list; +static guint modem_daemon_watch; +static guint property_changed_watch; +static DBusConnection *connection; + +static void state_change(struct ste_modem *stemodem, enum ste_operation op) +{ + switch (stemodem-state) { + case STE_STATE_OFF: + /* +* The STE Modem is in state OFF and we're waiting for +* the Modem Init Daemon to signal that modem is ready +* in order to create and register the modem. +*/ + switch (op) { + case STE_OP_READY: + stemodem-modem = ofono_modem_create(stemodem-serial, + ste); + if (stemodem-modem == NULL) { + ofono_error(Could not create modem %s, %s, + stemodem-path, + stemodem-serial); + return; + } + + DBG(register modem %s, %s, stemodem-path, + stemodem-serial); + + if (stemodem-interface != NULL) + ofono_modem_set_string(stemodem-modem, + Interface, + stemodem-interface); + + ofono_modem_register(stemodem-modem); + stemodem-state = STE_STATE_READY; + break; + case STE_OP_STARTING: + case STE_OP_RESTART: + case STE_OP_OFF: + break; + } + break
[PATCHv5] plugin: Add ste modem initd integration
From: Sjur Brændeland sjur.brandel...@stericsson.com This patch introduces auto discovery of ST-Ericsson modems. ST-Ericsson modems (M57XX, M7XX, M74XX) are managed by a Modem Init Daemon responsible for start, power cycles, flashing etc. This STE plugin monitors the modem state exposed from the Modem Init Damon's Dbus API. When the modem is in state on the STE modem is created and registered. Muliple modem instances, and reset handling is supported. --- Hi Marcel. + +builtin_modules += stemgr +builtin_sources += plugins/stemgr.c + This is a minor nitpick, but I think this is better placed between ste and caif plugin details. And not on top of stemodem. Sure, I've moved this entry. +#define MGR_SERVICE com.stericsson.modeminit +#define MGR_MGR_INTERFACEMGR_SERVICE .Manager Really? MGR_MGR and not MGR_MANAGER ;) Oops, s/mid/mgr didn't do it right this time ;-) Let's call it MGR_INTERFACE instead. +struct ste_modem { + struct ofono_modem *modem; + char *path; You don't have to necessarily do it this way, but since you are using the path memory also as index for your hash table it might be good to put it first in your struct. Ok, I've put path first in struct. +static guint mgr_api_watch; It is more like a service watch or daemon watch. Yes, I renamed this to modem_daemon_watch. +static guint mgr_state_watch; And this is property changed watch, right? Yes, renamed this to property_changed_watch What is this exactly for? How many do you expect to have pending? I have removed this one. get_modems is *only* called when the Modem Init Daemon is first connected. +static inline gboolean is_ready(const char *action) +{ + return g_strcmp0(action, ready) == 0; +} ... This is nasty. Why not convert the state into an enum once and be done with it. Nasty? Anyway I've changed this to a ste_operation enum, and I'll give you that - it does make the state machine a more readable. I find this all a bit complicated. Can you quickly describe the logic here in plain words. Sure, I've written some prose describing the state machine. I've also done this function like a standard FSM implementation: switch(state) { case STATE_A: switch (operation) { case OPERATION_1: ... +static void get_modems(const char *path) +{ This path parameter is rather pointless. It is always /. Agree. + if (get_modems_call_pending) + return; I still haven't figured out what you are trying to protect here. +static gboolean property_changed(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ ... + stemodem = g_hash_table_lookup(modem_list, + dbus_message_get_path(message)); + + if (stemodem == NULL) { + get_modems(/); + return TRUE; + } So here we go. So you are expecting a property changed signal before GetModems finished and therefor you just call it again. This is rather pointless since you get the properties with the return of the GetModems call and these should be the actual ones. So if the modem path is not in your hash-table, then just ignore the property changed signal. Yes, agree. This was a left over from previous API. I have removed this completely. get_modems() is only called when Modem Init Daemon API becomes available. If modems ever pop up dynamically I will add a new signal for this in the DBus API as suggested. +static void stemgr_exit() +{ The only thing you missed here is to remove the property changed watch in case it was registered (aka the init daemon started). Good catch thanks, I'v removed this watch. Thank you for reviewing this code, hopefully we're close to completion now ;-) Regards, Sjur Makefile.am |3 + plugins/stemgr.c | 385 ++ 2 files changed, 388 insertions(+), 0 deletions(-) create mode 100644 plugins/stemgr.c diff --git a/Makefile.am b/Makefile.am index 8a8555d..1e4f9df 100644 --- a/Makefile.am +++ b/Makefile.am @@ -292,6 +292,9 @@ builtin_sources += plugins/ifx.c builtin_modules += ste builtin_sources += plugins/ste.c +builtin_modules += stemgr +builtin_sources += plugins/stemgr.c + builtin_modules += caif builtin_sources += plugins/caif.c endif diff --git a/plugins/stemgr.c b/plugins/stemgr.c new file mode 100644 index 000..0e2745c --- /dev/null +++ b/plugins/stemgr.c @@ -0,0 +1,385 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2011 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU
Re: [PATCH] Fix compile warning at MeeGo The gcc version is MeeGo 4.5.1
Hi Martin. On Thu, Jan 6, 2011 at 10:46 AM, martin...@intel.com wrote: From: blutolan bluto...@blutolan-desktop.(none) Your git-config is wrong, you need to set name and email right in your git-config before committing. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [RFC PATCH] gprs: add function to handle activated context
Hi Redouane, ... +static void gprs_cid_take(struct ofono_gprs *gprs, unsigned int id) +{ + idmap_take(gprs-cid_map, id); +} + How do we assure that this CID is not already in use? I think the M7400 is going to use CID=0 and M700 uses CID=1. Perhaps we should make sure CID=0 is a legal value and reserve CID 0 and 1 at start up. There is probably other ways of handling this as well, but I think any other solution would end up with race conditions, as context could be initiated from two sources. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [RFC PATCH] gprs: add function to handle activated context
Hi, From my understanding the ID in the core is an internal ID for oFono core, even if today we usually have a mapping 1 to 1 between oFono core ID and modems CID. Denis, Marcel could you confirm ? Negative, to my understanding the CID is allocated in src/gprs.c and used when activating/deactivating PDP contexts (PDN Connections): snip static gboolean assign_context(struct pri_context *ctx) { ... ctx-context.cid = gprs_cid_alloc(ctx-gprs); snip static void ...gprs_activate_primary(struct ofono_gprs_context *gc, const struct ofono_gprs_primary_context *ctx, ofono_gprs_context_up_cb_t cb, void *data) { gcd-active_context = ctx-cid; If we try to do something else oFono core will be modem dependent and it's really not a good idea. It has been talk about standardizing the use of CID=0 for initial PDN.If this comes true this is no longer modem vendor dependent. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCHv4 0/1] STE Modem Init Daemon integration
From: Sjur Brændeland sjur.brandel...@stericsson.com This is the latest version of the Modem Init Daemon API. STE Modem Init Deamon Manager = Service com.stericsson.modeminit Interface com.stericsson.modeminit.Manager Object path / Methods array{object,dict} GetModems() Get array of STE Modem objects and their state and properties (out signature 'a(oa{sv})'). The method should only be call once per application. Further changes shall be monitored via StateChange signals. STE Modem = Service com.stericsson.modeminit Interface com.stericsson.modeminit.Modem Object path variable Signals PropertyChanged(string property, variant value) This signal indicates a changed value of the given property. Properties string State [readonly] The modems state is dynamic can can have the following values: booting Modem is powered up (flashed version) or Modem is powered up and firmware upload is completed. (flashless version) upgrading Firmware upgrade on going or Flashing manager under execution - modem in service mode. ready Modem has booted and is ready for use. This implies that all AT channels are available, the modem might be in e.g. flight mode. dumping Modem has crashed and dump is ongoing off Modem is powered off. string Interface[readonly] CAIF Link Layer interface to be used for CAIF channels for a modem. string Serial[optional,readonly] Serial Number or IMEI for the Modem. The Serial will not be available until the modem can open an AT channel. Sjur Brændeland (1): plugin: Add ste modem initd integration Makefile.am |4 + plugins/stemgr.c | 345 ++ 2 files changed, 349 insertions(+), 0 deletions(-) create mode 100644 plugins/stemgr.c ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCHv4 1/1] plugin: Add ste modem initd integration
From: Sjur Brændeland sjur.brandel...@stericsson.com This patch introduces auto discovery of ST-Ericsson modems. ST-Ericsson modems (M57XX, M7XX, M74XX) are managed by a Modem Init Daemon responsible for start, power cycles, flashing etc. This STE plugin monitors the modem state exposed from the Modem Init Damon's Dbus API. When the modem is in state on the STE modem is created and registered. Muliple modem instances, and reset handling is supported. --- Changes: - Adapted to new Dbus API, using GetModems method and PropertyChange signal - Using Serial as modem id - Review comments from last v3 Makefile.am |4 + plugins/stemgr.c | 345 ++ 2 files changed, 349 insertions(+), 0 deletions(-) create mode 100644 plugins/stemgr.c diff --git a/Makefile.am b/Makefile.am index 8a8555d..6fc4c62 100644 --- a/Makefile.am +++ b/Makefile.am @@ -223,6 +223,10 @@ builtin_sources += drivers/atmodem/atutil.h \ drivers/ifxmodem/gprs-context.c \ drivers/ifxmodem/stk.c + +builtin_modules += stemgr +builtin_sources += plugins/stemgr.c + builtin_modules += stemodem builtin_sources += drivers/atmodem/atutil.h \ drivers/stemodem/stemodem.h \ diff --git a/plugins/stemgr.c b/plugins/stemgr.c new file mode 100644 index 000..467d0f8 --- /dev/null +++ b/plugins/stemgr.c @@ -0,0 +1,345 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2011 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include errno.h +#include string.h +#include net/if.h + +#include glib.h +#include gdbus.h + +#define OFONO_API_SUBJECT_TO_CHANGE +#include ofono/plugin.h +#include ofono/log.h +#include ofono/modem.h +#include ofono/dbus.h + +/* + * ST-Ericsson's Modem Init Daemon is used for controling the modem power + * cycles and provides a dbus API for modem state and properties. + */ +#define MGR_SERVICEcom.stericsson.modeminit +#define MGR_MGR_INTERFACE MGR_SERVICE .Manager +#define MGR_GET_MODEMS GetModems +#define GET_MODEMS_TIMEOUT 5000 + +#define MGR_MODEM_INTERFACEMGR_SERVICE .Modem +#define PROPERTY_CHANGED PropertyChanged + +enum ste_state { + STE_PENDING, + STE_REGISTERED, + STE_RESETTING +}; + +struct ste_modem { + struct ofono_modem *modem; + char *path; + enum ste_state state; + char *serial; + char *interface; +}; + +static GHashTable *modem_list; +static guint mgr_api_watch; +static guint mgr_state_watch; +static DBusConnection *connection; +static gboolean get_modems_call_pending; + +static inline gboolean is_ready(const char *action) +{ + return g_strcmp0(action, ready) == 0; +} + +static inline gboolean is_reset(const char *action) +{ + return g_strcmp0(action, dumping) == 0; +} + +static void state_change(struct ste_modem *stemodem, const char *action) +{ + + switch (stemodem-state) { + case STE_PENDING: + + if (!is_ready(action)) + break; + + stemodem-modem = ofono_modem_create(stemodem-serial, + ste); + if (stemodem-modem == NULL) { + ofono_error(Could not create modem %s, %s, + stemodem-path, stemodem-serial); + return; + } + + DBG(register modem %s, %s, stemodem-path, stemodem-serial); + ofono_modem_set_string(stemodem-modem, Interface, + stemodem-interface); + ofono_modem_register(stemodem-modem); + stemodem-state = STE_REGISTERED; + break; + case STE_REGISTERED: + + if (is_reset(action)) { + DBG(reset ongoing %s, stemodem-path); + /* Note: Consider to power off modem here? */ + stemodem-state = STE_RESETTING; + } else if (!is_ready(action)) { + DBG(STE modem unregistering %s %s, stemodem-path, + action); + ofono_modem_remove(stemodem-modem
Re: [PATCHv2] plugin: Add ste modem initd integration
Hi Marcel. is this the full API or only part of it. If it is just a part of it, please send the full API for the daemon. Just looking at this piece, I am not really thinking that this is a good API. It is actually pretty much broken :( Ok, here's an updated version of the Modem Init Daemon DBus API. I hope this is aligned with what we discussed on the IRC. STE Modem Init Deamon Manager Service com.stericsson.modeminit Interface com.stericsson.modeminit.Manager Object path / Methods array{object,dict} GetModems() Get array of STE Modem objects and their state and properties (out signature 'a(oa{sv})'). The method should only be call once per application. Further changes shall be monitored via StateChange signals. STE Modem Service com.stericsson.modeminit Interface com.stericsson.modeminit.Modem Object path variable Signals StateChange(string State) The modems state sent from when a modem state change occurs. State is the only dynamic property in this Interface. Properties string State [readonly] The modems state is dynamic can can have the following values: booting Modem is powered up (flashed version) or Modem is powered up and firmware upload is completed. (flashless version) upgrading Firmware upgrade on going or Flashing manager under execution - modem in service mode. on Modem has booted and is ready for use. This implies that all AT channels are available, the modem might be in e.g. flight mode. dumping Modem has crashed and dump is ongoing off Modem is powered off. string CaifAtInterface [readonly] CAIF Link Layer interface to be used for AT channels for a modem. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCHv2] plugin: Add ste modem initd integration
Hi Marcel, Signals StateChange(string State) The modems state sent from when a modem state change occurs. State is the only dynamic property in this Interface. I would personally just go straight for PropertyChanged signal here and not bother with StateChanged. It is actually ...Changed since at that time the state has already changed ;) OK, I'll look into this. I thought StateChange was the only dynamic parameter, but I might have been wrong here (see below). You also need the following signals: ModemAdded(object, dict) ModemRemoved(object) I think I'd rather add this when I see a use case for it. The Modem Init Deamon would need to know what GPIOs are associated with what modems, and what CAIF interfaces to use etc. This information is not dynamic, at least not at the moment. So ModemAdded and ModemRemoved will not happen in the current implementation, all the modems will be known when the Manager interface becomes available. ... string CaifAtInterface [readonly] CAIF Link Layer interface to be used for AT channels for a modem. I would really just call this Interface to make it simpler. Don't think that you are expecting more than just CAIF interface here anyway. OK, Fair enough. And in addition if we can have the modem serial number here as Serial as well would be good. Even it is is not right away available, you can signal a change via PropertyChanged signal. That way we can construct a proper modem object path inside oFono. I really rather use the serial number and only fallback to the interface name. OK, a Serial property is doable, but I think this is only available after state on (ready) has been reached. The drawback is that my assumption of State being the only dynamic property wrong. Crap you were right - I might need to add a PropertyChanged signal. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCHv2] plugin: Add ste modem initd integration
Hi Marcel, what about potential USB based CAIF devices? Good question, but in a Bridge Setup for a phone this will not really be devices that come and go. I belive it will still be a fixed HW setup where the Modem Init Daemon will have static knowledge of the USB modems. But I'll discuss this with my coleagues tomorrow. In case of true USB dongles the modem should look pretty much identical to MBM USB dongles. I would just ask to send the property changed signal for the serial number before sending the signal for on/ready. It will require a re-design of the state machine in the Modem Init Daemon, but I'll check into this tomorrow. Here is the latest version of the Dbus API: STE Modem Init Deamon Manager = Service com.stericsson.modeminit Interface com.stericsson.modeminit.ModemManager Object path / Methods array{object,dict} GetModems() Get array of STE Modem objects and their state and properties (out signature 'a(oa{sv})'). The method should only be call once per application. Further changes shall be monitored via StateChange signals. STE Modem = Service com.stericsson.modeminit Interface com.stericsson.modeminit.Modem Object path variable Signals PropertyChanged(string property, variant value) This signal indicates a changed value of the given property. Properties string State [readonly] The modems state is dynamic can can have the following values: booting Modem is powered up (flashed version) or Modem is powered up and firmware upload is completed. (flashless version) upgrading Firmware upgrade on going or Flashing manager under execution - modem in service mode. onModem has booted and is ready for use. This implies that all AT channels are available, the modem might be in e.g. flight mode. NOTE: Consider change name to ready dumping Modem has crashed and dump is ongoing off Modem is powered off. string AtInterface[readonly] CAIF Link Layer interface to be used for AT channels for a modem. string Serial[optional,readonly] Serial Number or IMEI for the Modem. The Serial will not be available until the modem can open an AT channel. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCHv2] plugin: Add ste modem initd integration
Hi Marcel. + +/* ResetState requests resending of StateChange. */ +#define MID_RESEND_STATE ResendState This is a bad D-Bus API btw. Using a D-Bus method to trigger signal sending. You will wake up any listener for that signal. What is wrong with just having a GetState? My problem is that I need to get the path, or modem serial-number if you like, to the modem(s). As I don't know the start order I have to query the state at startup. So this will happens only once. The simples way for me to get the path is to send ResendState to path /. This will then send the state info for all modem paths. I don't think I have the path them available at connect... If you have any other ideas of how to query the modem instances I'm all ears? The other is feedback makes sens to me ;-) Thanks for review and feedback. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCHv2] plugin: Add ste modem initd integration
Hi Marcel. This is a bad D-Bus API btw. Using a D-Bus method to trigger signal sending. You will wake up any listener for that signal. What is wrong with just having a GetState? My problem is that I need to get the path, or modem serial-number if you like, to the modem(s). As I don't know the start order I have to query the state at startup. So this will happens only once. The simples way for me to get the path is to send ResendState to path /. This will then send the state info for all modem paths. I don't think I have the path them available at connect... If you have any other ideas of how to query the modem instances I'm all ears? I think you need to resend the D-Bus API of your init daemon. I need to have a second look. This is an extract of the Modem Init Daemon D-Bus API. I have removed the GetState API as we don't know the object path of the modem when oFOno has just booted. Instead we have added the ResendState API. This will be called initially when oFono starts to query the modem instances and their state. After startup state changes are handed as signals with StateChange. (There are some exceptions to this but they should be only corner cases). Modem Init Deamon Service com.stericsson.modeminit Interface com.stericsson.modeminit.Modem Object path /{modem-serial} or / Methods void ResendState() Resends state information for all modems. This method must use with '/' as object path. string GetCaifIfName() Returns the CAIF Link Layer interface used for AT channels for a specific modem. This method must use the same object path as used in StateChange. Signals StateChange(string status) The modems state sent from Modem Init Daemon when a modem state change occurs. The object path must be the identifier of the modem (typically the serial-id or IMEI of the HW). booting Modem is powered up (flashed version) or Modem is powered up and firmware upload is completed. (flashless version) upgrading Firmware upgrade on going or Flashing manager under execution - modem in service mode. on Modem has booted and is ready for use. This implies that all AT channels are available, the modem might be in e.g. flight mode. dumping Modem has crashed and dump is ongoing off Modem is powered off. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCHv3] plugin: Add ste modem initd integration
From: Sjur Brændeland sjur.brandel...@stericsson.com This patch introduces auto discovery of ST-Ericsson modems. ST-Ericsson modems (M57XX, M7XX, M74XX) are managed by a Modem Init Daemon responsible for start, power cycles, flashing etc. This STE plugin monitors the modem state exposed from the Modem Init Damon's Dbus API. When the modem is in state on the STE modem is created and registered. Muliple modem instances, and reset handling is supported. --- Hi Marcel. I think I have resolved most of your comments on my last patch set, including the massive confusion caused by calling this MID ;-) The only remark left is ResendState. I have done this as simple as possible where you just re-send all state information for all modem instances and implicit get the object-path (serial-id) for each modem when the StateChange signal is received. I really don't think resending the state information should be of much concern as this only happens once - when oFono starts. The extra cost of waking the other two STE daemons should be negligible, as they most likely are initializing and preparing for communicating with the STE-modem anyway. Regards, Sjur Makefile.am |3 + plugins/stemgr.c | 310 ++ 2 files changed, 313 insertions(+), 0 deletions(-) create mode 100644 plugins/stemgr.c diff --git a/Makefile.am b/Makefile.am index 12b3c33..d9c0505 100644 --- a/Makefile.am +++ b/Makefile.am @@ -221,6 +221,9 @@ builtin_sources += drivers/atmodem/atutil.h \ drivers/ifxmodem/gprs-context.c \ drivers/ifxmodem/stk.c +builtin_modules += stemgr +builtin_sources += plugins/stemgr.c + builtin_modules += stemodem builtin_sources += drivers/atmodem/atutil.h \ drivers/stemodem/stemodem.h \ diff --git a/plugins/stemgr.c b/plugins/stemgr.c new file mode 100644 index 000..6317516 --- /dev/null +++ b/plugins/stemgr.c @@ -0,0 +1,309 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2010 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include errno.h +#include string.h +#include net/if.h + +#include glib.h +#include gdbus.h + +#define OFONO_API_SUBJECT_TO_CHANGE +#include ofono/plugin.h +#include ofono/log.h +#include ofono/modem.h +#include ofono/dbus.h + +/* + * ST-Ericsson's Modem Init Daemon is used for controling the modem power + * cycles and provides a dbus API for modem state and properties. + */ +#define MGR_SERVICEcom.stericsson.modeminit +#define MGR_INTERFACE MGR_SERVICE .Modem + +/* The signal StateChange sends the modem state.*/ +#define STATUS_CHANGED StateChange + +#define MGR_ACTION_ON on/* Modem is on */ +#define MGR_ACTION_RESET dumping /* Modem is resetting */ + +/* + * ResendState requests resending of StateChange. This method is only + * called at startup, in order to retrieve the modem's serial id, + * (object path) and state. + */ +#define MGR_RESEND_STATE ResendState + +/* GetCaifIfName requests the CAIF Interface Name. */ +#define MGR_GET_CAIFIF GetCaifIfName + +#define TIMEOUT5000 + +enum ste_state { + STE_PENDING,/* Waiting for caifif and on notification */ + STE_PENDING_IF, /* Waiting for caifif, already got on */ + STE_REGISTERED, /* Modem is registered */ + STE_RESETTING /* Modem is resetting */ +}; + +struct ste_modem { + char *path; + struct ofono_modem *modem; + enum ste_state state; + gboolean got_caifif; + gboolean pending_call; +}; + +static GHashTable *modem_list; +static guint mgr_api_watch; +static guint mgr_state_watch; +static DBusConnection *connection; + +static void get_caifif_reply(DBusPendingCall *call, void *user_data) +{ + DBusMessage *reply; + char *ifname; + struct ste_modem *stemodem = user_data; + + stemodem-pending_call = FALSE; + stemodem-got_caifif = TRUE; + reply = dbus_pending_call_steal_reply(call); + + if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN)) { + ofono_error(STE Modem Init Daemon: unavailable); + goto error; + } + + if (dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING
Re: Failed to create CAIF socket for AT
Hi Kris, I am trying to understand CAIF protocol implementation in OFono. I am getting Failed to create CAIF socket for AT when i am trying to enable my modem. Maybe the easies way to check if you have CAIF running is to try out unit/test-caif. It will try to open a CAIF Socket to the modem and send an AT command. You need to do the following to get the CAIF serial interface up: 1) Run a user space program to configure your serial cable and insert the CAIF line discipline. (You'll find a really old sample of ldiscd.c here: http://patchwork.ozlabs.org/patch/34179/ perhaps you could get this to work? Please ignore all the other stuff in this patch, it is completely obsolete). Please note that you have to run as root in order to install the ldisc. 2) If this is succesfull you will get a new network interface called cfttyname representing the CAIF Link Layer. You need to set this interface in state up (e.g. sudo ifconfig cfttyname up). You should now be able to connect CAIF sockets, and run unit/test-caif. If Marcel accepts the patch I send for plugin/stemgr.c then this is the best way to start the STE modem. I will post a python-script simulating the Modem Init Daemon when the stemgr is accepted. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCHv2] plugin: Add ste modem initd integration
From: Sjur Brændeland sjur.brandel...@stericsson.com This patch introduces auto discovery of ST-Ericsson modems. ST-Ericsson modems (M5XX, M57XX, M7XX, M74XX) are managed by a Modem Init Daemon responsible for start, power cycles, flashing etc. This STE plugin monitors the modem state exposed from the Modem Init Damon's Dbus API. When the modem is in state on the STE modem is created and registered. Multiple modem instances, and reset handling is supported. --- Changes: - Support for multiple STE modems. - Better naming of STE modem instances, using received dbus path. - CAIF Link layer to use for AT channels specified pr modem instance. - Added support for reset. Makefile.am |5 + configure.ac |6 + plugins/stemid.c | 310 ++ 3 files changed, 321 insertions(+), 0 deletions(-) create mode 100644 plugins/stemid.c diff --git a/Makefile.am b/Makefile.am index 12b3c33..98096ae 100644 --- a/Makefile.am +++ b/Makefile.am @@ -82,6 +82,11 @@ gatchat_sources = gatchat/gatchat.h gatchat/gatchat.c \ udev_files = plugins/ofono.rules +if STE_MODEM_INITD +builtin_modules += stemid +builtin_sources += plugins/stemid.c +endif + if UDEV builtin_modules += udev builtin_sources += plugins/udev.c diff --git a/configure.ac b/configure.ac index 5c18f68..f733fc4 100644 --- a/configure.ac +++ b/configure.ac @@ -177,6 +177,12 @@ AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--disable-datafiles], AM_CONDITIONAL(DATAFILES, test ${enable_datafiles} != no) +AC_ARG_ENABLE(ste_modem_initd, AC_HELP_STRING([--disable-ste-modem-initd], + [disable auto discovery of STE modem using modem init daemon]), + [enable_ste_modem_initd=${enableval}]) + +AM_CONDITIONAL(STE_MODEM_INITD, test ${enable_ste_modem_initd} != no) + if (test ${prefix} = NONE); then dnl no prefix and no localstatedir, so default to /var if (test $localstatedir = '${prefix}/var'); then diff --git a/plugins/stemid.c b/plugins/stemid.c new file mode 100644 index 000..9f5da22 --- /dev/null +++ b/plugins/stemid.c @@ -0,0 +1,310 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2010 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include errno.h +#include string.h +#include net/if.h + +#include glib.h + +#define OFONO_API_SUBJECT_TO_CHANGE +#include ofono/plugin.h +#include ofono/log.h +#include ofono/modem.h +#include ofono/dbus.h + +/* + * ST-Ericsson's Modem Init Daemon is used for controling the modem power + * cycles and provides a dbus API for modem state and properties. + */ +#define MID_SERVICEcom.stericsson.modeminit +#define MID_INTERFACE MID_SERVICE .Modem + +/* The signal StateChange sends the modem state.*/ +#define STATUS_CHANGED StateChange + +#define MID_ACTION_ON on/* Modem is on */ +#define MID_ACTION_RESET dumping /* Modem is resetting */ +#define MID_ACTION_UNKNOWN unknown /* Don't care */ + +/* ResetState requests resending of StateChange. */ +#define MID_RESEND_STATE ResendState + +/* GetCaifIfName requests the CAIF Interface Name. */ +#define MID_GET_CAIFIF GetCaifIfName + +#define TIMEOUT5000 +#define STE_DRIVER_NAMEste +#define STE_INTERFACE_PROPERTY Interface + +enum ste_state { + STE_PENDING,/* Waiting for caifif and on notification */ + STE_PENDING_IF, /* Waiting for caifif, already got on */ + STE_REGISTERED, /* Modem is registered */ + STE_RESETTING /* Modem is resetting */ +}; + +struct ste_modem { + char *path; + struct ofono_modem *modem; + enum ste_state state; + gboolean got_caifif; + gboolean pending_call; +}; + +static GHashTable *modem_list; +static guint mid_api_watch; +static guint mid_state_watch; +static DBusConnection *connection; + +static void get_caifif_reply(DBusPendingCall *call, void *user_data) +{ + DBusMessage *reply; + char *ifname; + struct ste_modem *stemodem = user_data; + + stemodem-pending_call = FALSE; + stemodem-got_caifif = TRUE; + reply = dbus_pending_call_steal_reply(call); + + if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN
[PATCHv2 1/2] stemodem: Create network interfaces statically
From: Sjur Brændeland sjur.brandel...@stericsson.com Changes: o Restructure code so interfaces are created statically when probe is called, instead of creating interfaces dynamically at activation. o Changed debug messages. o Removed some of the unnecessary initializations at declaration. o No longer reporting default gateway for PtP IP Interface. o Bugfix: Handle network initiated deactivation. --- drivers/stemodem/gprs-context.c | 149 +- 1 files changed, 82 insertions(+), 67 deletions(-) diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index faa3124..7bdcdb8 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -28,6 +28,7 @@ #include string.h #include stdlib.h #include stdio.h +#include errno.h #include glib.h @@ -65,10 +66,18 @@ struct gprs_context_data { }; struct conn_info { + /* +* cid is allocated in oFono Core and is identifying +* the Account. cid = 0 indicates that it is currently unused. +*/ unsigned int cid; - unsigned int device; + /* Id used by CAIF and EPPSD to identify the CAIF channel*/ unsigned int channel_id; - char interface[10]; + /* Linux Interface Id */ + unsigned int ifindex; + /* Linux Interface name */ + char interface[IF_NAMESIZE]; + gboolean created; }; struct eppsd_response { @@ -76,7 +85,6 @@ struct eppsd_response { char ip_address[IP_ADDR_LEN]; char subnet_mask[IP_ADDR_LEN]; char mtu[IP_ADDR_LEN]; - char default_gateway[IP_ADDR_LEN]; char dns_server1[IP_ADDR_LEN]; char dns_server2[IP_ADDR_LEN]; char p_cscf_server[IP_ADDR_LEN]; @@ -96,8 +104,6 @@ static void start_element_handler(GMarkupParseContext *context, rsp-current = rsp-subnet_mask; else if (!strcmp(element_name, mtu)) rsp-current = rsp-mtu; - else if (!strcmp(element_name, default_gateway)) - rsp-current = rsp-default_gateway; else if (!strcmp(element_name, dns_server) rsp-dns_server1[0] == '\0') rsp-current = rsp-dns_server1; @@ -123,7 +129,7 @@ static void text_handler(GMarkupParseContext *context, if (rsp-current) { strncpy(rsp-current, text, IP_ADDR_LEN); - rsp-current[IP_ADDR_LEN] = 0; + rsp-current[IP_ADDR_LEN] = '\0'; } } @@ -153,8 +159,7 @@ static gint conn_compare_by_cid(gconstpointer a, gconstpointer b) return 0; } -static struct conn_info *conn_info_create(unsigned int device, - unsigned int channel_id) +static struct conn_info *conn_info_create(unsigned int channel_id) { struct conn_info *connection = g_try_new0(struct conn_info, 1); @@ -162,7 +167,6 @@ static struct conn_info *conn_info_create(unsigned int device, return NULL; connection-cid = 0; - connection-device = device; connection-channel_id = channel_id; return connection; @@ -171,7 +175,7 @@ static struct conn_info *conn_info_create(unsigned int device, /* * Creates a new IP interface for CAIF. */ -static gboolean caif_if_create(const char *interface, unsigned int connid) +static gboolean caif_if_create(struct conn_info *conn) { return FALSE; } @@ -179,9 +183,8 @@ static gboolean caif_if_create(const char *interface, unsigned int connid) /* * Removes IP interface for CAIF. */ -static gboolean caif_if_remove(const char *interface, unsigned int connid) +static void caif_if_remove(struct conn_info *conn) { - return FALSE; } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -210,21 +213,13 @@ static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, DBG(Did not find data (used caif device) for connection with cid; %d, gcd-active_context); - goto error; + CALLBACK_WITH_FAILURE(cb, cbd-data); + return; } conn = l-data; - - if (!caif_if_remove(conn-interface, conn-channel_id)) { - DBG(Failed to remove caif interface %s., - conn-interface); - } - conn-cid = 0; - return; - -error: - CALLBACK_WITH_FAILURE(cb, cbd-data); + CALLBACK_WITH_SUCCESS(cb, cbd-data); } static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) @@ -233,7 +228,7 @@ static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) ofono_gprs_context_up_cb_t cb = cbd-cb; struct ofono_gprs_context *gc = cbd-user; struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); - struct conn_info *conn = NULL; + struct conn_info *conn; GAtResultIter
[PATCHv2 2/2] stemodem: Use RTNL to create network interfaces.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- drivers/stemodem/gprs-context.c | 43 -- 1 files changed, 36 insertions(+), 7 deletions(-) diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index 7bdcdb8..1762fb3 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -47,6 +47,7 @@ #include stemodem.h #include caif_socket.h #include if_caif.h +#include caif_rtnl.h #define MAX_CAIF_DEVICES 4 #define MAX_DNS 2 @@ -172,12 +173,20 @@ static struct conn_info *conn_info_create(unsigned int channel_id) return connection; } -/* - * Creates a new IP interface for CAIF. - */ -static gboolean caif_if_create(struct conn_info *conn) +static void rtnl_callback(int ifindex, const char *ifname, void *user_data) { - return FALSE; + struct conn_info *conn = user_data; + + if (ifindex 0) { + conn-created = FALSE; + ofono_error(Failed to create caif interface %s, + conn-interface); + return; + } + + strncpy(conn-interface, ifname, sizeof(conn-interface)); + conn-ifindex = ifindex; + conn-created = TRUE; } /* @@ -185,6 +194,17 @@ static gboolean caif_if_create(struct conn_info *conn) */ static void caif_if_remove(struct conn_info *conn) { + if (!conn-created) + return; + + if (caif_rtnl_delete_interface(conn-ifindex) 0) { + ofono_error(Failed to delete caif interface %s, + conn-interface); + return; + } + + DBG(removed CAIF interface ch:%d ifname:%s ifindex:%d\n, + conn-channel_id, conn-interface, conn-ifindex); } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -526,7 +546,7 @@ static int ste_gprs_context_probe(struct ofono_gprs_context *gc, GAtChat *chat = data; struct gprs_context_data *gcd; struct conn_info *ci; - int i; + int i, err; gcd = g_new0(struct gprs_context_data, 1); gcd-chat = g_at_chat_clone(chat); @@ -539,7 +559,14 @@ static int ste_gprs_context_probe(struct ofono_gprs_context *gc, ci = conn_info_create(i+1); if (!ci) return -ENOMEM; - caif_if_create(ci); + err = caif_rtnl_create_interface(IFLA_CAIF_IPV4_CONNID, + ci-channel_id, FALSE, + rtnl_callback, ci); + if (err 0) { + DBG(Failed to create IP interface for CAIF); + return err; + } + g_caif_devices = g_slist_append(g_caif_devices, ci); } @@ -571,10 +598,12 @@ static struct ofono_gprs_context_driver driver = { void ste_gprs_context_init() { + caif_rtnl_init(); ofono_gprs_context_driver_register(driver); } void ste_gprs_context_exit() { ofono_gprs_context_driver_unregister(driver); + caif_rtnl_exit(); } -- 1.7.0.4 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: ConnectionContext creation for LTE PDN Connection.
Hi Marcel, Marcel Holtmann wrote: Or should oFono automatically create a Connection Context? Furthermore, should oFono automatically proceed and set Active=true, bind the connection to a network interface and set network interface in state UP, Definitely not. This would interfere with any other existing IP connection, say WiFi. why would bringing an interface up interfere? We are doing this right now. Just the IP assignment is done by ConnMan, but the interface up/down status is controlled by oFono or even BlueZ in case of Bluetooth. So does this imply that you think oFono should set Active=true and and bring up the interface as soon as the Initial PDN is avilable? What about the ConnectionContext, should oFono automatically create a new one if needed? Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[RESEND PATCHv2 1/2] stemodem: Create network interfaces statically
From: Sjur Brændeland sjur.brandel...@stericsson.com Changes: o Restructure code so interfaces are created statically when probe is called, instead of creating interfaces dynamically at activation. o Changed debug messages. o Removed some of the unnecessary initializations at declaration. o No longer reporting default gateway for PtP IP Interface. o Bugfix: Handle network initiated deactivation. --- Resend after re-basing with latest commit: drivers: explicitly compare pointers to NULL. drivers/stemodem/gprs-context.c | 149 +- 1 files changed, 82 insertions(+), 67 deletions(-) diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index faa3124..7bdcdb8 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -28,6 +28,7 @@ #include string.h #include stdlib.h #include stdio.h +#include errno.h #include glib.h @@ -65,10 +66,18 @@ struct gprs_context_data { }; struct conn_info { + /* +* cid is allocated in oFono Core and is identifying +* the Account. cid = 0 indicates that it is currently unused. +*/ unsigned int cid; - unsigned int device; + /* Id used by CAIF and EPPSD to identify the CAIF channel*/ unsigned int channel_id; - char interface[10]; + /* Linux Interface Id */ + unsigned int ifindex; + /* Linux Interface name */ + char interface[IF_NAMESIZE]; + gboolean created; }; struct eppsd_response { @@ -76,7 +85,6 @@ struct eppsd_response { char ip_address[IP_ADDR_LEN]; char subnet_mask[IP_ADDR_LEN]; char mtu[IP_ADDR_LEN]; - char default_gateway[IP_ADDR_LEN]; char dns_server1[IP_ADDR_LEN]; char dns_server2[IP_ADDR_LEN]; char p_cscf_server[IP_ADDR_LEN]; @@ -96,8 +104,6 @@ static void start_element_handler(GMarkupParseContext *context, rsp-current = rsp-subnet_mask; else if (!strcmp(element_name, mtu)) rsp-current = rsp-mtu; - else if (!strcmp(element_name, default_gateway)) - rsp-current = rsp-default_gateway; else if (!strcmp(element_name, dns_server) rsp-dns_server1[0] == '\0') rsp-current = rsp-dns_server1; @@ -123,7 +129,7 @@ static void text_handler(GMarkupParseContext *context, if (rsp-current) { strncpy(rsp-current, text, IP_ADDR_LEN); - rsp-current[IP_ADDR_LEN] = 0; + rsp-current[IP_ADDR_LEN] = '\0'; } } @@ -153,8 +159,7 @@ static gint conn_compare_by_cid(gconstpointer a, gconstpointer b) return 0; } -static struct conn_info *conn_info_create(unsigned int device, - unsigned int channel_id) +static struct conn_info *conn_info_create(unsigned int channel_id) { struct conn_info *connection = g_try_new0(struct conn_info, 1); @@ -162,7 +167,6 @@ static struct conn_info *conn_info_create(unsigned int device, return NULL; connection-cid = 0; - connection-device = device; connection-channel_id = channel_id; return connection; @@ -171,7 +175,7 @@ static struct conn_info *conn_info_create(unsigned int device, /* * Creates a new IP interface for CAIF. */ -static gboolean caif_if_create(const char *interface, unsigned int connid) +static gboolean caif_if_create(struct conn_info *conn) { return FALSE; } @@ -179,9 +183,8 @@ static gboolean caif_if_create(const char *interface, unsigned int connid) /* * Removes IP interface for CAIF. */ -static gboolean caif_if_remove(const char *interface, unsigned int connid) +static void caif_if_remove(struct conn_info *conn) { - return FALSE; } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -210,21 +213,13 @@ static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, DBG(Did not find data (used caif device) for connection with cid; %d, gcd-active_context); - goto error; + CALLBACK_WITH_FAILURE(cb, cbd-data); + return; } conn = l-data; - - if (!caif_if_remove(conn-interface, conn-channel_id)) { - DBG(Failed to remove caif interface %s., - conn-interface); - } - conn-cid = 0; - return; - -error: - CALLBACK_WITH_FAILURE(cb, cbd-data); + CALLBACK_WITH_SUCCESS(cb, cbd-data); } static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) @@ -233,7 +228,7 @@ static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) ofono_gprs_context_up_cb_t cb = cbd-cb; struct ofono_gprs_context *gc = cbd-user; struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc
[RESEND PATCHv2 2/2] stemodem: Use RTNL to create network interfaces.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- drivers/stemodem/gprs-context.c | 44 -- 1 files changed, 37 insertions(+), 7 deletions(-) diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index bfc0d65..21ca126 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -47,6 +47,7 @@ #include stemodem.h #include caif_socket.h #include if_caif.h +#include caif_rtnl.h #define MAX_CAIF_DEVICES 4 #define MAX_DNS 2 @@ -172,12 +173,20 @@ static struct conn_info *conn_info_create(unsigned int channel_id) return connection; } -/* - * Creates a new IP interface for CAIF. - */ -static gboolean caif_if_create(struct conn_info *conn) +static void rtnl_callback(int ifindex, const char *ifname, void *user_data) { - return FALSE; + struct conn_info *conn = user_data; + + if (ifindex 0) { + conn-created = FALSE; + ofono_error(Failed to create caif interface %s, + conn-interface); + return; + } + + strncpy(conn-interface, ifname, sizeof(conn-interface)); + conn-ifindex = ifindex; + conn-created = TRUE; } /* @@ -185,6 +194,18 @@ static gboolean caif_if_create(struct conn_info *conn) */ static void caif_if_remove(struct conn_info *conn) { + if (!conn-created) + return; + + if (caif_rtnl_delete_interface(conn-ifindex) 0) { + ofono_error(Failed to delete caif interface %s, + conn-interface); + return; + } + + DBG(removed CAIF interface ch:%d ifname:%s ifindex:%d\n, + conn-channel_id, conn-interface, conn-ifindex); + return; } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -526,7 +547,7 @@ static int ste_gprs_context_probe(struct ofono_gprs_context *gc, GAtChat *chat = data; struct gprs_context_data *gcd; struct conn_info *ci; - int i; + int i,err; gcd = g_new0(struct gprs_context_data, 1); gcd-chat = g_at_chat_clone(chat); @@ -539,7 +560,14 @@ static int ste_gprs_context_probe(struct ofono_gprs_context *gc, ci = conn_info_create(i+1); if (!ci) return -ENOMEM; - caif_if_create(ci); + err = caif_rtnl_create_interface(IFLA_CAIF_IPV4_CONNID, + ci-channel_id, FALSE, + rtnl_callback, ci); + if (err 0) { + DBG(Failed to create IP interface for CAIF); + return err; + } + g_caif_devices = g_slist_append(g_caif_devices, ci); } @@ -571,10 +599,12 @@ static struct ofono_gprs_context_driver driver = { void ste_gprs_context_init() { + caif_rtnl_init(); ofono_gprs_context_driver_register(driver); } void ste_gprs_context_exit() { + caif_rtnl_exit(); ofono_gprs_context_driver_unregister(driver); } -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[RESEND PATCH] plugin: Add ste modem initd integration
From: Sjur Brændeland sjur.brandel...@stericsson.com This patch introduces auto discovery of ST-Ericsson modems. ST-Ericsson modems (M57XX, M7XX, M74XX) are managed by a Modem Init Daemon that is responsible for start/stop/restart flashing etc. This STE plugin monitors the modem state exposed from the Modem Init Damon Dbus API. When the modem is in state on the STE modem is created and registered. Currently only a single modem instance is supported, support for multiple modems should be added in the future. --- Makefile.am |5 ++ configure.ac |6 ++ plugins/stemid.c | 195 ++ 3 files changed, 206 insertions(+), 0 deletions(-) create mode 100644 plugins/stemid.c diff --git a/Makefile.am b/Makefile.am index f841b4c..aaf5de5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -81,6 +81,11 @@ gatchat_sources = gatchat/gatchat.h gatchat/gatchat.c \ udev_files = plugins/ofono.rules +if STE_MODEM_INITD +builtin_modules += stemid +builtin_sources += plugins/stemid.c +endif + if UDEV builtin_modules += udev builtin_sources += plugins/udev.c diff --git a/configure.ac b/configure.ac index c0f4217..4dff372 100644 --- a/configure.ac +++ b/configure.ac @@ -175,6 +175,12 @@ AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--disable-datafiles], AM_CONDITIONAL(DATAFILES, test ${enable_datafiles} != no) +AC_ARG_ENABLE(ste_modem_initd, AC_HELP_STRING([--disable-ste-modem-initd], + [disable auto discovery of STE modem using modem init daemon]), + [enable_ste_modem_initd=${enableval}]) + +AM_CONDITIONAL(STE_MODEM_INITD, test ${enable_ste_modem_initd} != no) + if (test ${prefix} = NONE); then dnl no prefix and no localstatedir, so default to /var if (test $localstatedir = '${prefix}/var'); then diff --git a/plugins/stemid.c b/plugins/stemid.c new file mode 100644 index 000..7041e5e --- /dev/null +++ b/plugins/stemid.c @@ -0,0 +1,195 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2010 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include errno.h +#include stdio.h +#include fcntl.h +#include stdlib.h +#include string.h +#include unistd.h +#include net/if.h + +#include gdbus.h +#include glib.h +#include gatchat.h + +#define OFONO_API_SUBJECT_TO_CHANGE +#include ofono/plugin.h +#include ofono/log.h +#include ofono/modem.h +#include ofono/dbus.h +#include ofono/version.h + +/* + * ST-Ericsson's modem init daemon defines the signal StateChange + * and the method GetState. When state is on the STE modem is + * created and registered. + */ +#define STATUS_CHANGED StateChange +#define MID_SERVICEcom.stericsson.modeminit +#define MID_INTERFACE MID_SERVICE .Modem +#define GET_STATE GetState +#define MID_STATE_ON on +#define MID_STATE_DISCONNECT disconnect +#define TIMEOUT5000 + +static struct ofono_modem *ste_modem; +static guint mid_api_watch; +static guint mid_state_watch; + +static void handle_stemodem(const char *state) +{ + + DBG(state:%s, state); + + if (strcmp(state, MID_STATE_ON) == 0) { + int err; + + if (ste_modem != NULL) + return; + + ste_modem = ofono_modem_create(ste, ste); + DBG(register STE modem); + err = ofono_modem_register(ste_modem); + } else { + + if (ste_modem == NULL) + return; + + ofono_modem_remove(ste_modem); + ste_modem = NULL; + } +} + +static void mid_getstate_reply(DBusPendingCall *call, void *user_data) +{ + DBusMessage *reply; + char *state; + + reply = dbus_pending_call_steal_reply(call); + + if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN)) { + ofono_error(STE Modem Init Daemon is unavailable); + goto error; + } + + if (dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, state, + DBUS_TYPE_INVALID) == FALSE) { + ofono_error(STE Modem Init Damon: bad signature for GetState); + goto error; + } + + handle_stemodem(state); + +error: + dbus_message_unref(reply); +} + +static
[RFCv2] doc: Assisted Satellite Navigation API and Agent API
From: Simon Lethbridge simon.lethbri...@stericsson.com This is our second proposal for the Assisted Satellite Navigation API, this time including an Agent API. Hopefully most of the review comments on our last proposal are included here. As you can see we have changed the name again, this time to Assisted Satellite Navigation. Feedback is appreciated. --- doc/assisted-sattelite-navigation.txt | 56 + 1 files changed, 56 insertions(+), 0 deletions(-) create mode 100755 doc/assisted-sattelite-navigation.txt diff --git a/doc/assisted-sattelite-navigation.txt b/doc/assisted-sattelite-navigation.txt new file mode 100755 index 000..6c85a7f --- /dev/null +++ b/doc/assisted-sattelite-navigation.txt @@ -0,0 +1,56 @@ +AssistedSatelliteNavigation hierarchy += + +Serviceorg.ofono +Interface org.ofono.AssistedSatelliteNavigation +Object path[variable prefix]/{modem0,modem1,...} + +Methodsvoid SendPositioningControl(string xml_element) + + Send an XML element conforming to the XML DTD for pos + as defined in 3GPP 27.007 Table 8.55-2. This xml is + used for transferring data associated with positioning + requests received via control plane from the network. + This includes assistance data requests and the results + of positioning procedures. This method maps directly to + the 3GPP 27.007 AT+CPOS command. + + void RegisterPositioningRequestAgent(object path) + + Registers an agent which will be called whenever a + CPOSR AT response is received. The Agent must respond + to requests using SendPositioningControl. + + void UnregisterPositioningRequestAgent(object path) + + Unregisters the agent. + +PositioningRequestAgent hierarchy +== + +Serviceunique name +Interface org.ofono.PositioningRequestAgent +Object pathfreely definable + +Methodsvoid PositioningRequest(string xml_element) + + Receive an XML element conforming to the XML DTD for + pos in 3GPP 27.007. This xml is used for transferring + data associated with positioning requests received, via + control plane, from the network. This includes + measurement requests and assistance data. This method + maps directly to the 3GPP defined +CPOSR unsolicited + result code. + + void AssistanceDataReset() + + A request has been received from the network that all + assistance data should be reset. This is used for 3gpp + performance tests. + + void Release() + + Agent is being released, possibly because of oFono + terminating, AssistedSatelliteNavigation interface + is being torn down or modem off. + No UnregisterAgent call is needed. -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v2 1/2] stemodem: Create network interfaces statically
From: Sjur Brændeland sjur.brandel...@stericsson.com Changes: o Restructure code so interfaces are created statically when probe is called. o Removed some of the unnecessary initializations at declaration. o No longer reporting default gateway on PtP IP Interface. o Bugfix: Handle network initiated deactivation. --- Changes from V1: o Removed unused label drivers/stemodem/gprs-context.c | 151 +- 1 files changed, 83 insertions(+), 68 deletions(-) diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index 05fec3f..3ccda87 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -28,6 +28,7 @@ #include string.h #include stdlib.h #include stdio.h +#include errno.h #include glib.h @@ -65,10 +66,18 @@ struct gprs_context_data { }; struct conn_info { + /* +* cid is allocated in oFono Core and is identifying +* the Account. cid = 0 indicates that it is currently unused. +*/ unsigned int cid; - unsigned int device; + /* Id used by CAIF and EPPSD to identify the CAIF channel*/ unsigned int channel_id; - char interface[10]; + /* Linux Interface Id */ + unsigned int ifindex; + /* Linux Interface name */ + char interface[IF_NAMESIZE]; + gboolean created; }; struct eppsd_response { @@ -76,7 +85,6 @@ struct eppsd_response { char ip_address[IP_ADDR_LEN]; char subnet_mask[IP_ADDR_LEN]; char mtu[IP_ADDR_LEN]; - char default_gateway[IP_ADDR_LEN]; char dns_server1[IP_ADDR_LEN]; char dns_server2[IP_ADDR_LEN]; char p_cscf_server[IP_ADDR_LEN]; @@ -96,8 +104,6 @@ static void start_element_handler(GMarkupParseContext *context, rsp-current = rsp-subnet_mask; else if (!strcmp(element_name, mtu)) rsp-current = rsp-mtu; - else if (!strcmp(element_name, default_gateway)) - rsp-current = rsp-default_gateway; else if (!strcmp(element_name, dns_server) rsp-dns_server1[0] == '\0') rsp-current = rsp-dns_server1; @@ -123,7 +129,7 @@ static void text_handler(GMarkupParseContext *context, if (rsp-current) { strncpy(rsp-current, text, IP_ADDR_LEN); - rsp-current[IP_ADDR_LEN] = 0; + rsp-current[IP_ADDR_LEN] = '\0'; } } @@ -153,8 +159,7 @@ static gint conn_compare_by_cid(gconstpointer a, gconstpointer b) return 0; } -static struct conn_info *conn_info_create(unsigned int device, - unsigned int channel_id) +static struct conn_info *conn_info_create(unsigned int channel_id) { struct conn_info *connection = g_try_new0(struct conn_info, 1); @@ -162,7 +167,6 @@ static struct conn_info *conn_info_create(unsigned int device, return NULL; connection-cid = 0; - connection-device = device; connection-channel_id = channel_id; return connection; @@ -171,7 +175,7 @@ static struct conn_info *conn_info_create(unsigned int device, /* * Creates a new IP interface for CAIF. */ -static gboolean caif_if_create(const char *interface, unsigned int connid) +static gboolean caif_if_create(struct conn_info *conn) { return FALSE; } @@ -179,9 +183,8 @@ static gboolean caif_if_create(const char *interface, unsigned int connid) /* * Removes IP interface for CAIF. */ -static gboolean caif_if_remove(const char *interface, unsigned int connid) +static void caif_if_remove(struct conn_info *conn) { - return FALSE; } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -210,21 +213,13 @@ static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, DBG(Did not find data (used caif device) for connection with cid; %d, gcd-active_context); - goto error; + CALLBACK_WITH_FAILURE(cb, cbd-data); + return; } conn = l-data; - - if (!caif_if_remove(conn-interface, conn-channel_id)) { - DBG(Failed to remove caif interface %s., - conn-interface); - } - conn-cid = 0; - return; - -error: - CALLBACK_WITH_FAILURE(cb, cbd-data); + CALLBACK_WITH_SUCCESS(cb, cbd-data); } static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) @@ -233,7 +228,7 @@ static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) ofono_gprs_context_up_cb_t cb = cbd-cb; struct ofono_gprs_context *gc = cbd-user; struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); - struct conn_info *conn = NULL; + struct conn_info *conn; GAtResultIter iter; GSList *l; int i
[PATCH v2 2/2] stemodem: Use RTNL to create network interfaces.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- drivers/stemodem/gprs-context.c | 43 ++- 1 files changed, 42 insertions(+), 1 deletions(-) diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index 3ccda87..3859107 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -47,6 +47,7 @@ #include stemodem.h #include caif_socket.h #include if_caif.h +#include caif_rtnl.h #define MAX_CAIF_DEVICES 4 #define MAX_DNS 2 @@ -172,12 +173,38 @@ static struct conn_info *conn_info_create(unsigned int channel_id) return connection; } +static void rtnl_callback(int ifindex, const char *ifname, void *user_data) +{ + struct conn_info *conn = user_data; + + if (ifindex 0) { + conn-created = FALSE; + ofono_error(Failed to create caif interface %s, + conn-interface); + return; + } + + strncpy(conn-interface, ifname, sizeof(conn-interface)); + conn-ifindex = ifindex; + conn-created = TRUE; +} + /* * Creates a new IP interface for CAIF. */ static gboolean caif_if_create(struct conn_info *conn) { - return FALSE; + int err; + + err = caif_rtnl_create_interface(IFLA_CAIF_IPV4_CONNID, + conn-channel_id, FALSE, + rtnl_callback, conn); + if (err 0) { + DBG(Failed to create IP interface for CAIF); + return FALSE; + } + + return TRUE; } /* @@ -185,6 +212,18 @@ static gboolean caif_if_create(struct conn_info *conn) */ static void caif_if_remove(struct conn_info *conn) { + if (!conn-created) + return; + + if (caif_rtnl_delete_interface(conn-ifindex) 0) { + ofono_error(Failed to delete caif interface %s, + conn-interface); + return; + } + + DBG(removed CAIF interface ch:%d ifname:%s ifindex:%d\n, + conn-channel_id, conn-interface, conn-ifindex); + return; } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -571,10 +610,12 @@ static struct ofono_gprs_context_driver driver = { void ste_gprs_context_init() { + caif_rtnl_init(); ofono_gprs_context_driver_register(driver); } void ste_gprs_context_exit() { + caif_rtnl_exit(); ofono_gprs_context_driver_unregister(driver); } -- 1.7.0.4 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH RESEND] stemodem: Change use of types
From: Sjur Brændeland sjur.brandel...@stericsson.com Use the type __u32 for sequence counting rather than guint32, and void * instead of gpointer. Reduce the size of RTNL message buffer from 4096 to 1024, as this should be sufficient to hold the NEWLINK message. --- Last patch was sent with base64 encoding :-( drivers/stemodem/caif_rtnl.c | 14 +++--- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/stemodem/caif_rtnl.c b/drivers/stemodem/caif_rtnl.c index 5d4073a..4c00446 100644 --- a/drivers/stemodem/caif_rtnl.c +++ b/drivers/stemodem/caif_rtnl.c @@ -41,7 +41,7 @@ #define NLMSG_TAIL(nmsg) \ ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len))) -#define RTNL_MSG_SIZE 4096 +#define RTNL_MSG_SIZE 1024 struct rtnl_msg { struct nlmsghdr n; @@ -50,17 +50,17 @@ struct rtnl_msg { }; struct iplink_req { - guint32 rtnlmsg_seqnr; - gpointer user_data; + __u32 rtnlmsg_seqnr; + void *user_data; caif_rtnl_create_cb_t callback; }; static GSList *pending_requests; -static guint32 rtnl_seqnr; +static __u32 rtnl_seqnr; static guint rtnl_watch; static GIOChannel *rtnl_channel; -static struct iplink_req *find_request(guint32 seq) +static struct iplink_req *find_request(__u32 seq) { GSList *list; @@ -169,7 +169,7 @@ static int add_attribute(struct nlmsghdr *n, unsigned int maxlen, int type, return 0; } -static inline void prep_rtnl_req(struct rtnl_msg *msg, int reqtype, guint seqnr) +static inline void prep_rtnl_req(struct rtnl_msg *msg, int reqtype, __u32 seqnr) { msg-n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); msg-n.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL; @@ -179,7 +179,7 @@ static inline void prep_rtnl_req(struct rtnl_msg *msg, int reqtype, guint seqnr) } static gboolean netlink_event(GIOChannel *chan, - GIOCondition cond, gpointer data) + GIOCondition cond, void *data) { unsigned char buf[RTNL_MSG_SIZE]; int len, sk; -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 0/2] unit: STE Unit Tests
From: Sjur Brændeland sjur.brandel...@stericsson.com This patch set introduces unit tests for functionality in o CAIF RTNL functions in drivers/stemodem/caif_rtnl.c o GPRS context handling in drivers/stemodem/gprs-context.c o Radio State settings in drivers/stemodem/radio-settings.c o Test for CAIF Character devices are removed as this is not supported by upstream version of CAIF. The unit tests calls functions in the driver and simulates AT-responses received from the modem. Patches should apply and compile cleanly. Successful execution depends on patches: stemodem: Create network interfaces statically stemodem: Use RTNL to create network interfaces. Sjur Brændeland (2): unit: CAIF test: remove character dev tests and add RTNL. unit: Add unit tests for STE modem Makefile.am | 19 ++- unit/test-caif.c | 108 +++ unit/test-ste.c | 554 ++ 3 files changed, 645 insertions(+), 36 deletions(-) create mode 100644 unit/test-ste.c ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 1/2] unit: CAIF test: remove character dev tests and add RTNL.
From: Sjur Brændeland sjur.brandel...@stericsson.com - Remove tests for CAIF Character device. Character devices are depreceated and replaced with Sockets. - Add RTNL Tests for creating and removing CAIF GPRS Network Interface. --- Makefile.am |4 +- unit/test-caif.c | 108 +- 2 files changed, 77 insertions(+), 35 deletions(-) diff --git a/Makefile.am b/Makefile.am index f841b4c..e505a39 100644 --- a/Makefile.am +++ b/Makefile.am @@ -474,7 +474,9 @@ unit_objects += $(unit_test_mux_OBJECTS) unit_test_caif_SOURCES = unit/test-caif.c $(gatchat_sources) \ drivers/stemodem/caif_socket.h \ - drivers/stemodem/if_caif.h + drivers/stemodem/caif_rtnl.c \ + drivers/stemodem/caif_rtnl.h \ + drivers/stemodem/if_caif.h unit_test_caif_LDADD = @GLIB_LIBS@ unit_objects += $(unit_test_caif_OBJECTS) diff --git a/unit/test-caif.c b/unit/test-caif.c index 51e29bc..fdcdc3e 100644 --- a/unit/test-caif.c +++ b/unit/test-caif.c @@ -3,6 +3,7 @@ * oFono - Open Source Telephony * * Copyright (C) 2008-2010 Intel Corporation. All rights reserved. + * Copyright (C) 2010 ST-Ericsson AB. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -28,28 +29,26 @@ #include unistd.h #include stdlib.h #include string.h +#include net/if.h #include glib.h #include glib/gprintf.h #include gatchat.h - +#include ofono/log.h #include drivers/stemodem/caif_socket.h #include drivers/stemodem/if_caif.h +#include drivers/stemodem/caif_rtnl.h static GMainLoop *mainloop; -static int do_open(void) +void ofono_debug(const char *format, ...) { - int fd; - - fd = open(/dev/chnlat11, O_RDWR); - if (fd 0) { - g_printerr(Open of chnlat11 failed (%d)\n, errno); - return -EIO; - } - - return fd; + va_list ap; + va_start(ap, format); + if (g_test_verbose()) + vprintf(format, ap); + va_end(ap); } static int do_connect(void) @@ -58,7 +57,7 @@ static int do_connect(void) int sk, err; /* Create a CAIF socket for AT Service */ - sk = socket(AF_CAIF, SOCK_SEQPACKET, CAIFPROTO_AT); + sk = socket(AF_CAIF, SOCK_STREAM, CAIFPROTO_AT); if (sk 0) { g_printerr(CAIF socket creation failed (%d)\n, errno); return -EIO; @@ -81,7 +80,8 @@ static int do_connect(void) static void caif_debug(const char *str, void *data) { - g_print(%s\n, str); + if (g_test_verbose()) + g_print(CAIF:%s\n, str); } static void caif_init(gboolean ok, GAtResult *result, gpointer data) @@ -100,18 +100,15 @@ static void caif_init(gboolean ok, GAtResult *result, gpointer data) g_main_loop_quit(mainloop); } -static void test_connect(gboolean use_socket) +static void test_connect() { GIOChannel *io; GAtChat *chat; GAtSyntax *syntax; int fd; - if (use_socket == TRUE) - fd = do_connect(); - else - fd = do_open(); + fd = do_connect(); if (fd 0) return; @@ -138,34 +135,77 @@ static void test_connect(gboolean use_socket) g_main_loop_unref(mainloop); } -static void test_basic(void) +/* Storage for rtnl_callback data */ +static int rtnl_result; +static int rtnl_ifi; +static char rtnl_ifname[16]; +static void *rtnl_user_data; + +static void rtnl_create_cb(int ifindex, const char *ifname, void *user_data) { - if (g_test_trap_fork(60 * 1000 * 1000, 0) == TRUE) { - test_connect(TRUE); - exit(0); - } + strcpy(rtnl_ifname, ifname); + rtnl_ifi = ifindex; + rtnl_user_data = user_data; +} + +static void test_rtnl_normal() +{ + int res; + int connid = 1; + + res = caif_rtnl_init(); + res = caif_rtnl_create_interface(IFLA_CAIF_IPV4_CONNID, connid, FALSE, + rtnl_create_cb, + (void *)0xbaadf00d); + g_assert_cmpint(0, ==, res); + + g_main_iteration(TRUE); - g_test_trap_assert_passed(); - //g_test_trap_assert_stderr(failed); + g_assert_cmpint(0, ==, rtnl_result); + g_assert((void *)0xbaadf00d == rtnl_user_data); + + res = caif_rtnl_delete_interface(rtnl_ifi); + + g_main_iteration(TRUE); + g_assert_cmpint(0, ==, res); + + caif_rtnl_exit(); } -static void test_chnlat(void) +static void test_rtnl_bad_delete() { - if (g_test_trap_fork(60 * 1000 * 1000, 0) == TRUE) { - test_connect(FALSE); - exit(0); - } + int res
Re: [PATCH v2 2/2] stemodem: Use RTNL to create network interfaces.
Hi George. it looks as if two functions: caif_if_create/remove (struct conn_info *conn) do nothing but verify the return results of functions: caif_rtnl_create_interface/caif_rtnl_delete_interface declared in in caif_rtnl.h Which means if you #include caif_rtnl.h in gprs-context.c create/delete_interface will be available directly without any wrappers and could make your code run a bit faster and easier to understand? Unless I missed something. Thank you for reviewing this patch :-) Yes, you are right concerning caif_if_create, I'll change this. But caif_if_remove needs to stay as is, it is called from g_slist_foreach and must have the list node as argument. BTW you should take a look at http://ofono.org/wiki/ofono-etiquette. Top-posting is not exactly popular on this list ;-) Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCHv3 1/2] stemodem: Create network interfaces statically
From: Sjur Brændeland sjur.brandel...@stericsson.com Changes: o Restructure code so interfaces are created statically when probe is called. o Removed some of the unnecessary initializations at declaration. o No longer reporting default gateway on PtP IP Interface. o Bugfix: Handle network initiated deactivation. --- No changes from v2. drivers/stemodem/gprs-context.c | 151 +- 1 files changed, 83 insertions(+), 68 deletions(-) diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index 05fec3f..3ccda87 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -28,6 +28,7 @@ #include string.h #include stdlib.h #include stdio.h +#include errno.h #include glib.h @@ -65,10 +66,18 @@ struct gprs_context_data { }; struct conn_info { + /* +* cid is allocated in oFono Core and is identifying +* the Account. cid = 0 indicates that it is currently unused. +*/ unsigned int cid; - unsigned int device; + /* Id used by CAIF and EPPSD to identify the CAIF channel*/ unsigned int channel_id; - char interface[10]; + /* Linux Interface Id */ + unsigned int ifindex; + /* Linux Interface name */ + char interface[IF_NAMESIZE]; + gboolean created; }; struct eppsd_response { @@ -76,7 +85,6 @@ struct eppsd_response { char ip_address[IP_ADDR_LEN]; char subnet_mask[IP_ADDR_LEN]; char mtu[IP_ADDR_LEN]; - char default_gateway[IP_ADDR_LEN]; char dns_server1[IP_ADDR_LEN]; char dns_server2[IP_ADDR_LEN]; char p_cscf_server[IP_ADDR_LEN]; @@ -96,8 +104,6 @@ static void start_element_handler(GMarkupParseContext *context, rsp-current = rsp-subnet_mask; else if (!strcmp(element_name, mtu)) rsp-current = rsp-mtu; - else if (!strcmp(element_name, default_gateway)) - rsp-current = rsp-default_gateway; else if (!strcmp(element_name, dns_server) rsp-dns_server1[0] == '\0') rsp-current = rsp-dns_server1; @@ -123,7 +129,7 @@ static void text_handler(GMarkupParseContext *context, if (rsp-current) { strncpy(rsp-current, text, IP_ADDR_LEN); - rsp-current[IP_ADDR_LEN] = 0; + rsp-current[IP_ADDR_LEN] = '\0'; } } @@ -153,8 +159,7 @@ static gint conn_compare_by_cid(gconstpointer a, gconstpointer b) return 0; } -static struct conn_info *conn_info_create(unsigned int device, - unsigned int channel_id) +static struct conn_info *conn_info_create(unsigned int channel_id) { struct conn_info *connection = g_try_new0(struct conn_info, 1); @@ -162,7 +167,6 @@ static struct conn_info *conn_info_create(unsigned int device, return NULL; connection-cid = 0; - connection-device = device; connection-channel_id = channel_id; return connection; @@ -171,7 +175,7 @@ static struct conn_info *conn_info_create(unsigned int device, /* * Creates a new IP interface for CAIF. */ -static gboolean caif_if_create(const char *interface, unsigned int connid) +static gboolean caif_if_create(struct conn_info *conn) { return FALSE; } @@ -179,9 +183,8 @@ static gboolean caif_if_create(const char *interface, unsigned int connid) /* * Removes IP interface for CAIF. */ -static gboolean caif_if_remove(const char *interface, unsigned int connid) +static void caif_if_remove(struct conn_info *conn) { - return FALSE; } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -210,21 +213,13 @@ static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, DBG(Did not find data (used caif device) for connection with cid; %d, gcd-active_context); - goto error; + CALLBACK_WITH_FAILURE(cb, cbd-data); + return; } conn = l-data; - - if (!caif_if_remove(conn-interface, conn-channel_id)) { - DBG(Failed to remove caif interface %s., - conn-interface); - } - conn-cid = 0; - return; - -error: - CALLBACK_WITH_FAILURE(cb, cbd-data); + CALLBACK_WITH_SUCCESS(cb, cbd-data); } static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) @@ -233,7 +228,7 @@ static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) ofono_gprs_context_up_cb_t cb = cbd-cb; struct ofono_gprs_context *gc = cbd-user; struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); - struct conn_info *conn = NULL; + struct conn_info *conn; GAtResultIter iter; GSList *l; int i; @@ -241,17 +236,15
Re: [PATCH 1/2] stemodem: Create network interfaces statically
Hi Denis Marcel. From: Sjur Brændeland sjur.brandel...@stericsson.com Changes: o Restructure code so interfaces are created statically when probe is called. o Removed some of the unnecessary initializations at declaration. o No longer reporting default gateway on PtP IP Interface. o Bugfix: Handle network initiated deactivation. --- drivers/stemodem/gprs-context.c | 153 ++- 1 files changed, 85 insertions(+), 68 deletions(-) diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index 05fec3f..d8db23b 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c Have you received this patch in readable format? I'm sending patches using git send-email over gmail, and when I check sent items in gmail, it comes up as base64 encoded. Is this garbled for you as well? BTW are you using patchwork or similar so I could check the patch status somewhere? Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] plugin: Add ste modem initd integration
From: Sjur Brændeland sjur.brandel...@stericsson.com This patch introduces auto discovery of ST-Ericsson modems. ST-Ericsson modems are managed by a Modem Init Daemon that is responsible for start/stop/restart flashing etc. The STE plugin monitors the modem state exposed from the Modem Init Damon Dbus API. When the modem is in state on the STE modem is created and registered. --- Makefile.am |5 ++ configure.ac |6 ++ plugins/stemid.c | 195 ++ 3 files changed, 206 insertions(+), 0 deletions(-) create mode 100644 plugins/stemid.c diff --git a/Makefile.am b/Makefile.am index f841b4c..aaf5de5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -81,6 +81,11 @@ gatchat_sources = gatchat/gatchat.h gatchat/gatchat.c \ udev_files = plugins/ofono.rules +if STE_MODEM_INITD +builtin_modules += stemid +builtin_sources += plugins/stemid.c +endif + if UDEV builtin_modules += udev builtin_sources += plugins/udev.c diff --git a/configure.ac b/configure.ac index 6aeab7c..6fafadd 100644 --- a/configure.ac +++ b/configure.ac @@ -175,6 +175,12 @@ AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--disable-datafiles], AM_CONDITIONAL(DATAFILES, test ${enable_datafiles} != no) +AC_ARG_ENABLE(ste_modem_initd, AC_HELP_STRING([--disable-ste-modem-initd], + [disable auto discovery of STE modem using modem init daemon]), + [enable_ste_modem_initd=${enableval}]) + +AM_CONDITIONAL(STE_MODEM_INITD, test ${enable_ste_modem_initd} != no) + if (test ${prefix} = NONE); then dnl no prefix and no localstatedir, so default to /var if (test $localstatedir = '${prefix}/var'); then diff --git a/plugins/stemid.c b/plugins/stemid.c new file mode 100644 index 000..7041e5e --- /dev/null +++ b/plugins/stemid.c @@ -0,0 +1,195 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2010 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include errno.h +#include stdio.h +#include fcntl.h +#include stdlib.h +#include string.h +#include unistd.h +#include net/if.h + +#include gdbus.h +#include glib.h +#include gatchat.h + +#define OFONO_API_SUBJECT_TO_CHANGE +#include ofono/plugin.h +#include ofono/log.h +#include ofono/modem.h +#include ofono/dbus.h +#include ofono/version.h + +/* + * ST-Ericsson's modem init daemon defines the signal StateChange + * and the method GetState. When state is on the STE modem is + * created and registered. + */ +#define STATUS_CHANGED StateChange +#define MID_SERVICEcom.stericsson.modeminit +#define MID_INTERFACE MID_SERVICE .Modem +#define GET_STATE GetState +#define MID_STATE_ON on +#define MID_STATE_DISCONNECT disconnect +#define TIMEOUT5000 + +static struct ofono_modem *ste_modem; +static guint mid_api_watch; +static guint mid_state_watch; + +static void handle_stemodem(const char *state) +{ + + DBG(state:%s, state); + + if (strcmp(state, MID_STATE_ON) == 0) { + int err; + + if (ste_modem != NULL) + return; + + ste_modem = ofono_modem_create(ste, ste); + DBG(register STE modem); + err = ofono_modem_register(ste_modem); + } else { + + if (ste_modem == NULL) + return; + + ofono_modem_remove(ste_modem); + ste_modem = NULL; + } +} + +static void mid_getstate_reply(DBusPendingCall *call, void *user_data) +{ + DBusMessage *reply; + char *state; + + reply = dbus_pending_call_steal_reply(call); + + if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN)) { + ofono_error(STE Modem Init Daemon is unavailable); + goto error; + } + + if (dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, state, + DBUS_TYPE_INVALID) == FALSE) { + ofono_error(STE Modem Init Damon: bad signature for GetState); + goto error; + } + + handle_stemodem(state); + +error: + dbus_message_unref(reply); +} + +static gboolean mid_signal_status_change(DBusConnection *connection, + DBusMessage *message, void *user_data
Re: [PATCH] doc: Add Location Services API
Hi Marcel. So far this looks like a nice and simple proposal. And it is driven by an existing standard. I like that. Sjur, are you guys up to the task of sending an initial atom implementation and atmodem driver for it? Yes, I think we should be able to, as longs as there is no big hurry. I'll send a patch on the TODO shortly. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] coding-style: Add exception to M12 rule for external enums
From: Sjur Brændeland sjur.brandel...@stericsson.com --- doc/coding-style.txt |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/doc/coding-style.txt b/doc/coding-style.txt index 6fa355e..fb43891 100644 --- a/doc/coding-style.txt +++ b/doc/coding-style.txt @@ -205,6 +205,10 @@ default: // wrong break; } +However if the enum comes from an external header file outside ofono +we cannot make any assumption of how the enum is defined and this +rule might not apply. + O1: Shorten the name Better to use abbreviation, rather than full name, to name a variable, -- 1.7.0.4 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] todo: Add Location Service (AGPS) task.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- TODO |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/TODO b/TODO index bf2305b..dec43fd 100644 --- a/TODO +++ b/TODO @@ -496,3 +496,11 @@ Miscellaneous Priority: Low Complexity: C4 + +- Add Location Service API for providing basic E911 suport. + This will be based on the 27.007 defined AT commands using + XML for transport of positioning request and responses. + + Priority: Medium + Complexity: C2 + Owner: Sjur Brændeland sjur.brandel...@stericsson.com -- 1.7.0.4 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] stemodem: Change use of types
From: Sjur Brændeland sjur.brandel...@stericsson.com Use the type __u32 for sequence counting rather than guint32, and void * instead of gpointer. Reduce the size of RTNL message buffer from 4096 to 1024, as this should be sufficient to hold the NEWLINK message. --- drivers/stemodem/caif_rtnl.c | 14 +++--- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/stemodem/caif_rtnl.c b/drivers/stemodem/caif_rtnl.c index 5d4073a..4c00446 100644 --- a/drivers/stemodem/caif_rtnl.c +++ b/drivers/stemodem/caif_rtnl.c @@ -41,7 +41,7 @@ #define NLMSG_TAIL(nmsg) \ ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len))) -#define RTNL_MSG_SIZE 4096 +#define RTNL_MSG_SIZE 1024 struct rtnl_msg { struct nlmsghdr n; @@ -50,17 +50,17 @@ struct rtnl_msg { }; struct iplink_req { - guint32 rtnlmsg_seqnr; - gpointer user_data; + __u32 rtnlmsg_seqnr; + void *user_data; caif_rtnl_create_cb_t callback; }; static GSList *pending_requests; -static guint32 rtnl_seqnr; +static __u32 rtnl_seqnr; static guint rtnl_watch; static GIOChannel *rtnl_channel; -static struct iplink_req *find_request(guint32 seq) +static struct iplink_req *find_request(__u32 seq) { GSList *list; @@ -169,7 +169,7 @@ static int add_attribute(struct nlmsghdr *n, unsigned int maxlen, int type, return 0; } -static inline void prep_rtnl_req(struct rtnl_msg *msg, int reqtype, guint seqnr) +static inline void prep_rtnl_req(struct rtnl_msg *msg, int reqtype, __u32 seqnr) { msg-n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); msg-n.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL; @@ -179,7 +179,7 @@ static inline void prep_rtnl_req(struct rtnl_msg *msg, int reqtype, guint seqnr) } static gboolean netlink_event(GIOChannel *chan, - GIOCondition cond, gpointer data) + GIOCondition cond, void *data) { unsigned char buf[RTNL_MSG_SIZE]; int len, sk; -- 1.7.0.4 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCH v5b 2/3] stemodem: Create network interfaces statically
Hi Marcel. - struct conn_info *conn; + struct conn_info *conn = NULL; GSList *l; why do you need the conn = NULL assignment here? I haven't even looked into your code flow, but I prefer clearly to not have these. I have removed this and tried to remove some of the other initialisations at declaration as well. New patch set on the remaining gprs-context changes is on it's way :-) Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v5] stemodem: Add RTNL functionality managing CAIF Network Interfaces.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- Makefile.am |2 + drivers/stemodem/caif_rtnl.c | 340 ++ drivers/stemodem/caif_rtnl.h | 29 3 files changed, 371 insertions(+), 0 deletions(-) create mode 100644 drivers/stemodem/caif_rtnl.c create mode 100644 drivers/stemodem/caif_rtnl.h diff --git a/Makefile.am b/Makefile.am index 05082de..f163b0a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -226,6 +226,8 @@ builtin_sources += drivers/atmodem/atutil.h \ drivers/stemodem/stemodem.c \ drivers/stemodem/voicecall.c \ drivers/stemodem/radio-settings.c \ + drivers/stemodem/caif_rtnl.c \ + drivers/stemodem/caif_rtnl.h \ drivers/stemodem/gprs-context.c \ drivers/stemodem/caif_socket.h \ drivers/stemodem/if_caif.h diff --git a/drivers/stemodem/caif_rtnl.c b/drivers/stemodem/caif_rtnl.c new file mode 100644 index 000..4ce2401 --- /dev/null +++ b/drivers/stemodem/caif_rtnl.c @@ -0,0 +1,340 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2010 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include string.h +#include unistd.h +#include errno.h +#include net/if.h +#include net/if_arp.h +#include fcntl.h +#include linux/rtnetlink.h + +#include glib.h + +#include ofono/log.h + +#include if_caif.h +#include caif_rtnl.h + +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len))) + +#define RTNL_MSG_SIZE 4096 + +struct rtnl_msg { + struct nlmsghdr n; + struct ifinfomsg i; + char data[RTNL_MSG_SIZE]; +}; + +struct iplink_req { + guint32 rtnlmsg_seqnr; + gpointer user_data; + caif_rtnl_create_cb_t callback; +}; + +static GSList *pending_requests; +static guint32 rtnl_seqnr; +static guint rtnl_watch; +static GIOChannel *rtnl_channel; + +static struct iplink_req *find_request(guint32 seq) +{ + GSList *list; + + for (list = pending_requests; list; list = list-next) { + struct iplink_req *req = list-data; + + if (req-rtnlmsg_seqnr == seq) + return req; + } + + return NULL; +} + +static void parse_newlink_param(struct ifinfomsg *msg, int size, + int *ifindex, char *ifname) +{ + struct rtattr *attr; + + for (attr = IFLA_RTA(msg); RTA_OK(attr, size); + attr = RTA_NEXT(attr, size)) { + + if (attr-rta_type == IFLA_IFNAME + ifname != NULL) { + + strncpy(ifname, RTA_DATA(attr), IF_NAMESIZE); + ifname[IF_NAMESIZE-1] = '\0'; + break; + } + } + + *ifindex = msg-ifi_index; +} + +static void parse_rtnl_message(const void *buf, size_t len) +{ + struct ifinfomsg *msg; + struct iplink_req *req = NULL; + char ifname[IF_NAMESIZE]; + int ifindex; + + while (len 0) { + const struct nlmsghdr *hdr = buf; + + if (!NLMSG_OK(hdr, len)) + break; + + switch (hdr-nlmsg_type) { + case RTM_NEWLINK: + req = g_slist_nth_data(pending_requests, 0); + if (req == NULL) + break; + + msg = (struct ifinfomsg *) NLMSG_DATA(hdr); + parse_newlink_param(msg, IFA_PAYLOAD(hdr), + ifindex, ifname); + + if (req-callback) + req-callback(ifindex, ifname, req-user_data); + break; + + case NLMSG_ERROR: + req = find_request(hdr-nlmsg_seq); + if (req == NULL) + break; + + DBG(nlmsg error req); + if (req-callback) + req-callback(-1, ifname, req-user_data); + break; + default
[PATCH v5b 2/3] stemodem: Create network interfaces statically
From: Sjur Brændeland sjur.brandel...@stericsson.com Create the network interfaces statically at start up instead of dynamically for each PDP activation. --- drivers/stemodem/gprs-context.c | 98 -- 1 files changed, 52 insertions(+), 46 deletions(-) diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index 05fec3f..62643ee 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -28,6 +28,7 @@ #include string.h #include stdlib.h #include stdio.h +#include errno.h #include glib.h @@ -153,8 +154,7 @@ static gint conn_compare_by_cid(gconstpointer a, gconstpointer b) return 0; } -static struct conn_info *conn_info_create(unsigned int device, - unsigned int channel_id) +static struct conn_info *conn_info_create(unsigned int channel_id) { struct conn_info *connection = g_try_new0(struct conn_info, 1); @@ -162,7 +162,6 @@ static struct conn_info *conn_info_create(unsigned int device, return NULL; connection-cid = 0; - connection-device = device; connection-channel_id = channel_id; return connection; @@ -171,7 +170,7 @@ static struct conn_info *conn_info_create(unsigned int device, /* * Creates a new IP interface for CAIF. */ -static gboolean caif_if_create(const char *interface, unsigned int connid) +static gboolean caif_if_create(struct conn_info *conn) { return FALSE; } @@ -179,9 +178,8 @@ static gboolean caif_if_create(const char *interface, unsigned int connid) /* * Removes IP interface for CAIF. */ -static gboolean caif_if_remove(const char *interface, unsigned int connid) +static void caif_if_remove(struct conn_info *conn) { - return FALSE; } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -191,7 +189,7 @@ static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, ofono_gprs_context_cb_t cb = cbd-cb; struct ofono_gprs_context *gc = cbd-user; struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); - struct conn_info *conn; + struct conn_info *conn = NULL; GSList *l; if (!ok) { @@ -214,13 +212,8 @@ static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, } conn = l-data; - - if (!caif_if_remove(conn-interface, conn-channel_id)) { - DBG(Failed to remove caif interface %s., - conn-interface); - } - conn-cid = 0; + CALLBACK_WITH_SUCCESS(cb, cbd-data); return; error: @@ -248,9 +241,7 @@ static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) conn_compare_by_cid); if (!l) { - DBG(Did not find data (device and channel id) - for connection with cid; %d, - gcd-active_context); + DBG(CAIF Device gone missing (cid:%d), gcd-active_context); goto error; } @@ -291,20 +282,9 @@ static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) dns[1] = rsp.dns_server2; dns[2] = NULL; - sprintf(conn-interface, caif%u, conn-device); - - if (!caif_if_create(conn-interface, conn-channel_id)) { - ofono_error(Failed to create caif interface %s., - conn-interface); - CALLBACK_WITH_SUCCESS(cb, NULL, FALSE, rsp.ip_address, + CALLBACK_WITH_SUCCESS(cb, conn-interface, TRUE, rsp.ip_address, rsp.subnet_mask, rsp.default_gateway, dns, cbd-data); - } else { - CALLBACK_WITH_SUCCESS(cb, conn-interface, - FALSE, rsp.ip_address, rsp.subnet_mask, - rsp.default_gateway, dns, cbd-data); - } - return; error: @@ -316,6 +296,7 @@ error: if (conn) conn-cid = 0; + gcd-active_context = 0; CALLBACK_WITH_FAILURE(cb, NULL, 0, NULL, NULL, NULL, NULL, cbd-data); } @@ -327,38 +308,43 @@ static void ste_cgdcont_cb(gboolean ok, GAtResult *result, gpointer user_data) struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct cb_data *ncbd = NULL; char buf[128]; - struct conn_info *conn; + struct conn_info *conn = NULL; GSList *l; + l = g_slist_find_custom(g_caif_devices, + GUINT_TO_POINTER(gcd-active_context), + conn_compare_by_cid); + + if (!l) { + DBG(CAIF Device gone missing (cid:%d), gcd-active_context); + goto error; + } + + conn = l-data; + if (!ok) { struct ofono_error error; + conn-cid = 0
[PATCH v5b 3/3] stemodem: Use RTNL to create interfaces
From: Sjur Brændeland sjur.brandel...@stericsson.com Use rtnl_caif_* functions to create network interfaces. The conn_info struct is also re-structured in order to hold the relevant information for network interfaces. --- drivers/stemodem/gprs-context.c | 76 ++- 1 files changed, 67 insertions(+), 9 deletions(-) diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index 62643ee..8b5cfdc 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -47,6 +47,7 @@ #include stemodem.h #include caif_socket.h #include if_caif.h +#include caif_rtnl.h #define MAX_CAIF_DEVICES 4 #define MAX_DNS 2 @@ -66,10 +67,18 @@ struct gprs_context_data { }; struct conn_info { + /* +* cid is allocated in oFono Core and is identifying +* the Account. cid = 0 indicates that it is currently unused. +*/ unsigned int cid; - unsigned int device; + /* Id used by CAIF and EPPSD to identify the CAIF channel*/ unsigned int channel_id; - char interface[10]; + /* Linux Interface Id */ + unsigned int ifindex; + /* Linux Interface name */ + char interface[IF_NAMESIZE]; + gboolean created; }; struct eppsd_response { @@ -77,7 +86,6 @@ struct eppsd_response { char ip_address[IP_ADDR_LEN]; char subnet_mask[IP_ADDR_LEN]; char mtu[IP_ADDR_LEN]; - char default_gateway[IP_ADDR_LEN]; char dns_server1[IP_ADDR_LEN]; char dns_server2[IP_ADDR_LEN]; char p_cscf_server[IP_ADDR_LEN]; @@ -97,8 +105,6 @@ static void start_element_handler(GMarkupParseContext *context, rsp-current = rsp-subnet_mask; else if (!strcmp(element_name, mtu)) rsp-current = rsp-mtu; - else if (!strcmp(element_name, default_gateway)) - rsp-current = rsp-default_gateway; else if (!strcmp(element_name, dns_server) rsp-dns_server1[0] == '\0') rsp-current = rsp-dns_server1; @@ -124,7 +130,7 @@ static void text_handler(GMarkupParseContext *context, if (rsp-current) { strncpy(rsp-current, text, IP_ADDR_LEN); - rsp-current[IP_ADDR_LEN] = 0; + rsp-current[IP_ADDR_LEN] = '\0'; } } @@ -167,12 +173,38 @@ static struct conn_info *conn_info_create(unsigned int channel_id) return connection; } +static void rtnl_callback(int ifindex, char *ifname, void *user_data) +{ + struct conn_info *conn = user_data; + + if (ifindex 0) { + conn-created = FALSE; + ofono_error(Failed to create caif interface %s, + conn-interface); + return; + } + + strncpy(conn-interface, ifname, sizeof(conn-interface)); + conn-ifindex = ifindex; + conn-created = TRUE; +} + /* * Creates a new IP interface for CAIF. */ static gboolean caif_if_create(struct conn_info *conn) { - return FALSE; + int err; + + err = caif_rtnl_create_interface(IFLA_CAIF_IPV4_CONNID, + conn-channel_id, FALSE, + rtnl_callback, conn); + if (err 0) { + DBG(Failed to create IP interface for CAIF); + return FALSE; + } + + return TRUE; } /* @@ -180,6 +212,18 @@ static gboolean caif_if_create(struct conn_info *conn) */ static void caif_if_remove(struct conn_info *conn) { + if (!conn-created) + return; + + if (caif_rtnl_delete_interface(conn-ifindex) 0) { + ofono_error(Failed to delete caif interface %s, + conn-interface); + return; + } + + DBG(removed CAIF interface ch:%d ifname:%s ifindex:%d\n, + conn-channel_id, conn-interface, conn-ifindex); + return; } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -283,7 +327,7 @@ static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) dns[2] = NULL; CALLBACK_WITH_SUCCESS(cb, conn-interface, TRUE, rsp.ip_address, - rsp.subnet_mask, rsp.default_gateway, + rsp.subnet_mask, NULL, dns, cbd-data); return; @@ -380,6 +424,11 @@ static void ste_gprs_activate_primary(struct ofono_gprs_context *gc, } conn = l-data; + if (!conn-created) { + DBG(CAIF interface not created (rtnl error?)); + goto error; + } + conn-cid = ctx-cid; len = snprintf(buf, sizeof(buf), AT+CGDCONT=%u,\IP\, ctx-cid); @@ -460,6 +509,7 @@ static void ste_cgact_read_cb(gboolean ok, GAtResult *result, struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); gint cid, state
Re: [PATCHv2 1/2] stemodem: Add RTNL functionality managing CAIF Network Interfaces.
Hi Marcel. I do need another look at the RTNL magic and casting. That always drives my crazy when I look at that. In the meantime, please address these details first. I have some RTNL unit tests ready if your're interested. Also I hope I have closed most open issues from your review in the v4 version of this patch, please inform me if you think otherwise. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v4 2/2] stemodem: Update gprs-context to use rtnl to create/remove interfaces.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- drivers/stemodem/gprs-context.c | 207 +-- 1 files changed, 135 insertions(+), 72 deletions(-) diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index 9f59579..4260d31 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -28,6 +28,7 @@ #include string.h #include stdlib.h #include stdio.h +#include errno.h #include glib.h @@ -46,10 +47,11 @@ #include stemodem.h #include caif_socket.h #include if_caif.h +#include caif_rtnl.h -#define MAX_CAIF_DEVICES 7 +#define MAX_CAIF_DEVICES 4 #define MAX_DNS 2 -#define MAX_ELEM 20 +#define IP_ADDR_LEN 20 #define AUTH_BUF_LENGTH (OFONO_GPRS_MAX_USERNAME_LENGTH + \ OFONO_GPRS_MAX_PASSWORD_LENGTH + 128) @@ -65,21 +67,29 @@ struct gprs_context_data { }; struct conn_info { + /* +* cid is allocated in oFono Core and is identifying +* the Account. cid = 0 indicates that it is currently unused. +*/ unsigned int cid; - unsigned int device; + /* Id used by CAIF and EPPSD to identify the CAIF channel*/ unsigned int channel_id; - char interface[10]; + /* Linux Interface Id */ + unsigned int ifindex; + /* Linux Interface name */ + char interface[IF_NAMESIZE]; + gboolean created; }; struct eppsd_response { char *current; - char ip_address[MAX_ELEM]; - char subnet_mask[MAX_ELEM]; - char mtu[MAX_ELEM]; - char default_gateway[MAX_ELEM]; - char dns_server1[MAX_ELEM]; - char dns_server2[MAX_ELEM]; - char p_cscf_server[MAX_ELEM]; + char ip_address[IP_ADDR_LEN]; + char subnet_mask[IP_ADDR_LEN]; + char mtu[IP_ADDR_LEN]; + char default_gateway[IP_ADDR_LEN]; + char dns_server1[IP_ADDR_LEN]; + char dns_server2[IP_ADDR_LEN]; + char p_cscf_server[IP_ADDR_LEN]; }; static void start_element_handler(GMarkupParseContext *context, @@ -122,8 +132,8 @@ static void text_handler(GMarkupParseContext *context, struct eppsd_response *rsp = user_data; if (rsp-current) { - strncpy(rsp-current, text, MAX_ELEM); - rsp-current[MAX_ELEM] = 0; + strncpy(rsp-current, text, IP_ADDR_LEN); + rsp-current[IP_ADDR_LEN] = 0; } } @@ -153,8 +163,7 @@ static gint conn_compare_by_cid(gconstpointer a, gconstpointer b) return 0; } -static struct conn_info *conn_info_create(unsigned int device, - unsigned int channel_id) +static struct conn_info *conn_info_create(unsigned int channel_id) { struct conn_info *connection = g_try_new0(struct conn_info, 1); @@ -162,26 +171,61 @@ static struct conn_info *conn_info_create(unsigned int device, return NULL; connection-cid = 0; - connection-device = device; connection-channel_id = channel_id; return connection; } +static void rtnl_callback(int result, gpointer user_data, + char *ifname, int ifindex) +{ + struct conn_info *conn = user_data; + + strncpy(conn-interface, ifname, sizeof(conn-interface)); + conn-ifindex = ifindex; + + if (result == 0) + conn-created = TRUE; + else { + conn-created = FALSE; + DBG(Could not create CAIF Interface); + } +} + /* * Creates a new IP interface for CAIF. */ -static gboolean caif_if_create(const char *interface, unsigned int connid) +static gboolean caif_if_create(struct conn_info *conn) { - return FALSE; + int err; + + err = caif_rtnl_create_interface(conn, IFLA_CAIF_IPV4_CONNID, + conn-channel_id, FALSE, rtnl_callback); + if (err 0) { + DBG(Failed to create IP interface for CAIF); + return FALSE; + } + + return TRUE; } /* * Removes IP interface for CAIF. */ -static gboolean caif_if_remove(const char *interface, unsigned int connid) +static void caif_if_remove(struct conn_info *conn) { - return FALSE; + if (!conn-created) + return; + + if (caif_rtnl_delete_interface(conn-ifindex) 0) { + ofono_error(Failed to delete caif interface %s, + conn-interface); + return; + } + + DBG(removed CAIF interface ch:%d ifname:%s ifindex:%d\n, + conn-channel_id, conn-interface, conn-ifindex); + return; } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -192,11 +236,14 @@ static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, struct ofono_gprs_context *gc = cbd-user; struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct ofono_error error; - struct conn_info *conn; + struct
[PATCH v4 1/2] stemodem: Add RTNL functionality managing CAIF Network Interfaces.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- Hi Marcel. I'm sorry about the formatting for the v3 version of this patch. I used git send-email via my gmail account, and ended up with base64 MIME content encoding. I dont' know what went wrong :-( I think I have closed most of your review comments so far. I kept using sendto as I don't quite get how to use g_io_channel_write_chars for rtnl socket. (I think connman is using sendto as well.) I still set g_caif_devices = NULL just in case someone in future does init/exit more than once. The patch has been tested activating/deactivation and I have run valgrind showing no leaks on some unit tests (not yet upstreamed). Regards, Sjur Makefile.am |2 + drivers/stemodem/caif_rtnl.c | 379 ++ drivers/stemodem/caif_rtnl.h | 29 3 files changed, 410 insertions(+), 0 deletions(-) create mode 100644 drivers/stemodem/caif_rtnl.c create mode 100644 drivers/stemodem/caif_rtnl.h diff --git a/Makefile.am b/Makefile.am index 05082de..f163b0a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -226,6 +226,8 @@ builtin_sources += drivers/atmodem/atutil.h \ drivers/stemodem/stemodem.c \ drivers/stemodem/voicecall.c \ drivers/stemodem/radio-settings.c \ + drivers/stemodem/caif_rtnl.c \ + drivers/stemodem/caif_rtnl.h \ drivers/stemodem/gprs-context.c \ drivers/stemodem/caif_socket.h \ drivers/stemodem/if_caif.h diff --git a/drivers/stemodem/caif_rtnl.c b/drivers/stemodem/caif_rtnl.c new file mode 100644 index 000..ad58c93 --- /dev/null +++ b/drivers/stemodem/caif_rtnl.c @@ -0,0 +1,379 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2010 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include string.h +#include unistd.h +#include errno.h +#include net/if.h +#include net/if_arp.h +#include fcntl.h +#include linux/rtnetlink.h + +#include glib.h + +#include ofono/log.h + +#include if_caif.h +#include caif_rtnl.h + +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len))) + +struct iplink_req { + struct nlmsghdr n; + struct ifinfomsg i; + char pad[1024]; + + int request_id; + int type; + int conn_id; + gpointer user_data; + gboolean loop_enabled; + + char ifname[IF_NAMESIZE]; + int ifindex; + caif_rtnl_create_cb_t callback; +}; + +static GSList *pending_requests; +static guint32 rtnl_seqnr; +static guint rtnl_watch; +static GIOChannel *channel; + +static gboolean get_ifname(struct ifinfomsg *msg, int bytes, + const char **ifname) +{ + struct rtattr *attr; + + for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes); + attr = RTA_NEXT(attr, bytes)) { + + if (attr-rta_type == IFLA_IFNAME + ifname != NULL) { + + *ifname = RTA_DATA(attr); + return TRUE; + } + } + + return FALSE; +} + +static void store_newlink_param(struct iplink_req *req, unsigned short type, + int index, unsigned flags, + unsigned change, struct ifinfomsg *msg, + int bytes) +{ + const char *ifname = NULL; + + get_ifname(msg, bytes, ifname); + strncpy(req-ifname, ifname, + sizeof(req-ifname)); + req-ifname[sizeof(req-ifname)-1] = '\0'; + req-ifindex = index; +} + +static int send_rtnl_req(struct iplink_req *req) +{ + struct sockaddr_nl addr; + int sk = g_io_channel_unix_get_fd(channel); + + memset(addr, 0, sizeof(addr)); + addr.nl_family = AF_NETLINK; + + return sendto(sk, req, req-n.nlmsg_len, 0, + (struct sockaddr *) addr, sizeof(addr)); +} + +static struct iplink_req *find_request(guint32 seq) +{ + GSList *list; + + for (list = pending_requests; list; list = list-next) { + struct iplink_req *req = list-data
Re: [RFC 1/3] doc: addidng documentation for basic assisted gps
Hi, So in general I'm currently against introducing this API as oFono official API. I suggest prefixing this with an IFX specific identifier. Maybe modem.ifx.AgpsManager. I would actually go one step further and call this com.infineon.Agps or something like that. As I stated this many times, before we make this a generic oFono API, we need at least three types of modems that support this kind of feature and find the common API. For me this is clearly IFX and ISI right now. And it looks to me that Sjur has also shown interested, so the third one might be STE/MBM. Yes, I can confirm that we are looking into this and are planning to support AGPS for oFono. Would you be interested if we proposed an API whith transparent transport of the XML specified by 3GPP? Such an API should be possible to implement with the 3GPP standardized AGPS commands, so that a generic driver could be implemented (atmodem/agps.c). Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCH v3 1/2] stemodem: Add RTNL functionality managing CAIF Network Interfaces.
Hi Marcel. +int caif_rtnl_init(void) +{ + struct sockaddr_nl addr; + int sk, err; + GError *gerr = NULL; + + sk = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); + if (sk 0) + return sk; + + memset(addr, 0, sizeof(addr)); + addr.nl_family = AF_NETLINK; + addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE; + + err = bind(sk, (struct sockaddr *) addr, sizeof(addr)); + if (err 0) { + close(sk); + return err; + } + + channel = g_io_channel_unix_new(sk); + g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, gerr); + g_io_channel_set_encoding(channel, NULL, gerr); + g_io_channel_set_buffered(channel, TRUE); + g_io_channel_set_close_on_unref(channel, TRUE); + + rtnl_watch = g_io_add_watch(channel, + G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, + netlink_event, NULL); + pending_requests = NULL; + + return 0; +} Sigh, I realize I have a potential leak on gerr above. I'll wait for more review comments from you, and resubmit later. Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[RFC] plugin/ste: Use D-Bus API from Modem Init Daemon for autoconfig.
From: Sjur Brændeland sjur.brandel...@stericsson.com This patch introduces auto discovery of ST-Ericsson modems. ST-Ericsson modems are managed by a Modem Init Daemon which is responsible for start/stop/restart flashing etc. The STE plugin monitors the modem state exposed from the Modem Init Damon Dbus API. When the modem is in state on the STE modem is created and registered. The reason for not using the standard udev paradigm is that the CAIF device is up before the modem is ready to setup AT channels. For flashless modems CAIF is used as part of the boot. The Modem Init Daemon is managing the flashless boot procedure and sets the State to on when the modem is available. --- plugins/ste.c | 146 - 1 files changed, 145 insertions(+), 1 deletions(-) diff --git a/plugins/ste.c b/plugins/ste.c index 508ad58..3e6b895 100644 --- a/plugins/ste.c +++ b/plugins/ste.c @@ -32,6 +32,7 @@ #include unistd.h #include net/if.h +#include gdbus.h #include glib.h #include gatchat.h @@ -73,6 +74,144 @@ struct ste_data { gboolean have_sim; }; +/* + * ST-Ericsson's modem init daemon defines the signal StateChange + * and the method GetState. When state is on the STE modem is + * created and registered. + */ +#define STATUS_CHANGED StateChange +#define MID_SERVICEcom.stericsson.mid +#define MID_INTERFACE MID_SERVICE .Modem +#define GET_STATE GetState +#define MID_STATE_ON on +#define MID_STATE_DISCONNECT disconnect +#define TIMEOUT5000 + +static struct ofono_modem *ste_modem; +static guint mid_api_watch; +static guint mid_state_watch; + +static void handle_stemodem(const char *state) +{ + + if (strcmp(state, MID_STATE_ON) == 0) { + int err; + + if (ste_modem != NULL) + return; + + ste_modem = ofono_modem_create(ste, ste); + DBG(register STE modem); + err = ofono_modem_register(ste_modem); + } else { + if (ste_modem == NULL) + return; + ofono_modem_remove(ste_modem); + ste_modem = NULL; + } +} + +static void mid_getstate_reply(DBusPendingCall *call, void *user_data) +{ + DBusMessage *reply; + char *state; + + reply = dbus_pending_call_steal_reply(call); + + if (dbus_message_is_error(reply, DBUS_ERROR_SERVICE_UNKNOWN)) { + ofono_error(STE Modem Init Daemon is unavailable); + goto error; + } + + if (dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, state, + DBUS_TYPE_INVALID) == FALSE) { + ofono_error(STE Modem Init Damon: bad signature for GetState); + goto error; + } + + handle_stemodem(state); +error: + dbus_message_unref(reply); +} + +static gboolean mid_signal_status_change(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + const char *state = NULL; + + if (dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, state, + DBUS_TYPE_INVALID) == FALSE) { + ofono_error(STE Modem Init Daemon: invalid signal signature); + return FALSE; + } + + handle_stemodem(state); + return TRUE; +} + +static void mid_connect(DBusConnection *connection, void *user_data) +{ + DBusMessage *message; + DBusPendingCall *call; + + message = dbus_message_new_method_call(MID_SERVICE, /, + MID_INTERFACE, GetState); + if (!message) { + ofono_error(Unable to allocate new D-Bus message); + goto error; + } + + dbus_message_set_auto_start(message, FALSE); + + if (dbus_connection_send_with_reply(connection, message, + call, TIMEOUT) == FALSE) { + ofono_error(Sending D-Bus message failed); + goto error; + } + + if (call == NULL) { + DBG(D-Bus connection not available); + goto error; + } + + dbus_pending_call_set_notify(call, mid_getstate_reply, NULL, NULL); + dbus_pending_call_unref(call); +error: + dbus_message_unref(message); +} + +static void mid_disconnect(DBusConnection *connection, void *user_data) +{ + handle_stemodem(MID_STATE_DISCONNECT); +} + +static int modem_initd_setup() +{ + DBusConnection *connection; + + connection = ofono_dbus_get_connection(); + if (connection == NULL) + return -EIO; + + mid_api_watch = g_dbus_add_service_watch(connection, MID_SERVICE, + mid_connect, mid_disconnect, NULL, NULL); + + mid_state_watch = g_dbus_add_signal_watch(connection, NULL, NULL, + MID_INTERFACE
Re: [RFC] AGPS Support
Hi Marcel. On positioning framework side, XML containers encoding/decoding does not seem to be yet widely used, while the support of RRC and RRLP framing is common, thanks to the support of SUPL. Using XML and 27.007 format would be great as long as long as ofono is not obliged to interpret the XML containers. Denis, is this something you would consider as an option, to transport both ASN.1 coded RRC / RRLP frames and XML transparently over the oFono API ? can some just quickly summarize for me what kind of different data type representation we actually have here. And what the different modems and standard suggest on how to encode them. The RRLP, RRC and LPP standards all use ASN.1 to specify the data that is transferred, this encoded using packed en coding rules. The data is represented as SEQUENCES of INTEGER and ENUMERATED data types. A lot of items are subject to interesting scaling algorithms to get them into an integral format. A handful of items (locations and required assistance data) are effectively octet strings from other 3gpp standards. Most of the data is assistance data describing reference location, reference time, satellite orbits, expected doppler and code phase. The UE calculates the location and returns this as a GAD shape which is basically an ellipse with uncertainty, the coordinates scaled to be integral values. And then really who needs to transcode what in to what standard if we would be going for XML as format? The STE-Ericsson modem is doing the transcoding to XML on the modem side, using the 27.007 AT commands defined for AGPS. For other modems sending the raw RRC/RRLP frames I guess the transcoding to XML would need to happen in the ofono driver or in ofono core if you want to expose an oFono XML API. Regards, Sjur and Simon ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [RFC] AGPS Support
Hi Denis, What are the possible reasons as to why oFono might need to peek inside the XML? I was previously under the false impression that you wanted oFono API to export AGPS functionality using dbus types only. Piping the AGPS XML (or ASN.1 coded data) through oFono certainly makes the oFono implementation much simpler. I'm all for that :-) Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v3 1/2] stemodem: Add RTNL functionality managing CAIF Network Interfaces.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- Hi Marcel. I hope I have closed most of your review comments so far. I had a go at using g_io_chanel_write_chars, but couldn't make it work, and I (stubbornly ;-) do g_caif_devices = NULL, just in case someone choose to call caif_rtnl_init more than once. Makefile.am |2 + drivers/stemodem/caif_rtnl.c | 382 ++ drivers/stemodem/caif_rtnl.h | 29 3 files changed, 413 insertions(+), 0 deletions(-) create mode 100644 drivers/stemodem/caif_rtnl.c create mode 100644 drivers/stemodem/caif_rtnl.h diff --git a/Makefile.am b/Makefile.am index cd17fa2..aea91ce 100644 --- a/Makefile.am +++ b/Makefile.am @@ -226,6 +226,8 @@ builtin_sources += drivers/atmodem/atutil.h \ drivers/stemodem/stemodem.c \ drivers/stemodem/voicecall.c \ drivers/stemodem/radio-settings.c \ + drivers/stemodem/caif_rtnl.c \ + drivers/stemodem/caif_rtnl.h \ drivers/stemodem/gprs-context.c \ drivers/stemodem/caif_socket.h \ drivers/stemodem/if_caif.h diff --git a/drivers/stemodem/caif_rtnl.c b/drivers/stemodem/caif_rtnl.c new file mode 100644 index 000..82740ba --- /dev/null +++ b/drivers/stemodem/caif_rtnl.c @@ -0,0 +1,382 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2010 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include string.h +#include unistd.h +#include errno.h +#include net/if.h +#include net/if_arp.h +#include fcntl.h +#include linux/rtnetlink.h + +#include glib.h + +#include ofono/log.h + +#include if_caif.h +#include caif_rtnl.h + +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len))) + +struct iplink_req { + struct nlmsghdr n; + struct ifinfomsg i; + char pad[1024]; + + int request_id; + int type; + int conn_id; + gpointer user_data; + gboolean loop_enabled; + + char ifname[IF_NAMESIZE]; + int ifindex; + caif_rtnl_create_cb_t callback; +}; + +static GSList *pending_requests; +static guint32 rtnl_seqnr; +static guint rtnl_watch; +static GIOChannel *channel; + +static gboolean get_ifname(struct ifinfomsg *msg, int bytes, + const char **ifname) +{ + struct rtattr *attr; + + for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes); + attr = RTA_NEXT(attr, bytes)) { + + if (attr-rta_type == IFLA_IFNAME + ifname != NULL) { + + *ifname = RTA_DATA(attr); + return TRUE; + } + } + + return FALSE; +} + +static void store_newlink_param(struct iplink_req *req, unsigned short type, + int index, unsigned flags, + unsigned change, struct ifinfomsg *msg, + int bytes) +{ + const char *ifname = NULL; + + get_ifname(msg, bytes, ifname); + strncpy(req-ifname, ifname, + sizeof(req-ifname)); + req-ifname[sizeof(req-ifname)-1] = '\0'; + req-ifindex = index; +} + +static int send_rtnl_req(struct iplink_req *req) +{ + struct sockaddr_nl addr; + int sk = g_io_channel_unix_get_fd(channel); + + memset(addr, 0, sizeof(addr)); + addr.nl_family = AF_NETLINK; + + return sendto(sk, req, req-n.nlmsg_len, 0, + (struct sockaddr *) addr, sizeof(addr)); +} + +static struct iplink_req *find_request(guint32 seq) +{ + GSList *list; + + for (list = pending_requests; list; list = list-next) { + struct iplink_req *req = list-data; + + if (req-n.nlmsg_seq == seq) + return req; + } + + return NULL; +} + +static void rtnl_client_response(struct iplink_req *req, int result) +{ + + if (req-callback req-n.nlmsg_type == RTM_NEWLINK) + req-callback(result, req-user_data, + req-ifname, req-ifindex); + + pending_requests
[PATCH v3 2/2] stemodem: Update gprs-context to use rtnl to create/remove interfaces.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- drivers/stemodem/gprs-context.c | 207 +-- 1 files changed, 135 insertions(+), 72 deletions(-) diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index 9f59579..4260d31 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -28,6 +28,7 @@ #include string.h #include stdlib.h #include stdio.h +#include errno.h #include glib.h @@ -46,10 +47,11 @@ #include stemodem.h #include caif_socket.h #include if_caif.h +#include caif_rtnl.h -#define MAX_CAIF_DEVICES 7 +#define MAX_CAIF_DEVICES 4 #define MAX_DNS 2 -#define MAX_ELEM 20 +#define IP_ADDR_LEN 20 #define AUTH_BUF_LENGTH (OFONO_GPRS_MAX_USERNAME_LENGTH + \ OFONO_GPRS_MAX_PASSWORD_LENGTH + 128) @@ -65,21 +67,29 @@ struct gprs_context_data { }; struct conn_info { + /* +* cid is allocated in oFono Core and is identifying +* the Account. cid = 0 indicates that it is currently unused. +*/ unsigned int cid; - unsigned int device; + /* Id used by CAIF and EPPSD to identify the CAIF channel*/ unsigned int channel_id; - char interface[10]; + /* Linux Interface Id */ + unsigned int ifindex; + /* Linux Interface name */ + char interface[IF_NAMESIZE]; + gboolean created; }; struct eppsd_response { char *current; - char ip_address[MAX_ELEM]; - char subnet_mask[MAX_ELEM]; - char mtu[MAX_ELEM]; - char default_gateway[MAX_ELEM]; - char dns_server1[MAX_ELEM]; - char dns_server2[MAX_ELEM]; - char p_cscf_server[MAX_ELEM]; + char ip_address[IP_ADDR_LEN]; + char subnet_mask[IP_ADDR_LEN]; + char mtu[IP_ADDR_LEN]; + char default_gateway[IP_ADDR_LEN]; + char dns_server1[IP_ADDR_LEN]; + char dns_server2[IP_ADDR_LEN]; + char p_cscf_server[IP_ADDR_LEN]; }; static void start_element_handler(GMarkupParseContext *context, @@ -122,8 +132,8 @@ static void text_handler(GMarkupParseContext *context, struct eppsd_response *rsp = user_data; if (rsp-current) { - strncpy(rsp-current, text, MAX_ELEM); - rsp-current[MAX_ELEM] = 0; + strncpy(rsp-current, text, IP_ADDR_LEN); + rsp-current[IP_ADDR_LEN] = 0; } } @@ -153,8 +163,7 @@ static gint conn_compare_by_cid(gconstpointer a, gconstpointer b) return 0; } -static struct conn_info *conn_info_create(unsigned int device, - unsigned int channel_id) +static struct conn_info *conn_info_create(unsigned int channel_id) { struct conn_info *connection = g_try_new0(struct conn_info, 1); @@ -162,26 +171,61 @@ static struct conn_info *conn_info_create(unsigned int device, return NULL; connection-cid = 0; - connection-device = device; connection-channel_id = channel_id; return connection; } +static void rtnl_callback(int result, gpointer user_data, + char *ifname, int ifindex) +{ + struct conn_info *conn = user_data; + + strncpy(conn-interface, ifname, sizeof(conn-interface)); + conn-ifindex = ifindex; + + if (result == 0) + conn-created = TRUE; + else { + conn-created = FALSE; + DBG(Could not create CAIF Interface); + } +} + /* * Creates a new IP interface for CAIF. */ -static gboolean caif_if_create(const char *interface, unsigned int connid) +static gboolean caif_if_create(struct conn_info *conn) { - return FALSE; + int err; + + err = caif_rtnl_create_interface(conn, IFLA_CAIF_IPV4_CONNID, + conn-channel_id, FALSE, rtnl_callback); + if (err 0) { + DBG(Failed to create IP interface for CAIF); + return FALSE; + } + + return TRUE; } /* * Removes IP interface for CAIF. */ -static gboolean caif_if_remove(const char *interface, unsigned int connid) +static void caif_if_remove(struct conn_info *conn) { - return FALSE; + if (!conn-created) + return; + + if (caif_rtnl_delete_interface(conn-ifindex) 0) { + ofono_error(Failed to delete caif interface %s, + conn-interface); + return; + } + + DBG(removed CAIF interface ch:%d ifname:%s ifindex:%d\n, + conn-channel_id, conn-interface, conn-ifindex); + return; } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -192,11 +236,14 @@ static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, struct ofono_gprs_context *gc = cbd-user; struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct ofono_error error; - struct conn_info *conn; + struct
Re: [RFC] AGPS Support
Hi Denis, Fredric wrote: On positioning framework side, XML containers encoding/decoding does not seem to be yet widely used, while the support of RRC and RRLP framing is common, thanks to the support of SUPL. Using XML and 27.007 format would be great as long as long as ofono is not obliged to interpret the XML containers. Denis, is this something you would consider as an option, to transport both ASN.1 coded RRC / RRLP frames and XML transparently over the oFono API ? Regards, Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCHv2 1/2] stemodem: Add RTNL functionality managing CAIF Network Interfaces.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- Changes from last patch-set: o squashed previous patches for rtnl.c, rtnl.h and Makefile.am into one patch o renamed rtnl.[ch] to caif_rtnl.[ch] o renamed rtnl_init and rtnl_exit to caif_rtnl_* o renamed rtnl_create_caif_interface to caif_rtnl_create_interface. Makefile.am |2 + drivers/stemodem/caif_rtnl.c | 365 ++ drivers/stemodem/caif_rtnl.h | 40 + 3 files changed, 407 insertions(+), 0 deletions(-) create mode 100644 drivers/stemodem/caif_rtnl.c create mode 100644 drivers/stemodem/caif_rtnl.h diff --git a/Makefile.am b/Makefile.am index 2562160..fdd363d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -226,6 +226,8 @@ builtin_sources += drivers/atmodem/atutil.h \ drivers/stemodem/stemodem.c \ drivers/stemodem/voicecall.c \ drivers/stemodem/radio-settings.c \ + drivers/stemodem/caif_rtnl.c \ + drivers/stemodem/caif_rtnl.h \ drivers/stemodem/gprs-context.c \ drivers/stemodem/caif_socket.h \ drivers/stemodem/if_caif.h diff --git a/drivers/stemodem/caif_rtnl.c b/drivers/stemodem/caif_rtnl.c new file mode 100644 index 000..2712df7 --- /dev/null +++ b/drivers/stemodem/caif_rtnl.c @@ -0,0 +1,365 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2010 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include string.h +#include unistd.h +#include errno.h +#include net/if.h +#include net/if_arp.h +#include linux/rtnetlink.h + +#include glib.h + +#include ofono/log.h + +#include if_caif.h +#include caif_rtnl.h + +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len))) + +struct iplink_req { + struct nlmsghdr n; + struct ifinfomsg i; + char pad[1024]; + int request_id; + struct rtnl_req_param req; + struct rtnl_rsp_param rsp; +}; + +static GSList *pending_requests; +static GIOChannel *channel; +static guint32 rtnl_seqnr; +static guint rtnl_watch; + +static gboolean get_ifname(struct ifinfomsg *msg, int bytes, + const char **ifname) +{ + struct rtattr *attr; + + for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes); + attr = RTA_NEXT(attr, bytes)) + + if (attr-rta_type == IFLA_IFNAME + ifname != NULL) { + *ifname = RTA_DATA(attr); + return TRUE; + } + + return FALSE; +} + +static void store_newlink_param(struct iplink_req *req, unsigned short type, + int index, unsigned flags, + unsigned change, struct ifinfomsg *msg, + int bytes) +{ + const char *ifname = NULL; + + get_ifname(msg, bytes, ifname); + strncpy(req-rsp.ifname, ifname, + sizeof(req-rsp.ifname)); + req-rsp.ifname[sizeof(req-rsp.ifname)-1] = '\0'; + req-rsp.ifindex = index; +} + +static int send_rtnl_req(struct iplink_req *req) +{ + struct sockaddr_nl addr; + int sk, ret; + + sk = g_io_channel_unix_get_fd(channel); + + memset(addr, 0, sizeof(addr)); + addr.nl_family = AF_NETLINK; + + ret = sendto(sk, req, req-n.nlmsg_len, 0, + (struct sockaddr *) addr, sizeof(addr)); + if (ret 0) + return ret; + return 0; +} + +static struct iplink_req *find_request(guint32 seq) +{ + GSList *list; + + for (list = pending_requests; list; list = list-next) { + struct iplink_req *req = list-data; + + if (req-n.nlmsg_seq == seq) + return req; + } + + return NULL; +} + +static void rtnl_client_response(struct iplink_req *req) +{ + + if (req-req.callback req-n.nlmsg_type == RTM_NEWLINK) + req-req.callback(req-rsp); + + pending_requests = g_slist_remove(pending_requests, req); + g_free(req); +} + +static void parse_rtnl_message(void *buf, size_t len
[PATCH 1/4] stemodem: Add rtnl header file.
From: Sjur Brændeland sjur.brandel...@stericsson.com Add new asynchronous rtnl interface for creating and deleting CAIF Network interfaces. Creation takes struct rtnl_req_param as input containing ip type (v4/v6), channel id etc. The result is returned in struct rtnl_rsp_param containing the interface name and interface index. --- drivers/stemodem/rtnl.h | 41 + 1 files changed, 41 insertions(+), 0 deletions(-) create mode 100644 drivers/stemodem/rtnl.h diff --git a/drivers/stemodem/rtnl.h b/drivers/stemodem/rtnl.h new file mode 100644 index 000..566452b --- /dev/null +++ b/drivers/stemodem/rtnl.h @@ -0,0 +1,41 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2010 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +struct rtnl_rsp_param { + int result; + gpointer user_data; + char ifname[IF_NAMESIZE]; + int ifindex; +}; + +struct rtnl_req_param { + void (*callback)(struct rtnl_rsp_param *param); + gpointer user_data; + int type; + int conn_id; + gboolean loop_enabled; +}; + +extern int rtnl_create_caif_interface(struct rtnl_req_param *req); +extern int rtnl_delete_caif_interface(int ifid); + +extern int rtnl_init(void); +extern void rtnl_exit(void); + -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 2/4] stemodem: Add RTNL functionality for CAIF Netw Interface.
From: Sjur Brændeland sjur.brandel...@stericsson.com Add file rtnl.c for creating and deleting CAIF network interfaces using the RTNL protocol. The interface is asynchronous. Only RTNL NEWLINK and DELLINK commands are implemented. CAIF requires NEWLINK to contain channel-id and ip-type (ipv4/ipv6) as arguments. --- drivers/stemodem/rtnl.c | 365 +++ 1 files changed, 365 insertions(+), 0 deletions(-) create mode 100644 drivers/stemodem/rtnl.c diff --git a/drivers/stemodem/rtnl.c b/drivers/stemodem/rtnl.c new file mode 100644 index 000..38f7f43 --- /dev/null +++ b/drivers/stemodem/rtnl.c @@ -0,0 +1,365 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2010 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#include string.h +#include unistd.h +#include errno.h +#include net/if.h +#include net/if_arp.h +#include linux/rtnetlink.h + +#include glib.h + +#include ofono/log.h + +#include if_caif.h +#include rtnl.h + +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len))) + +struct iplink_req { + struct nlmsghdr n; + struct ifinfomsg i; + char pad[1024]; + int request_id; + struct rtnl_req_param req; + struct rtnl_rsp_param rsp; +}; + +static GSList *pending_requests; +static GIOChannel *channel; +static guint32 rtnl_seqnr; +static guint rtnl_watch; + +static gboolean get_ifname(struct ifinfomsg *msg, int bytes, + const char **ifname) +{ + struct rtattr *attr; + + for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes); + attr = RTA_NEXT(attr, bytes)) + + if (attr-rta_type == IFLA_IFNAME + ifname != NULL) { + *ifname = RTA_DATA(attr); + return TRUE; + } + + return FALSE; +} + +static void store_newlink_param(struct iplink_req *req, unsigned short type, + int index, unsigned flags, + unsigned change, struct ifinfomsg *msg, + int bytes) +{ + const char *ifname = NULL; + + get_ifname(msg, bytes, ifname); + strncpy(req-rsp.ifname, ifname, + sizeof(req-rsp.ifname)); + req-rsp.ifname[sizeof(req-rsp.ifname)-1] = '\0'; + req-rsp.ifindex = index; +} + +static int send_rtnl_req(struct iplink_req *req) +{ + struct sockaddr_nl addr; + int sk, ret; + + sk = g_io_channel_unix_get_fd(channel); + + memset(addr, 0, sizeof(addr)); + addr.nl_family = AF_NETLINK; + + ret = sendto(sk, req, req-n.nlmsg_len, 0, + (struct sockaddr *) addr, sizeof(addr)); + if (ret 0) + return ret; + return 0; +} + +static struct iplink_req *find_request(guint32 seq) +{ + GSList *list; + + for (list = pending_requests; list; list = list-next) { + struct iplink_req *req = list-data; + + if (req-n.nlmsg_seq == seq) + return req; + } + + return NULL; +} + +static void rtnl_client_response(struct iplink_req *req) +{ + + if (req-req.callback req-n.nlmsg_type == RTM_NEWLINK) + req-req.callback(req-rsp); + + pending_requests = g_slist_remove(pending_requests, req); + g_free(req); +} + +static void parse_rtnl_message(void *buf, size_t len) +{ + struct ifinfomsg *msg; + struct iplink_req *req; + + while (len 0) { + struct nlmsghdr *hdr = buf; + if (!NLMSG_OK(hdr, len)) + break; + if (hdr-nlmsg_type == RTM_NEWLINK) { + req = g_slist_nth_data(pending_requests, 0); + DBG(NEWLINK req:%p\n, req); + if (req == NULL) + break; + msg = (struct ifinfomsg *) NLMSG_DATA(hdr); + store_newlink_param(req, msg-ifi_type, + msg-ifi_index, msg-ifi_flags, + msg-ifi_change, msg, + IFA_PAYLOAD
[PATCH 3/4] stemodem: Update gprs-context to use rtnl
From: Sjur Brændeland sjur.brandel...@stericsson.com RTNL is now used to create and remove CAIF network interfaces. The created CAIF interface is assigned a channel-id which is used as parameter in the AT*EPPSD command used to activate the PDP-Context. The CAIF Network interfaces are created when gprs-context is probed initially. Some refactoring and bug-fixes are also included. --- drivers/stemodem/gprs-context.c | 210 +- 1 files changed, 138 insertions(+), 72 deletions(-) diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index d3a50a9..7e956d3 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -28,6 +28,7 @@ #include string.h #include stdlib.h #include stdio.h +#include errno.h #include glib.h @@ -46,10 +47,11 @@ #include stemodem.h #include caif_socket.h #include if_caif.h +#include rtnl.h -#define MAX_CAIF_DEVICES 7 +#define MAX_CAIF_DEVICES 4 #define MAX_DNS 2 -#define MAX_ELEM 20 +#define IP_ADDR_LEN 20 #define AUTH_BUF_LENGTH (OFONO_GPRS_MAX_USERNAME_LENGTH + \ OFONO_GPRS_MAX_PASSWORD_LENGTH + 128) @@ -65,21 +67,29 @@ struct gprs_context_data { }; struct conn_info { + /* +* cid is allocated in oFono Core and is identifying +* the Account. cid = 0 indicates that it is currently unused. +*/ unsigned int cid; - unsigned int device; + /* Id used by CAIF and EPPSD to identify the CAIF channel*/ unsigned int channel_id; - char interface[10]; + /* Linux Interface Id */ + unsigned int ifindex; + /* Linux Interface name */ + char interface[IF_NAMESIZE]; + gboolean created; }; struct eppsd_response { char *current; - char ip_address[MAX_ELEM]; - char subnet_mask[MAX_ELEM]; - char mtu[MAX_ELEM]; - char default_gateway[MAX_ELEM]; - char dns_server1[MAX_ELEM]; - char dns_server2[MAX_ELEM]; - char p_cscf_server[MAX_ELEM]; + char ip_address[IP_ADDR_LEN]; + char subnet_mask[IP_ADDR_LEN]; + char mtu[IP_ADDR_LEN]; + char default_gateway[IP_ADDR_LEN]; + char dns_server1[IP_ADDR_LEN]; + char dns_server2[IP_ADDR_LEN]; + char p_cscf_server[IP_ADDR_LEN]; }; static void start_element_handler(GMarkupParseContext *context, @@ -122,8 +132,8 @@ static void text_handler(GMarkupParseContext *context, struct eppsd_response *rsp = user_data; if (rsp-current) { - strncpy(rsp-current, text, MAX_ELEM); - rsp-current[MAX_ELEM] = 0; + strncpy(rsp-current, text, IP_ADDR_LEN); + rsp-current[IP_ADDR_LEN] = 0; } } @@ -153,8 +163,7 @@ static gint conn_compare_by_cid(gconstpointer a, gconstpointer b) return 0; } -static struct conn_info *conn_info_create(unsigned int device, - unsigned int channel_id) +static struct conn_info *conn_info_create(unsigned int channel_id) { struct conn_info *connection = g_try_new0(struct conn_info, 1); @@ -162,26 +171,64 @@ static struct conn_info *conn_info_create(unsigned int device, return NULL; connection-cid = 0; - connection-device = device; connection-channel_id = channel_id; return connection; } +static void rtnl_callback(struct rtnl_rsp_param *param) +{ + struct conn_info *conn = param-user_data; + + strncpy(conn-interface, param-ifname, sizeof(conn-interface)); + conn-ifindex = param-ifindex; + + if (param-result == 0) + conn-created = TRUE; + else { + conn-created = FALSE; + DBG(Could not create CAIF Interface); + } +} + /* * Creates a new IP interface for CAIF. */ -static gboolean caif_if_create(const char *interface, unsigned int connid) +static gboolean caif_if_create(struct conn_info *conn) { - return FALSE; + struct rtnl_req_param req_param = { + .type = IFLA_CAIF_IPV4_CONNID, + .conn_id = conn-channel_id, + .user_data = conn, + .callback = rtnl_callback, + .loop_enabled = FALSE + }; + + if (rtnl_create_caif_interface(req_param) 0) { + DBG(Failed to create IP interface for CAIF); + return FALSE; + } + + return TRUE; } /* * Removes IP interface for CAIF. */ -static gboolean caif_if_remove(const char *interface, unsigned int connid) +static void caif_if_remove(struct conn_info *conn) { - return FALSE; + if (!conn-created) + return; + + if (rtnl_delete_caif_interface(conn-ifindex) 0) { + ofono_error(Failed to delete caif interface %s, + conn-interface); + return; + } + + DBG(removed CAIF interface ch:%d ifname:%s ifindex:%d\n
[PATCH 4/4] stemodem: Add rtnl to Makefile.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- Makefile.am |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/Makefile.am b/Makefile.am index 2562160..1b09a3c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -226,6 +226,8 @@ builtin_sources += drivers/atmodem/atutil.h \ drivers/stemodem/stemodem.c \ drivers/stemodem/voicecall.c \ drivers/stemodem/radio-settings.c \ + drivers/stemodem/rtnl.c \ + drivers/stemodem/rtnl.h \ drivers/stemodem/gprs-context.c \ drivers/stemodem/caif_socket.h \ drivers/stemodem/if_caif.h -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [online-impl-v2 PATCH 00/10] implement Online property
[Marcel] STE version needs testing by the STE guys, but I did run into some SIM not ready issues with MBM when switching online/offline a few times. So that needs to be looked into. OK, I'll put in on our list. Perhaps you could send me thelogs if you still have them around? Regards Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCH 1/3] mbm: fix initial polling for sim
Marcel Holtmann mar...@holtmann.org wrote: maybe the STE modem is a bit more specific here than the MBM one. Which MBM modem did you test this with? I have been using MBM as template for my sim ready changes, so I don't think there is any point at looking at STE driver at this point in time. Regards Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[RFC] stemodem: Add RTNL support for creating CAIF interface.
This patch adds a new module rtnl.[ch] for creating and deleting a CAIF Network Interface. The rtnl module uses standard RTNL NEWLINK and DELLINK commands. CAIF Network Interface takes a Connection-ID in order to be able to associate the AT command for pdp-context activation with CAIF Channel and CAIF Interface. gprs-context.c will create interfaces at initially in the probe function and delete the interfaces at remove. The RTNL requests are handled asynchronously. --- Makefile.am |2 + drivers/stemodem/gprs-context.c | 77 ++--- drivers/stemodem/rtnl.c | 359 +++ drivers/stemodem/rtnl.h | 42 + 4 files changed, 456 insertions(+), 24 deletions(-) create mode 100644 drivers/stemodem/rtnl.c create mode 100644 drivers/stemodem/rtnl.h diff --git a/Makefile.am b/Makefile.am index 0485a84..52debb7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -203,6 +203,8 @@ builtin_sources += drivers/atmodem/atutil.h \ drivers/stemodem/stemodem.c \ drivers/stemodem/voicecall.c \ drivers/stemodem/radio-settings.c \ + drivers/stemodem/rtnl.c \ + drivers/stemodem/rtnl.h \ drivers/stemodem/gprs-context.c \ drivers/stemodem/caif_socket.h \ drivers/stemodem/if_caif.h diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index d3a50a9..1c8e203 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -46,6 +46,7 @@ #include stemodem.h #include caif_socket.h #include if_caif.h +#include rtnl.h #define MAX_CAIF_DEVICES 7 #define MAX_DNS 2 @@ -68,7 +69,9 @@ struct conn_info { unsigned int cid; unsigned int device; unsigned int channel_id; - char interface[10]; + unsigned int ifindex; + gboolean created; + char interface[IF_NAMESIZE]; }; struct eppsd_response { @@ -168,20 +171,53 @@ static struct conn_info *conn_info_create(unsigned int device, return connection; } +static void rtnl_callback(struct rtnl_rsp_param *param) +{ + struct conn_info *conn = param-user_data; + + strncpy(conn-interface, param-ifname, sizeof(conn-interface)); + conn-ifindex = param-ifindex; + conn-created = param-result == 0; +} + /* * Creates a new IP interface for CAIF. */ -static gboolean caif_if_create(const char *interface, unsigned int connid) +static gboolean caif_if_create(struct conn_info *conn) { - return FALSE; + struct rtnl_req_param req_param; + + req_param.type = IFLA_CAIF_IPV4_CONNID; + req_param.conn_id = conn-channel_id; + req_param.user_data = conn; + req_param.callback = rtnl_callback; + strcpy(req_param.ifname, caif%d); + + if (rtnl_create_caif_interface(req_param) 0) { + DBG(Failed to create IP interface for CAIF); + return FALSE; + } + + return TRUE; } /* * Removes IP interface for CAIF. */ -static gboolean caif_if_remove(const char *interface, unsigned int connid) +static void caif_if_remove(struct conn_info *conn) { - return FALSE; + if (!conn-created) + return; + + if (rtnl_delete_caif_interface(conn-ifindex) 0) { + ofono_error(Failed to delete caif interface %s, + conn-interface); + return; + } + + DBG(removed CAIF interface ch:%d ifname:%s ifindex:%d\n, + conn-channel_id, conn-interface, conn-ifindex); + return; } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -210,12 +246,6 @@ static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, } conn = l-data; - - if (!caif_if_remove(conn-interface, conn-channel_id)) { - DBG(Failed to remove caif interface %s., - conn-interface); - } - conn-cid = 0; decode_at_error(error, g_at_result_final_response(result)); @@ -283,20 +313,9 @@ static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) dns[1] = rsp.dns_server2; dns[2] = NULL; - sprintf(conn-interface, caif%u, conn-device); - - if (!caif_if_create(conn-interface, conn-channel_id)) { - ofono_error(Failed to create caif interface %s., - conn-interface); - CALLBACK_WITH_SUCCESS(cb, NULL, FALSE, rsp.ip_address, + CALLBACK_WITH_SUCCESS(cb, conn-interface, FALSE, rsp.ip_address, rsp.subnet_mask, rsp.default_gateway, dns, cbd-data); - } else { - CALLBACK_WITH_SUCCESS(cb, conn-interface, - FALSE, rsp.ip_address, rsp.subnet_mask, -
[PATCH v5 0/8] Resubmitting STE Driver Patches.
Resubmitting same changes as last patch set, but some of the patches are split up in smaller parts. The RTNL patch is removed and replaced by a separate RFC. Sjur Brændeland (8): plugins/ste: SIM - STE registers as MBM to utilize mbm quirks. stemodem: Add polling for SIM ready. plugins/ste: Add AT Channel configurations (new) stemodem: Add Radio Settings to STE Modem plugins/ste: Add Radio-Settings plugins/modemconf.c add support for Interface for STE plugin. (new) plugins/ste: Use SOCK_STREAM for CAIF and enable interface specification. plugins: Add STE sample to modem.conf (new) Makefile.am |2 + drivers/stemodem/radio-settings.c | 225 + drivers/stemodem/stemodem.c |2 + drivers/stemodem/stemodem.h |2 + plugins/modem.conf|5 + plugins/modemconf.c |1 + plugins/ste.c | 79 - 7 files changed, 311 insertions(+), 5 deletions(-) create mode 100644 drivers/stemodem/radio-settings.c ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v5 2/8] stemodem: Add polling for SIM ready.
Interim solution until support for SIM 'ready' notification is supported. --- Change: AT-channel configuration is moved to separate patch. plugins/ste.c | 52 ++-- 1 files changed, 50 insertions(+), 2 deletions(-) diff --git a/plugins/ste.c b/plugins/ste.c index ef375ea..fcf4d15 100644 --- a/plugins/ste.c +++ b/plugins/ste.c @@ -60,8 +60,13 @@ #include drivers/stemodem/caif_socket.h #include drivers/stemodem/if_caif.h +static const char *cpin_prefix[] = { +CPIN:, NULL }; + struct ste_data { GAtChat *chat; + guint cpin_poll_source; + guint cpin_poll_count; + gboolean have_sim; }; static int ste_probe(struct ofono_modem *modem) @@ -88,6 +93,10 @@ static void ste_remove(struct ofono_modem *modem) ofono_modem_set_data(modem, NULL); g_at_chat_unref(data-chat); + + if (data-cpin_poll_source 0) + g_source_remove(data-cpin_poll_source); + g_free(data); } @@ -96,16 +105,55 @@ static void ste_debug(const char *str, void *user_data) ofono_info(%s, str); } +static gboolean init_simpin_check(gpointer user_data); + +static void simpin_check(gboolean ok, GAtResult *result, gpointer user_data) +{ + struct ofono_modem *modem = user_data; + struct ste_data *data = ofono_modem_get_data(modem); + + /* Modem returns +CME ERROR: 10 if SIM is not ready. */ + if (!ok result-final_or_pdu + !strcmp(result-final_or_pdu, +CME ERROR: 10) + data-cpin_poll_count++ 5) { + data-cpin_poll_source = + g_timeout_add_seconds(1, init_simpin_check, modem); + return; + } + + data-cpin_poll_count = 0; + + /* Modem returns ERROR if there is no SIM in slot. */ + data-have_sim = ok; + + ofono_modem_set_powered(modem, TRUE); +} + +static gboolean init_simpin_check(gpointer user_data) +{ + struct ofono_modem *modem = user_data; + struct ste_data *data = ofono_modem_get_data(modem); + + data-cpin_poll_source = 0; + + g_at_chat_send(data-chat, AT+CPIN?, cpin_prefix, + simpin_check, modem, NULL); + + return FALSE; +} + static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data) { struct ofono_modem *modem = user_data; DBG(); - if (!ok) + if (!ok) { ofono_modem_set_powered(modem, FALSE); + return; + } - ofono_modem_set_powered(modem, TRUE); + init_simpin_check(modem); } static int ste_enable(struct ofono_modem *modem) -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v5 3/8] plugins/ste: Add AT Channel configurations
--- plugins/ste.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/plugins/ste.c b/plugins/ste.c index fcf4d15..bcf2704 100644 --- a/plugins/ste.c +++ b/plugins/ste.c @@ -216,7 +216,8 @@ static int ste_enable(struct ofono_modem *modem) if (getenv(OFONO_AT_DEBUG)) g_at_chat_set_debug(data-chat, ste_debug, NULL); - g_at_chat_send(data-chat, ATE0 +CMEE=1, NULL, NULL, NULL, NULL); + g_at_chat_send(data-chat, ATF E0 V1 X4 C1 +CMEE=1, + NULL, NULL, NULL, NULL); g_at_chat_send(data-chat, AT+CFUN=1, NULL, cfun_enable, modem, NULL); return -EINPROGRESS; -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v5 4/7] stemodem: Add Radio Settings to STE Modem
--- Changes: o Changed order of files in Makefile o Fixed missing empty line in copyright o Formatted enum better o Removed default is switches o Removed ste in function names Makefile.am |2 + drivers/stemodem/radio-settings.c | 230 + drivers/stemodem/stemodem.c |2 + drivers/stemodem/stemodem.h |2 + 4 files changed, 236 insertions(+), 0 deletions(-) create mode 100644 drivers/stemodem/radio-settings.c diff --git a/Makefile.am b/Makefile.am index 16a3a3d..d8f36f2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -202,10 +202,12 @@ builtin_sources += drivers/atmodem/atutil.h \ drivers/stemodem/stemodem.h \ drivers/stemodem/stemodem.c \ drivers/stemodem/voicecall.c \ + drivers/stemodem/radio-settings.c \ drivers/stemodem/gprs-context.c \ drivers/stemodem/caif_socket.h \ drivers/stemodem/if_caif.h + builtin_modules += phonesim builtin_sources += plugins/phonesim.c diff --git a/drivers/stemodem/radio-settings.c b/drivers/stemodem/radio-settings.c new file mode 100644 index 000..9f93695 --- /dev/null +++ b/drivers/stemodem/radio-settings.c @@ -0,0 +1,230 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2008-2010 Intel Corporation. All rights reserved. + * Copyright (C) 2010 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#define _GNU_SOURCE +#include string.h +#include stdlib.h +#include stdio.h +#include errno.h + +#include glib.h + +#include ofono/log.h +#include ofono/modem.h +#include ofono/radio-settings.h + +#include gatchat.h +#include gatresult.h + +#include stemodem.h + +static const char *none_prefix[] = { NULL }; +static const char *cfun_prefix[] = { +CFUN:, NULL }; + +struct radio_settings_data { + GAtChat *chat; +}; + +enum ste_radio_mode { + STE_RADIO_OFF = 0, + STE_RADIO_ON = 1, + STE_RADIO_FLIGHT_MODE = 4, + STE_RADIO_GSM_ONLY =5, + STE_RADIO_WCDMA_ONLY = 6 +}; + +static gboolean ste_mode_to_ofono_mode(enum ste_radio_mode stemode, + enum ofono_radio_access_mode *mode) +{ + switch (stemode) { + case STE_RADIO_ON: + *mode = OFONO_RADIO_ACCESS_MODE_ANY; + return TRUE; + case STE_RADIO_GSM_ONLY: + *mode = OFONO_RADIO_ACCESS_MODE_GSM; + return TRUE; + case STE_RADIO_WCDMA_ONLY: + *mode = OFONO_RADIO_ACCESS_MODE_UMTS; + return TRUE; + case STE_RADIO_OFF: + case STE_RADIO_FLIGHT_MODE: + break; + } + + return FALSE; +} + +static gboolean ofono_mode_to_ste_mode(enum ofono_radio_access_mode mode, + enum ste_radio_mode *stemode) +{ + switch (mode) { + case OFONO_RADIO_ACCESS_MODE_ANY: + *stemode = STE_RADIO_ON; + return TRUE; + case OFONO_RADIO_ACCESS_MODE_GSM: + *stemode = STE_RADIO_GSM_ONLY; + return TRUE; + case OFONO_RADIO_ACCESS_MODE_UMTS: + *stemode = STE_RADIO_WCDMA_ONLY; + return TRUE; + case OFONO_RADIO_ACCESS_MODE_LTE: + break; + } + + return FALSE; +} + +static void rat_query_cb(gboolean ok, GAtResult *result, gpointer user_data) +{ + struct cb_data *cbd = user_data; + ofono_radio_settings_rat_mode_query_cb_t cb = cbd-cb; + enum ofono_radio_access_mode mode; + struct ofono_error error; + GAtResultIter iter; + int value; + + decode_at_error(error, g_at_result_final_response(result)); + + if (!ok) { + cb(error, -1, cbd-data); + return; + } + + g_at_result_iter_init(iter, result); + + if (!g_at_result_iter_next(iter, +CFUN:)) + goto err; + + if (!g_at_result_iter_next_number(iter, value)) + goto err; + + if (!ste_mode_to_ofono_mode(value, mode)) + goto err; + + CALLBACK_WITH_SUCCESS(cb, mode, cbd-data); + + return; + +err: + CALLBACK_WITH_FAILURE(cb, -1, cbd-data); +} +
[PATCH v5 5/8] plugins/ste: Add Radio-Settings
--- drivers/stemodem/radio-settings.c |5 + plugins/ste.c |2 ++ 2 files changed, 7 insertions(+), 0 deletions(-) diff --git a/plugins/ste.c b/plugins/ste.c index bcf2704..16ddbe1 100644 --- a/plugins/ste.c +++ b/plugins/ste.c @@ -54,6 +54,7 @@ #include ofono/voicecall.h #include ofono/gprs.h #include ofono/gprs-context.h +#include ofono/radio-settings.h #include ofono/stk.h #include drivers/atmodem/vendor.h @@ -279,6 +280,7 @@ static void ste_post_sim(struct ofono_modem *modem) DBG(%p, modem); ofono_stk_create(modem, 0, mbmmodem, data-chat); + ofono_radio_settings_create(modem, 0, stemodem, data-chat); ofono_ussd_create(modem, 0, atmodem, data-chat); ofono_call_forwarding_create(modem, 0, atmodem, data-chat); ofono_call_settings_create(modem, 0, atmodem, data-chat); -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v5 7/8] plugins/ste: Use SOCK_STREAM for CAIF and enable interface specification.
--- plugins/ste.c | 20 +++- 1 files changed, 19 insertions(+), 1 deletions(-) diff --git a/plugins/ste.c b/plugins/ste.c index 16ddbe1..479d85c 100644 --- a/plugins/ste.c +++ b/plugins/ste.c @@ -30,6 +30,7 @@ #include stdlib.h #include string.h #include unistd.h +#include net/if.h #include glib.h #include gatchat.h @@ -171,14 +172,31 @@ static int ste_enable(struct ofono_modem *modem) if (!device) { struct sockaddr_caif addr; int err; + const char *interface; /* Create a CAIF socket for AT Service */ - fd = socket(AF_CAIF, SOCK_SEQPACKET, CAIFPROTO_AT); + fd = socket(AF_CAIF, SOCK_STREAM, CAIFPROTO_AT); if (fd 0) { ofono_error(Failed to create CAIF socket for AT); return -EIO; } + /* Bind CAIF socket to specified interface */ + interface = ofono_modem_get_string(modem, Interface); + if (interface) { + struct ifreq ifreq; + memset(ifreq, 0, sizeof(ifreq)); + strcpy(ifreq.ifr_name, interface); + err = setsockopt(fd, SOL_SOCKET, + SO_BINDTODEVICE, ifreq, sizeof(ifreq)); + if (err 0) { + ofono_error(Failed to bind caif socket + to interface); + close(fd); + return err; + } + } + memset(addr, 0, sizeof(addr)); addr.family = AF_CAIF; addr.u.at.type = CAIF_ATTYPE_PLAIN; -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v5 6/8] plugins/modemconf.c add support for Interface for STE plugin.
--- plugins/modemconf.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/plugins/modemconf.c b/plugins/modemconf.c index 3747cd9..d7b1354 100644 --- a/plugins/modemconf.c +++ b/plugins/modemconf.c @@ -138,6 +138,7 @@ static struct { { g1, set_device }, { wavecom,set_device }, { ste,set_device }, + { ste,set_interface }, { calypso,set_device }, { palmpre,set_device }, { isimodem, set_interface }, -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v5 8/8] plugins: Add STE sample to modem.conf
--- plugins/modem.conf |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/plugins/modem.conf b/plugins/modem.conf index 66bf932..b577114 100644 --- a/plugins/modem.conf +++ b/plugins/modem.conf @@ -44,3 +44,8 @@ #[n900] #Driver=n900modem #Interface=phonet0 + +# Sample STE modem +#[ste] +#Interface=cfttyS0 +#Driver=ste -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: Terminating emergency calls
Denis Kenzior denk...@gmail.com wrote: Hi Sjur, I have to verify this with some of my colleagues, but I am pretty sure emergency calls cannot be applied to the AT+CHLD command. i.e. they cannot be part of mpty. Initial testing on STE modem indicates that emergency call cannot participate in multi call or be put on hold. What about a somewhat backdoor of putting call on hold on some modems: If a call is active, and you dial another call, the active call is automatically put on hold. So if an emergency call is active and we dial another number, what happens? On the STE modem I get NO CARRIER if I try to put an emergency call on hold this way. fonod[27624]: ATD911;\r ofonod[27624]: \r\nOK\r\n ... ofonod[27624]: ATD+4425993004494;\r ofonod[27624]: \r\nNO CARRIER\r\n However the other way around works, by having a normal call and then dialing an emergency number puts the regular call on hold. ... Yes, you're right using hangup_active will terminate all active calls participating in a multi call. So my proposal will not work as is. Maybe we need to know if release_next was called for multi call? I have commited a fix for this that I think should work just fine. Can you please check bab23b39767b664061ac2bcba747fe2b96561ca7 and let me know if it solves the issue? Yes, it does. I can now use hangup_all on an emergency call :-) I think this closes the last voice call issue for STE modems (for now). Regards Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCHv2 1/7] stemodem: Add support for STK by including MBM implementation.
--- Changes: o Use MBM stk driver implementation (avoid copying code). Note: stemodm.h has to declare the mbm_stk_init/exit functions because importing mbmdriver causes compile errors due to duplicated declarations. drivers/stemodem/stemodem.c |2 ++ drivers/stemodem/stemodem.h |2 ++ plugins/ste.c |2 ++ 3 files changed, 6 insertions(+), 0 deletions(-) diff --git a/drivers/stemodem/stemodem.c b/drivers/stemodem/stemodem.c index c18a8b5..0ba7878 100644 --- a/drivers/stemodem/stemodem.c +++ b/drivers/stemodem/stemodem.c @@ -38,6 +38,7 @@ static int stemodem_init(void) { ste_voicecall_init(); ste_gprs_context_init(); + mbm_stk_init(); return 0; } @@ -46,6 +47,7 @@ static void stemodem_exit(void) { ste_voicecall_exit(); ste_gprs_context_exit(); + mbm_stk_exit(); } OFONO_PLUGIN_DEFINE(stemodem, STE modem driver, VERSION, diff --git a/drivers/stemodem/stemodem.h b/drivers/stemodem/stemodem.h index 267e001..e10abd3 100644 --- a/drivers/stemodem/stemodem.h +++ b/drivers/stemodem/stemodem.h @@ -28,3 +28,5 @@ extern void ste_gprs_context_exit(); extern void ste_voicecall_init(); extern void ste_voicecall_exit(); +extern void mbm_stk_init(); +extern void mbm_stk_exit(); diff --git a/plugins/ste.c b/plugins/ste.c index f3ae0b2..9cb49d3 100644 --- a/plugins/ste.c +++ b/plugins/ste.c @@ -54,6 +54,7 @@ #include ofono/voicecall.h #include ofono/gprs.h #include ofono/gprs-context.h +#include ofono/stk.h #include drivers/atmodem/vendor.h #include drivers/stemodem/caif_socket.h @@ -241,6 +242,7 @@ static void ste_post_sim(struct ofono_modem *modem) gprs = ofono_gprs_create(modem, OFONO_VENDOR_STE, atmodem, data-chat); + ofono_stk_create(modem, 0, mbmmodem, data-chat); gc = ofono_gprs_context_create(modem, 0, stemodem, data-chat); if (gprs gc) -- 1.7.0.4 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCHv2 0/7] Resubmitting STE Driver patches.
Resubmitting based on rebase comments from Denis K. Changes: o SIM-ready and Radio-Settings are now split in two parts, one patch for driver and one for plugin. o Use MBM stk driver implementation (avoid copying code). o Updated error handling for Radio Settings. o Various Style issues (new line and tabs). New patch: o Added patch for plugins/ste using Socket stream mode for CAIF, and adding support for specifying CAIF interface to bind to. Sjur Brændeland (7): stemodem: Add support for STK by including MBM implementation. atmodem: Enable STE usage of AT*EPEV and AT*EPEE for PIN handling. stemodem: Add polling for SIM ready. stemodem: Add Radio Settings to STE Modem plugins/ste: Add Radio-Settings stemodem: Use RTNL for creating CAIF interface plugins/ste: Use SOCK_STREAM for CAIF and enable interface specification. Makefile.am |6 +- drivers/atmodem/sim.c |9 +- drivers/stemodem/gprs-context.c | 51 +-- drivers/stemodem/radio-settings.c | 225 ++ drivers/stemodem/rtnl.c | 318 + drivers/stemodem/rtnl.h | 24 +++ drivers/stemodem/stemodem.c |4 + drivers/stemodem/stemodem.h |5 + plugins/modem.conf|5 + plugins/modemconf.c |1 + plugins/ste.c | 79 +- 11 files changed, 706 insertions(+), 21 deletions(-) create mode 100644 drivers/stemodem/radio-settings.c create mode 100644 drivers/stemodem/rtnl.c create mode 100644 drivers/stemodem/rtnl.h ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCHv2 3/7] stemodem: Add polling for SIM ready.
Interim solution until support for SIM 'ready' notification is supported. --- Changes: o Fixed style issues (tabs and newlines) plugins/ste.c | 55 --- 1 files changed, 52 insertions(+), 3 deletions(-) diff --git a/plugins/ste.c b/plugins/ste.c index 9cb49d3..e1ca06c 100644 --- a/plugins/ste.c +++ b/plugins/ste.c @@ -60,8 +60,13 @@ #include drivers/stemodem/caif_socket.h #include drivers/stemodem/if_caif.h +static const char *cpin_prefix[] = { +CPIN:, NULL }; + struct ste_data { GAtChat *chat; + guint cpin_poll_source; + guint cpin_poll_count; + gboolean have_sim; }; static int ste_probe(struct ofono_modem *modem) @@ -88,6 +93,10 @@ static void ste_remove(struct ofono_modem *modem) ofono_modem_set_data(modem, NULL); g_at_chat_unref(data-chat); + + if (data-cpin_poll_source 0) + g_source_remove(data-cpin_poll_source); + g_free(data); } @@ -96,16 +105,55 @@ static void ste_debug(const char *str, void *user_data) ofono_info(%s, str); } +static gboolean init_simpin_check(gpointer user_data); + +static void simpin_check(gboolean ok, GAtResult *result, gpointer user_data) +{ + struct ofono_modem *modem = user_data; + struct ste_data *data = ofono_modem_get_data(modem); + + /* Modem returns +CME ERROR: 10 if SIM is not ready. */ + if (!ok result-final_or_pdu + !strcmp(result-final_or_pdu, +CME ERROR: 10) + data-cpin_poll_count++ 5) { + data-cpin_poll_source = + g_timeout_add_seconds(1, init_simpin_check, modem); + return; + } + + data-cpin_poll_count = 0; + + /* Modem returns ERROR if there is no SIM in slot. */ + data-have_sim = ok; + + ofono_modem_set_powered(modem, TRUE); +} + +static gboolean init_simpin_check(gpointer user_data) +{ + struct ofono_modem *modem = user_data; + struct ste_data *data = ofono_modem_get_data(modem); + + data-cpin_poll_source = 0; + + g_at_chat_send(data-chat, AT+CPIN?, cpin_prefix, + simpin_check, modem, NULL); + + return FALSE; +} + static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data) { struct ofono_modem *modem = user_data; DBG(); - if (!ok) + if (!ok) { ofono_modem_set_powered(modem, FALSE); + return; + } - ofono_modem_set_powered(modem, TRUE); + init_simpin_check(modem); } static int ste_enable(struct ofono_modem *modem) @@ -168,7 +216,8 @@ static int ste_enable(struct ofono_modem *modem) if (getenv(OFONO_AT_DEBUG)) g_at_chat_set_debug(data-chat, ste_debug, NULL); - g_at_chat_send(data-chat, ATE0 +CMEE=1, NULL, NULL, NULL, NULL); + g_at_chat_send(data-chat, ATF E0 V1 X4 C1 +CMEE=1, + NULL, NULL, NULL, NULL); g_at_chat_send(data-chat, AT+CFUN=1, NULL, cfun_enable, modem, NULL); return -EINPROGRESS; -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCHv2 5/7] plugins/ste: Add Radio-Settings
--- plugins/ste.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/plugins/ste.c b/plugins/ste.c index e1ca06c..1e3ed9d 100644 --- a/plugins/ste.c +++ b/plugins/ste.c @@ -55,6 +55,7 @@ #include ofono/gprs.h #include ofono/gprs-context.h #include ofono/stk.h +#include ofono/radio-settings.h #include drivers/atmodem/vendor.h #include drivers/stemodem/caif_socket.h @@ -292,6 +293,7 @@ static void ste_post_sim(struct ofono_modem *modem) gprs = ofono_gprs_create(modem, OFONO_VENDOR_STE, atmodem, data-chat); ofono_stk_create(modem, 0, mbmmodem, data-chat); + ofono_radio_settings_create(modem, 0, stemodem, data-chat); gc = ofono_gprs_context_create(modem, 0, stemodem, data-chat); if (gprs gc) -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCHv2 4/7] stemodem: Add Radio Settings to STE Modem
--- Changes since last patch set: o Moved updates to plugins/ste to separate patch. o Updated error handling. o Style issues. Makefile.am |4 +- drivers/stemodem/radio-settings.c | 223 + drivers/stemodem/stemodem.c |2 + drivers/stemodem/stemodem.h |2 + 4 files changed, 230 insertions(+), 1 deletions(-) create mode 100644 drivers/stemodem/radio-settings.c diff --git a/Makefile.am b/Makefile.am index 2f0b745..3e1efde 100644 --- a/Makefile.am +++ b/Makefile.am @@ -204,7 +204,9 @@ builtin_sources += drivers/atmodem/atutil.h \ drivers/stemodem/voicecall.c \ drivers/stemodem/gprs-context.c \ drivers/stemodem/caif_socket.h \ - drivers/stemodem/if_caif.h + drivers/stemodem/if_caif.h \ + drivers/stemodem/radio-settings.c + builtin_modules += phonesim builtin_sources += plugins/phonesim.c diff --git a/drivers/stemodem/radio-settings.c b/drivers/stemodem/radio-settings.c new file mode 100644 index 000..0c5b438 --- /dev/null +++ b/drivers/stemodem/radio-settings.c @@ -0,0 +1,223 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2008-2010 Intel Corporation. All rights reserved. + * Copyright (C) 2010 ST-Ericsson AB. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include config.h +#endif + +#define _GNU_SOURCE +#include string.h +#include stdlib.h +#include stdio.h +#include errno.h + +#include glib.h + +#include ofono/log.h +#include ofono/modem.h +#include ofono/radio-settings.h + +#include gatchat.h +#include gatresult.h + +#include stemodem.h + +static const char *none_prefix[] = { NULL }; +static const char *cfun_prefix[] = { +CFUN:, NULL }; + +struct radio_settings_data { + GAtChat *chat; +}; + +enum ste_radio_mode { + STE_RADIO_OFF = 0, + STE_RADIO_ON = 1, + STE_RADIO_FLIGHT_MODE = 4, + STE_RADIO_GSM_ONLY = 5, + STE_RADIO_WCDMA_ONLY = 6 +}; + +static gboolean ste_mode_to_ofono_mode(enum ste_radio_mode stemode, + enum ofono_radio_access_mode *mode) +{ + switch (stemode) { + case STE_RADIO_ON: + *mode = OFONO_RADIO_ACCESS_MODE_ANY; + return TRUE; + case STE_RADIO_GSM_ONLY: + *mode = OFONO_RADIO_ACCESS_MODE_GSM; + return TRUE; + case STE_RADIO_WCDMA_ONLY: + *mode = OFONO_RADIO_ACCESS_MODE_UMTS; + return TRUE; + default: + return FALSE; + } +} + +static gboolean ofono_mode_to_ste_mode(enum ofono_radio_access_mode mode, + enum ste_radio_mode *stemode) +{ + switch (mode) { + case OFONO_RADIO_ACCESS_MODE_ANY: + *stemode = STE_RADIO_ON; + return TRUE; + case OFONO_RADIO_ACCESS_MODE_GSM: + *stemode = STE_RADIO_GSM_ONLY; + return TRUE; + + case OFONO_RADIO_ACCESS_MODE_UMTS: + *stemode = STE_RADIO_WCDMA_ONLY; + return TRUE; + default: + return FALSE; + } +} + +static void sterat_query_cb(gboolean ok, GAtResult *result, gpointer user_data) +{ + struct cb_data *cbd = user_data; + ofono_radio_settings_rat_mode_query_cb_t cb = cbd-cb; + enum ofono_radio_access_mode mode; + GAtResultIter iter; + int value; + + decode_at_error(error, g_at_result_final_response(result)); + + if (!ok) { + cb(error, -1, cbd-data); + return; + } + + g_at_result_iter_init(iter, result); + + if (!g_at_result_iter_next(iter, +CFUN:)) + goto err; + + if (!g_at_result_iter_next_number(iter, value)) + goto err; + + if (!ste_mode_to_ofono_mode(value, mode)) + goto err; + + CALLBACK_WITH_SUCCESS(cb, mode, cbd-data); + + return; + +err: + CALLBACK_WITH_FAILURE(cb, -1, cbd-data); +} + +static void ste_query_rat_mode(struct ofono_radio_settings *rs, + ofono_radio_settings_rat_mode_query_cb_t cb, + void *data) +{ + struct radio_settings_data *rsd = ofono_radio_settings_get_data(rs);
[PATCHv2 6/7] stemodem: Use RTNL for creating CAIF interface
CAIF in Linux kernel 2.6.35 must use RTNL for configuring CAIF interfaces. --- Makefile.am |4 +- drivers/stemodem/gprs-context.c | 51 +-- drivers/stemodem/rtnl.c | 318 +++ drivers/stemodem/rtnl.h | 24 +++ 4 files changed, 383 insertions(+), 14 deletions(-) create mode 100644 drivers/stemodem/rtnl.c create mode 100644 drivers/stemodem/rtnl.h diff --git a/Makefile.am b/Makefile.am index 3e1efde..1298fb9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -205,7 +205,9 @@ builtin_sources += drivers/atmodem/atutil.h \ drivers/stemodem/gprs-context.c \ drivers/stemodem/caif_socket.h \ drivers/stemodem/if_caif.h \ - drivers/stemodem/radio-settings.c + drivers/stemodem/radio-settings.c \ + drivers/stemodem/rtnl.h \ + drivers/stemodem/rtnl.c builtin_modules += phonesim diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index ace9d6e..591df33 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -43,8 +43,9 @@ #include gatchat.h #include gatresult.h + +#include rtnl.h #include stemodem.h -#include caif_socket.h #include if_caif.h #define MAX_CAIF_DEVICES 7 @@ -68,7 +69,8 @@ struct conn_info { unsigned int cid; unsigned int device; unsigned int channel_id; - char interface[10]; + char ifname[16]; + int ifindex; }; struct eppsd_response { @@ -171,17 +173,40 @@ static struct conn_info *conn_info_create(unsigned int device, /* * Creates a new IP interface for CAIF. */ -static gboolean caif_if_create(const char *interface, unsigned int connid) +static gboolean caif_if_create(struct conn_info *conn) { - return FALSE; + + strcpy(conn-ifname, caif%d); + if (rtnl_create_caif_interface(IFLA_CAIF_IPV4_CONNID, + conn-channel_id, + conn-ifname, + conn-ifindex) 0) { + DBG(Failed to create IP interface for CAIF); + return FALSE; + } + + DBG(created CAIF interface ch:%d ifname:%s ifindex:%d\n, + conn-channel_id, conn-ifname, conn-ifindex); + + return TRUE; } /* * Removes IP interface for CAIF. */ -static gboolean caif_if_remove(const char *interface, unsigned int connid) +static gboolean caif_if_remove(struct conn_info *conn) { - return FALSE; + + if (rtnl_delete_caif_interface(conn-ifindex) 0) { + ofono_error(Failed to delete caif interface %s, + conn-ifname); + return FALSE; + } + + DBG(removed CAIF interface ch:%d ifname:%s ifindex:%d\n, + conn-channel_id, conn-ifname, conn-ifindex); + + return TRUE; } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -211,9 +236,9 @@ static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, conn = l-data; - if (!caif_if_remove(conn-interface, conn-channel_id)) { + if (!caif_if_remove(conn)) { DBG(Failed to remove caif interface %s., - conn-interface); + conn-ifname); } conn-cid = 0; @@ -283,16 +308,16 @@ static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) dns[1] = rsp.dns_server2; dns[2] = NULL; - sprintf(conn-interface, caif%u, conn-device); + sprintf(conn-ifname, caif%u, conn-device); - if (!caif_if_create(conn-interface, conn-channel_id)) { + if (!caif_if_create(conn)) { ofono_error(Failed to create caif interface %s., - conn-interface); + conn-ifname); CALLBACK_WITH_SUCCESS(cb, NULL, FALSE, rsp.ip_address, rsp.subnet_mask, rsp.default_gateway, dns, cbd-data); } else { - CALLBACK_WITH_SUCCESS(cb, conn-interface, + CALLBACK_WITH_SUCCESS(cb, conn-ifname, FALSE, rsp.ip_address, rsp.subnet_mask, rsp.default_gateway, dns, cbd-data); } @@ -544,7 +569,7 @@ static void ste_gprs_context_remove(struct ofono_gprs_context *gc) static struct ofono_gprs_context_driver driver = { .name = stemodem, .probe = ste_gprs_context_probe, - .remove = ste_gprs_context_remove, + .remove = ste_gprs_context_remove, .activate_primary = ste_gprs_activate_primary, .deactivate_primary = ste_gprs_deactivate_primary, }; diff --git a/drivers/stemodem/rtnl.c b/drivers/stemodem/rtnl.c
[PATCHv2 7/7] plugins/ste: Use SOCK_STREAM for CAIF and enable interface specification.
--- plugins/modem.conf |5 + plugins/modemconf.c |1 + plugins/ste.c | 20 +++- 3 files changed, 25 insertions(+), 1 deletions(-) diff --git a/plugins/modem.conf b/plugins/modem.conf index 66bf932..b577114 100644 --- a/plugins/modem.conf +++ b/plugins/modem.conf @@ -44,3 +44,8 @@ #[n900] #Driver=n900modem #Interface=phonet0 + +# Sample STE modem +#[ste] +#Interface=cfttyS0 +#Driver=ste diff --git a/plugins/modemconf.c b/plugins/modemconf.c index 3747cd9..d7b1354 100644 --- a/plugins/modemconf.c +++ b/plugins/modemconf.c @@ -138,6 +138,7 @@ static struct { { g1, set_device }, { wavecom,set_device }, { ste,set_device }, + { ste,set_interface }, { calypso,set_device }, { palmpre,set_device }, { isimodem, set_interface }, diff --git a/plugins/ste.c b/plugins/ste.c index 1e3ed9d..3e227af 100644 --- a/plugins/ste.c +++ b/plugins/ste.c @@ -30,6 +30,7 @@ #include stdlib.h #include string.h #include unistd.h +#include net/if.h #include glib.h #include gatchat.h @@ -171,14 +172,31 @@ static int ste_enable(struct ofono_modem *modem) if (!device) { struct sockaddr_caif addr; int err; + const char *interface; /* Create a CAIF socket for AT Service */ - fd = socket(AF_CAIF, SOCK_SEQPACKET, CAIFPROTO_AT); + fd = socket(AF_CAIF, SOCK_STREAM, CAIFPROTO_AT); if (fd 0) { ofono_error(Failed to create CAIF socket for AT); return -EIO; } + /* Bind CAIF socket to specified interface */ + interface = ofono_modem_get_string(modem, Interface); + if (interface) { + struct ifreq ifreq; + memset(ifreq, 0, sizeof(ifreq)); + strcpy(ifreq.ifr_name, interface); + err = setsockopt(fd, SOL_SOCKET, + SO_BINDTODEVICE, ifreq, sizeof(ifreq)); + if (err 0) { + ofono_error(Failed to bind caif socket + to interface); + close(fd); + return err; + } + } + memset(addr, 0, sizeof(addr)); addr.family = AF_CAIF; addr.u.at.type = CAIF_ATTYPE_PLAIN; -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCHv2 4/7] stemodem: Add Radio Settings to STE Modem
Marcel Holtmann mar...@holtmann.org wrote: Hi Sjur, Changes since last patch set: o Moved updates to plugins/ste to separate patch. o Updated error handling. o Style issues. Makefile.am | 4 +- drivers/stemodem/radio-settings.c | 223 + drivers/stemodem/stemodem.c | 2 + drivers/stemodem/stemodem.h | 2 + 4 files changed, 230 insertions(+), 1 deletions(-) create mode 100644 drivers/stemodem/radio-settings.c is this identical to how MBM does it? If yes, then I prefer we add this to drivers/mbmmodem/ and you just reference it. If not then I like to see the MBM version of this and where it actually differs. Maybe a MBM version with a STE quirk is better. Actually this is not yet implemented by MBM, so I guess STE is master this time ;-) I prefer doing this in MBM since that modem driver was just the first. There is no other preference here ;) This actually raises one question. How should we handle version variations from the same Modem vendor. The differences will be larger as we start adding support for LTE, and support different bearers (PC cards with USB and Modems with CAIF). Should we create more entries in the vendor enum, or do you have something else in mind? Regards Sjur ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v3 1/7] plugins/ste: Include STK support from MBM driver.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- Marcel Holtmann wrote: ... The build system builds the plugins properly and you can cross reference modem drivers from your modem plugin without any problems. Simply refering to MBM driver from ste.c plugins/ste.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/plugins/ste.c b/plugins/ste.c index f3ae0b2..9cb49d3 100644 --- a/plugins/ste.c +++ b/plugins/ste.c @@ -54,6 +54,7 @@ #include ofono/voicecall.h #include ofono/gprs.h #include ofono/gprs-context.h +#include ofono/stk.h #include drivers/atmodem/vendor.h #include drivers/stemodem/caif_socket.h @@ -241,6 +242,7 @@ static void ste_post_sim(struct ofono_modem *modem) gprs = ofono_gprs_create(modem, OFONO_VENDOR_STE, atmodem, data-chat); + ofono_stk_create(modem, 0, mbmmodem, data-chat); gc = ofono_gprs_context_create(modem, 0, stemodem, data-chat); if (gprs gc) -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v3 3/7] stemodem: Add polling for SIM ready.
From: Sjur Brændeland sjur.brandel...@stericsson.com Interim solution until support for SIM 'ready' notification is supported. --- Changes: o Fixed style issues (tabs and newlines) plugins/ste.c | 55 --- 1 files changed, 52 insertions(+), 3 deletions(-) diff --git a/plugins/ste.c b/plugins/ste.c index f9875fd..5fecd5e 100644 --- a/plugins/ste.c +++ b/plugins/ste.c @@ -60,8 +60,13 @@ #include drivers/stemodem/caif_socket.h #include drivers/stemodem/if_caif.h +static const char *cpin_prefix[] = { +CPIN:, NULL }; + struct ste_data { GAtChat *chat; + guint cpin_poll_source; + guint cpin_poll_count; + gboolean have_sim; }; static int ste_probe(struct ofono_modem *modem) @@ -88,6 +93,10 @@ static void ste_remove(struct ofono_modem *modem) ofono_modem_set_data(modem, NULL); g_at_chat_unref(data-chat); + + if (data-cpin_poll_source 0) + g_source_remove(data-cpin_poll_source); + g_free(data); } @@ -96,16 +105,55 @@ static void ste_debug(const char *str, void *user_data) ofono_info(%s, str); } +static gboolean init_simpin_check(gpointer user_data); + +static void simpin_check(gboolean ok, GAtResult *result, gpointer user_data) +{ + struct ofono_modem *modem = user_data; + struct ste_data *data = ofono_modem_get_data(modem); + + /* Modem returns +CME ERROR: 10 if SIM is not ready. */ + if (!ok result-final_or_pdu + !strcmp(result-final_or_pdu, +CME ERROR: 10) + data-cpin_poll_count++ 5) { + data-cpin_poll_source = + g_timeout_add_seconds(1, init_simpin_check, modem); + return; + } + + data-cpin_poll_count = 0; + + /* Modem returns ERROR if there is no SIM in slot. */ + data-have_sim = ok; + + ofono_modem_set_powered(modem, TRUE); +} + +static gboolean init_simpin_check(gpointer user_data) +{ + struct ofono_modem *modem = user_data; + struct ste_data *data = ofono_modem_get_data(modem); + + data-cpin_poll_source = 0; + + g_at_chat_send(data-chat, AT+CPIN?, cpin_prefix, + simpin_check, modem, NULL); + + return FALSE; +} + static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data) { struct ofono_modem *modem = user_data; DBG(); - if (!ok) + if (!ok) { ofono_modem_set_powered(modem, FALSE); + return; + } - ofono_modem_set_powered(modem, TRUE); + init_simpin_check(modem); } static int ste_enable(struct ofono_modem *modem) @@ -168,7 +216,8 @@ static int ste_enable(struct ofono_modem *modem) if (getenv(OFONO_AT_DEBUG)) g_at_chat_set_debug(data-chat, ste_debug, NULL); - g_at_chat_send(data-chat, ATE0 +CMEE=1, NULL, NULL, NULL, NULL); + g_at_chat_send(data-chat, ATF E0 V1 X4 C1 +CMEE=1, + NULL, NULL, NULL, NULL); g_at_chat_send(data-chat, AT+CFUN=1, NULL, cfun_enable, modem, NULL); return -EINPROGRESS; -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v3 6/7] stemodem: Use RTNL for creating CAIF interface
From: Sjur Brændeland sjur.brandel...@stericsson.com CAIF in Linux kernel 2.6.35 must use RTNL for configuring CAIF interfaces. --- drivers/stemodem/gprs-context.c | 51 +-- drivers/stemodem/rtnl.c | 318 +++ drivers/stemodem/rtnl.h | 24 +++ 3 files changed, 380 insertions(+), 13 deletions(-) create mode 100644 drivers/stemodem/rtnl.c create mode 100644 drivers/stemodem/rtnl.h diff --git a/drivers/stemodem/gprs-context.c b/drivers/stemodem/gprs-context.c index ace9d6e..591df33 100644 --- a/drivers/stemodem/gprs-context.c +++ b/drivers/stemodem/gprs-context.c @@ -43,8 +43,9 @@ #include gatchat.h #include gatresult.h + +#include rtnl.h #include stemodem.h -#include caif_socket.h #include if_caif.h #define MAX_CAIF_DEVICES 7 @@ -68,7 +69,8 @@ struct conn_info { unsigned int cid; unsigned int device; unsigned int channel_id; - char interface[10]; + char ifname[16]; + int ifindex; }; struct eppsd_response { @@ -171,17 +173,40 @@ static struct conn_info *conn_info_create(unsigned int device, /* * Creates a new IP interface for CAIF. */ -static gboolean caif_if_create(const char *interface, unsigned int connid) +static gboolean caif_if_create(struct conn_info *conn) { - return FALSE; + + strcpy(conn-ifname, caif%d); + if (rtnl_create_caif_interface(IFLA_CAIF_IPV4_CONNID, + conn-channel_id, + conn-ifname, + conn-ifindex) 0) { + DBG(Failed to create IP interface for CAIF); + return FALSE; + } + + DBG(created CAIF interface ch:%d ifname:%s ifindex:%d\n, + conn-channel_id, conn-ifname, conn-ifindex); + + return TRUE; } /* * Removes IP interface for CAIF. */ -static gboolean caif_if_remove(const char *interface, unsigned int connid) +static gboolean caif_if_remove(struct conn_info *conn) { - return FALSE; + + if (rtnl_delete_caif_interface(conn-ifindex) 0) { + ofono_error(Failed to delete caif interface %s, + conn-ifname); + return FALSE; + } + + DBG(removed CAIF interface ch:%d ifname:%s ifindex:%d\n, + conn-channel_id, conn-ifname, conn-ifindex); + + return TRUE; } static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, @@ -211,9 +236,9 @@ static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, conn = l-data; - if (!caif_if_remove(conn-interface, conn-channel_id)) { + if (!caif_if_remove(conn)) { DBG(Failed to remove caif interface %s., - conn-interface); + conn-ifname); } conn-cid = 0; @@ -283,16 +308,16 @@ static void ste_eppsd_up_cb(gboolean ok, GAtResult *result, gpointer user_data) dns[1] = rsp.dns_server2; dns[2] = NULL; - sprintf(conn-interface, caif%u, conn-device); + sprintf(conn-ifname, caif%u, conn-device); - if (!caif_if_create(conn-interface, conn-channel_id)) { + if (!caif_if_create(conn)) { ofono_error(Failed to create caif interface %s., - conn-interface); + conn-ifname); CALLBACK_WITH_SUCCESS(cb, NULL, FALSE, rsp.ip_address, rsp.subnet_mask, rsp.default_gateway, dns, cbd-data); } else { - CALLBACK_WITH_SUCCESS(cb, conn-interface, + CALLBACK_WITH_SUCCESS(cb, conn-ifname, FALSE, rsp.ip_address, rsp.subnet_mask, rsp.default_gateway, dns, cbd-data); } @@ -544,7 +569,7 @@ static void ste_gprs_context_remove(struct ofono_gprs_context *gc) static struct ofono_gprs_context_driver driver = { .name = stemodem, .probe = ste_gprs_context_probe, - .remove = ste_gprs_context_remove, + .remove = ste_gprs_context_remove, .activate_primary = ste_gprs_activate_primary, .deactivate_primary = ste_gprs_deactivate_primary, }; diff --git a/drivers/stemodem/rtnl.c b/drivers/stemodem/rtnl.c new file mode 100644 index 000..7990810 --- /dev/null +++ b/drivers/stemodem/rtnl.c @@ -0,0 +1,318 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2010 ST-Ericsson AB. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS
[PATCH v3 7/7] plugins/ste: Use SOCK_STREAM for CAIF and enable interface specification.
From: Sjur Brændeland sjur.brandel...@stericsson.com --- plugins/modem.conf |5 + plugins/modemconf.c |1 + plugins/ste.c | 20 +++- 3 files changed, 25 insertions(+), 1 deletions(-) diff --git a/plugins/modem.conf b/plugins/modem.conf index 66bf932..b577114 100644 --- a/plugins/modem.conf +++ b/plugins/modem.conf @@ -44,3 +44,8 @@ #[n900] #Driver=n900modem #Interface=phonet0 + +# Sample STE modem +#[ste] +#Interface=cfttyS0 +#Driver=ste diff --git a/plugins/modemconf.c b/plugins/modemconf.c index 3747cd9..d7b1354 100644 --- a/plugins/modemconf.c +++ b/plugins/modemconf.c @@ -138,6 +138,7 @@ static struct { { g1, set_device }, { wavecom,set_device }, { ste,set_device }, + { ste,set_interface }, { calypso,set_device }, { palmpre,set_device }, { isimodem, set_interface }, diff --git a/plugins/ste.c b/plugins/ste.c index 5a71945..e737bbb 100644 --- a/plugins/ste.c +++ b/plugins/ste.c @@ -30,6 +30,7 @@ #include stdlib.h #include string.h #include unistd.h +#include net/if.h #include glib.h #include gatchat.h @@ -171,14 +172,31 @@ static int ste_enable(struct ofono_modem *modem) if (!device) { struct sockaddr_caif addr; int err; + const char *interface; /* Create a CAIF socket for AT Service */ - fd = socket(AF_CAIF, SOCK_SEQPACKET, CAIFPROTO_AT); + fd = socket(AF_CAIF, SOCK_STREAM, CAIFPROTO_AT); if (fd 0) { ofono_error(Failed to create CAIF socket for AT); return -EIO; } + /* Bind CAIF socket to specified interface */ + interface = ofono_modem_get_string(modem, Interface); + if (interface) { + struct ifreq ifreq; + memset(ifreq, 0, sizeof(ifreq)); + strcpy(ifreq.ifr_name, interface); + err = setsockopt(fd, SOL_SOCKET, + SO_BINDTODEVICE, ifreq, sizeof(ifreq)); + if (err 0) { + ofono_error(Failed to bind caif socket + to interface); + close(fd); + return err; + } + } + memset(addr, 0, sizeof(addr)); addr.family = AF_CAIF; addr.u.at.type = CAIF_ATTYPE_PLAIN; -- 1.6.3.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono